module TestCodec_CAM {
    
  // LibIts
  import from ITS_Container language "ASN.1:1997" all;
  import from CAM_PDU_Descriptions language "ASN.1:1997"all;
  
  // LibItsCommon
  import from LibItsCommon_Functions all;
  import from LibItsCommon_ASN1_NamedNumbers all;
    
  // LibItsGeoNetworking
  import from LibItsGeoNetworking_Pixits all;
  import from LibItsGeoNetworking_Pics all;
  
  // LibItsCam
  import from LibItsCam_TypesAndValues all;
  import from LibItsCam_TestSystem all;
  import from LibItsCam_Templates all;
    
  // TestCodec
  import from TestCodec_TestAndSystem all;
    
  group LibItsCam_testCases {
        
    group camTemplates {
            
      template (value) CAM m_camMsg(
                                    StationID p_stationId,
                                    GenerationDeltaTime p_generationTime
                                    ) := {
      header := {
        protocolVersion := LibItsCommon_ASN1_NamedNumbers.ItsPduHeader_protocolVersion_currentVersion_,
        messageID := LibItsCommon_ASN1_NamedNumbers.ItsPduHeader_messageID_cam_,
        stationID := p_stationId
      },
      cam := {
        generationDeltaTime := p_generationTime,
        camParameters := {
          basicContainer := {
            stationType := LibItsCommon_ASN1_NamedNumbers.StationType_passengerCar_,
            referencePosition := {
              latitude := 435524450,
              longitude := 103002416,
              positionConfidenceEllipse := {
                semiMajorConfidence   := LibItsCommon_ASN1_NamedNumbers.SemiAxisLength_unavailable_,
                semiMinorConfidence   := LibItsCommon_ASN1_NamedNumbers.SemiAxisLength_unavailable_,
                semiMajorOrientation  := 3601
                },
              altitude := {
                altitudeValue := 500,
                altitudeConfidence := unavailable
              }
              }
          },
          highFrequencyContainer := {
            basicVehicleContainerHighFrequency := {
              heading := {
                headingValue := 2343,
                headingConfidence := 127
              },
              speed := {
                speedValue := 1001,
                speedConfidence := 1
              },
              driveDirection := unavailable,
              vehicleLength := {
                vehicleLengthValue := 40,
                vehicleLengthConfidenceIndication := unavailable
                },
              vehicleWidth := 18,
              longitudinalAcceleration := {
                longitudinalAccelerationValue := 0,
                longitudinalAccelerationConfidence := 1
                },
              curvature := {
                curvatureValue := LibItsCommon_ASN1_NamedNumbers.CurvatureValue_unavailable_, //30001
                curvatureConfidence := onePerMeter_0_00002
              },
              curvatureCalculationMode := yawRateUsed,
              yawRate := {
                yawRateValue := LibItsCommon_ASN1_NamedNumbers.YawRateValue_straight_,
                yawRateConfidence := unavailable
                },
              accelerationControl := '0000000'B,
              lanePosition := 14,
              steeringWheelAngle := omit,
              lateralAcceleration := {
                lateralAccelerationValue := 0,
                lateralAccelerationConfidence := 1
                },
              verticalAcceleration := omit, 
              performanceClass := omit,
              cenDsrcTollingZone := omit
            }
          },
          lowFrequencyContainer := omit,
          specialVehicleContainer := omit
          }
      }
      };
            
    } // End of group camTemplates
        
    group testCamPrimitiveMessages {
      
      testcase tc_CamReq() runs on TCType system TCType {
        TestCamReq(
                   m_camReq(
                            m_camMsg(
                                     10047,
                                     31859
                                     )
                            ), 
                   true,
                   oct2bit('01020000273F7C730059F34F8C4E2DB0661FFFFFFC2231129E68927FC1F48082788A800F53080FFFD003D40040'O)
                   );
      }
      
      testcase tc_CamInd_1() runs on TCType system TCType {
        TestCamInd(
                   mw_camIndWithGnParameters(
                             m_camMsg(
                                      10047,
                                      31859
                                      ),
                             1, // 01
                             2, // 02
                             3, // 03
                             67438087, // 04050607
                             8 // 08
                            ), 
                   '01020000273F7C730059F34F8C4E2DB0661FFFFFFC2231129E68927FC1F48082788A800F53080FFFD003D400400102030405060708090a0b0c00000000000000000000000000000000000000000000000000000000000000000a0a0a0a'O
                   );
      }
      
      testcase tc_CamInd_2() runs on TCType system TCType {
        TestCamInd(
                   mw_camIndWithSecurityParameters(
                             m_camMsg(
                                      10047,
                                      31859
                                      ),
                             int2bit(0, 256), // 00{32}
                             168430090 // 0a0a0a0a
                            ), 
                   '01020000273F7C730059F34F8C4E2DB0661FFFFFFC2231129E68927FC1F48082788A800F53080FFFD003D400400102030405060708090a0b0c00000000000000000000000000000000000000000000000000000000000000000a0a0a0a'O
                   );
      }
      
    } // End of group testCamPrimitiveMessages

    group testCamUpperTester {

      /**
       * @desc Validate template GeoNetworking/UtCamInitialize
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamInitialize() runs on TCType system TCType {
        var bitstring v_encMsg;
        var UtCamInitialize v_decMsg;
        var integer v_res := 0;
        var template (value) UtCamInitialize m_utCamInitialize := { '0809AABBCCDDEEFF'O };
        var bitstring v_expEncMsg := oct2bit('000809AABBCCDDEEFF'O);
        
        // Encode template
        log("Encode template ", valueof(m_utCamInitialize));
      v_encMsg := encvalue(m_utCamInitialize);
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamInitialize

      /**
       * @desc Validate template Cam/UtCamChangePosition
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamChangePosition() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var template (value) UtCamChangePosition v_utCamChangePosition := { 1234, 5678, 9876 };
        var bitstring v_expEncMsg := oct2bit('02000004D20000162E00002694'O);
    
        // Encode template
        log("Encode template ", valueof(v_utCamChangePosition));
      v_encMsg := encvalue(v_utCamChangePosition);
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamChangePosition
      
      /**
       * @desc Validate template Cam/UtCamChangeCurvature
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamChangeCurvature() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('30000a'O);
    
        // Encode template
        log("Encode template ", valueof(m_changeCurvature(10)));
        v_encMsg := encvalue(m_changeCurvature(10));
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamChangeCurvature
      
      /**
       * @desc Validate template Cam/UtCamChangeSpeed
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamChangeSpeed() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('310020'O);
    
        // Encode template
        log("Encode template ", valueof(m_changeSpeed(32)));
        v_encMsg := encvalue(m_changeSpeed(32));
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamChangeSpeed
      
      /**
       * @desc Validate template Cam/UtCamSetAccelerationControlStatus
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamSetAccelerationControlStatus() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('3210'O);
        var template (value) UtCamTrigger v_accelerationControlStatus := { setAccelerationControlStatus := '0000100'B };
    
        // Encode template
        log("Encode template ", valueof(v_accelerationControlStatus));
        v_encMsg := encvalue(v_accelerationControlStatus);
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamSetAccelerationControlStatus
      
      /**
       * @desc Validate template Cam/UtCamSetExteriorLightsStatus
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamSetExteriorLightsStatus_lowBeamHeadlightsOn() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('3380'O);
        var template (value) UtCamTrigger v_exteriorLightsStatus := { setExteriorLightsStatus := '10000000'B };
    
        // Encode template
        log("Encode template ", valueof(v_exteriorLightsStatus));
        v_encMsg := encvalue(v_exteriorLightsStatus);
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamSetExteriorLightsStatus_lowBeamHeadlightsOn
      
      /**
       * @desc Validate template Cam/UtCamSetExteriorLightsStatus
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamSetExteriorLightsStatus_leftTurnSignalOn() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('3320'O);
        var template (value) UtCamTrigger v_exteriorLightsStatus := { setExteriorLightsStatus := '00100000'B };
    
        // Encode template
        log("Encode template ", valueof(v_exteriorLightsStatus));
        v_encMsg := encvalue(v_exteriorLightsStatus);
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamSetExteriorLightsStatus_leftTurnSignalOn
      
      /**
       * @desc Validate template Cam/UtCamSetExteriorLightsStatus
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamSetExteriorLightsStatus_daytimeRunningLightsOn() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('3308'O);
        var template (value) UtCamTrigger v_exteriorLightsStatus := { setExteriorLightsStatus := '00001000'B };
    
        // Encode template
        log("Encode template ", valueof(v_exteriorLightsStatus));
        v_encMsg := encvalue(v_exteriorLightsStatus);
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamSetExteriorLightsStatus_daytimeRunningLightsOn
      
      /**
       * @desc Validate template Cam/UtCamSetExteriorLightsStatus
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamSetExteriorLightsStatus_parkingLightsOn() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('3301'O);
        var template (value) UtCamTrigger v_exteriorLightsStatus := { setExteriorLightsStatus := '00000001'B };
    
        // Encode template
        log("Encode template ", valueof(v_exteriorLightsStatus));
        v_encMsg := encvalue(v_exteriorLightsStatus);
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamSetExteriorLightsStatus_parkingLightsOn
      
      /**
       * @desc Validate template Cam/UtCamChangeHeading
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamChangeHeading() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('340010'O);
    
        // Encode template
        log("Encode template ", valueof(m_changeHeading(16)));
        v_encMsg := encvalue(m_changeHeading(16));
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamChangeHeading
      
      /**
       * @desc Validate template Cam/UtCamSetDriveDirection
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamSetDriveDirection() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('3502'O);
    
        // Encode template
        log("Encode template ", valueof(m_setDriveDirection(unavailable)));
        v_encMsg := encvalue(m_setDriveDirection(unavailable));
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamSetDriveDirection
      
      /**
       * @desc Validate template Cam/UtCamChangeYawRate
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamChangeYawRate() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('360080'O);
    
        // Encode template
        log("Encode template ", valueof(m_changeYawRate(128)));
        v_encMsg := encvalue(m_changeYawRate(128));
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamChangeYawRate
      
      /**
       * @desc Validate template Cam/UtCamChangeYawRate
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamChangeYawRate_negative() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('36FF80'O);
    
        // Encode template
        log("Encode template ", valueof(m_changeYawRate(-128)));
        v_encMsg := encvalue(m_changeYawRate(-128));
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamChangeYawRate_negative
      
      /**
       * @desc Validate template Cam/UtCamSetStationType
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamSetStationType() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('3903'O);
        var template (value) UtCamTrigger v_stationType := { setStationType := 3 };
    
        // Encode template
        log("Encode template ", valueof(v_stationType));
        v_encMsg := encvalue(v_stationType);
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamSetStationType
      
      /**
       * @desc Validate template Cam/UtCamSetVehicleRole
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamSetVehicleRole() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('3a05'O);
    
        // Encode template
        log("Encode template ", valueof(m_setVehicleRole(rescue)));
        v_encMsg := encvalue(m_setVehicleRole(rescue));
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamSetVehicleRole
      
      /**
       * @desc Validate template Cam/UtCamSetEmbarkationStatus
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamSetEmbarkationStatus() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('3bff'O);
        var template (value) UtCamTrigger v_setEmbarkationStatus := { setEmbarkationStatus := true };
    
        // Encode template
        log("Encode template ", valueof(v_setEmbarkationStatus));
        v_encMsg := encvalue(v_setEmbarkationStatus);
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamSetEmbarkationStatus
      
      /**
       * @desc Validate template Cam/UtCamSetDangerousGoods
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamSetDangerousGoods() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('3D13'O);
    
        // Encode template
        log("Encode template ", valueof(m_setDangerousGoods(miscellaneousDangerousSubstances)));
        v_encMsg := encvalue(m_setDangerousGoods(miscellaneousDangerousSubstances));
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamSetDangerousGoods
      
      /**
       * @desc Validate template Cam/UtCamSetLightBarSirene
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamSetLightBarSirene() runs on TCType system TCType {
        var bitstring v_encMsg;
        var integer v_res := 0;
        var bitstring v_expEncMsg := oct2bit('3fC0'O);
        var template (value) UtCamTrigger v_setLightBarSirene := { setLightBarSirene := '11'B };
    
        // Encode template
        log("Encode template ", valueof(v_setLightBarSirene));
        v_encMsg := encvalue(v_setLightBarSirene);
        log("Encoded message:  ", bit2oct(v_encMsg));
        // Check result
        if (not isbound(v_encMsg)) {
          setverdict(fail, "Encoding failed!");
          stop;
        }
        if (not match(v_encMsg, v_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(v_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
        setverdict(pass, "Encoding passed.");
      } // End of tc_Cam_UtCamSetLightBarSirene
      
      /**
       * @desc Validate decoding of Cam/UtCamTriggerResult
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamTriggerResult() runs on TCType system TCType {
        var bitstring v_binary := oct2bit('2101'O);
        var UtCamResults v_decMsg;
        var integer v_res := 0;
        var template (value) UtCamResults v_expDecMsg := { utCamTriggerResult := true };
        
        // Decode template
        v_res := decvalue(v_binary, v_decMsg);
        log("Decoded message: ", v_decMsg);
        select (v_res) {
        case (0) {
          if(match(v_decMsg, v_expDecMsg)) {
            setverdict(pass);
          } else {
            setverdict(fail);
          }
        }
        case (1) {
          setverdict(fail, "Decoding failed.");
        }
        case (2) {
          setverdict(fail, "Not enough bits.");
        }
        }
      } // End of tc_Cam_UtCamTriggerResult

      /**
       * @desc Validate decoding of Cam/UtCamEventInd
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamEventInd_1() runs on TCType system TCType {
        var bitstring v_binary := oct2bit('23002e0102000027a8f3080059f3504c2e2dafcb9ffffffc22312b9e20000fc002fe81605a8333a9870fffd1e058ea2167'O);
        var UtCamEventInd v_decMsg;
        var integer v_res := 0;
        
        // Decode template
        v_res := decvalue(v_binary, v_decMsg);
        log("Decoded message: ", v_decMsg);
        select (v_res) {
        case (0) {
          if(match(v_decMsg.camMsg, mw_camMsg_any)) {
            setverdict(pass);
          } else {
            setverdict(fail);
          }
        }
        case (1) {
          setverdict(fail, "Decoding failed.");
        }
        case (2) {
          setverdict(fail, "Not enough bits.");
        }
        }
      } // End of tc_Cam_UtCamEventInd_1

      /**
       * @desc Validate decoding of Cam/UtCamEventInd
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_UtCamEventInd_2() runs on TCType system TCType {
        var bitstring v_binary := oct2bit('23002a01020000270f0067005a4a735b0d4a2928dfffffe00030d40040000fc0007e3fe9ed0737530f1fffb000'O);
        var UtCamEventInd v_decMsg;
        var integer v_res := 0;
        
        // Decode template
        v_res := decvalue(v_binary, v_decMsg);
        log("Decoded message: ", v_decMsg);
        select (v_res) {
        case (0) {
          if(match(v_decMsg.camMsg, mw_camMsg_HF_BV(mw_HF_BV_yawRate(?)))) {
            setverdict(pass);
          } else {
            setverdict(fail);
          }
        }
        case (1) {
          setverdict(fail, "Decoding failed.");
        }
        case (2) {
          setverdict(fail, "Not enough bits.");
        }
        }
      } // End of tc_Cam_UtCamEventInd_2

    } // End of group testCamUpperTester
    
    group testCamPort {
            
      /**
       * @desc validate CamReq
       * @verdict Pass on success, Fail otherwise
       */
      testcase tc_Cam_Port() runs on ItsCam system ItsCamSystem {
        var CamReq v_camReq;
        var boolean v_got_cam := false;
	
        if (PX_GN_UPPER_LAYER != e_btpB) {
          log("PX_GN_UPPER_LAYER shall be set to e_btpB");
          stop;
        }
        
        map(self:camPort, system:camPort);
        
      v_camReq := valueof(
                          CamReq : { msgOut := m_camMsg(
                                                        f_getTsStationId(),
                                                        35000 // See ETSI EN 302 637-2 V1.3.0 - Clause B.3 generationDelatTime
                                                        )
                            }
                          );
        camPort.send(v_camReq);
        tc_ac.start;
        alt {
          [v_got_cam == false] camPort.receive(CamInd : ?) {
            v_got_cam := true;
            setverdict(pass);
          }
          [] tc_ac.timeout { // Give time to receive LS_REQUEST from the simulator
            setverdict(fail, "Expected message not received1");
          }
        }
                
        unmap(self:camPort, system:camPort);
                
      }
            
    } // End of group testCamPort_1
        
  } // End of group LibItsCam_testCases
    
  group encdec_functions {
        
    function TestCamReq(
                        in template (value) CamReq p_camReq,
                        in boolean p_decode := true, 
                        in template (omit) bitstring p_expEncMsg := omit 
                        ) runs on TCType {
      var bitstring v_encMsg;
      var template (omit) TestRecord v_tr := { bs := p_expEncMsg };
      var CamReq v_decMsg;
      var integer v_res := 0;
    
      // Encode template
      log("Encode template ", valueof(p_camReq));
    v_encMsg := encvalue(p_camReq);
      log("Encoded message:  ", bit2oct(v_encMsg));
      // Check result
      if (not isbound(v_encMsg)) {
        setverdict(fail, "Encoding failed!");
        stop;
      }
      if (ispresent(v_tr.bs)) {
        if (not match(v_encMsg, p_expEncMsg)) {
          log("Expected message: ", bit2oct(valueof(p_expEncMsg)));
          setverdict(fail, "Encoding failed, not the expected result!");
          stop;
        }
      }
      setverdict(pass, "Encoding passed.");
    
      // Check decoding
      if (p_decode == true) {
      v_res := decvalue(v_encMsg, v_decMsg);
        log("Decoded message: ", v_decMsg);
        select (v_res) {
        case (0) {
          if(match(v_decMsg, p_camReq)) {
            setverdict(pass);
          } else {
            setverdict(fail);
          }
        }
        case (1) {
          setverdict(fail, "Decoding failed.");
        }
        case (2) {
          setverdict(fail, "Not enough bits.");
        }
        }
      }
            
    } // End of function TestCamReq
        
    function TestCamInd(
                        in template CamInd p_camInd,
                        in octetstring p_expEncMsg 
                        ) runs on TCType {
      var bitstring v_encMsg := oct2bit(p_expEncMsg);
      var CamInd v_decMsg;
      var integer v_res := 0;
      
      // Check decoding
      v_res := decvalue(v_encMsg, v_decMsg);
      select (v_res) {
      case (0) {
        log("v_decMsg: ", v_decMsg);
        if(match(valueof(v_decMsg), p_camInd)) {
          setverdict(pass);
        } else {
          setverdict(fail);
        }
      }
      case (1) {
        setverdict(fail, "Decoding failed.");
      }
      case (2) {
        setverdict(fail, "Not enough bits.");
      }
      } // End of 'select' statement
      
    } // End of function TestCamInd
    
  } // End of group encdec_functions
  
  control {
    execute(tc_CamReq());
    execute(tc_CamInd_1());
    execute(tc_CamInd_2());
    execute(tc_Cam_Port());
    execute(tc_Cam_UtCamInitialize());
    execute(tc_Cam_UtCamChangePosition());
    execute(tc_Cam_UtCamChangeSpeed());
    execute(tc_Cam_UtCamChangePosition());
    execute(tc_Cam_UtCamChangeHeading());
    execute(tc_Cam_UtCamChangeCurvature());
    execute(tc_Cam_UtCamChangeYawRate());
    execute(tc_Cam_UtCamChangeYawRate_negative());

    execute(tc_Cam_UtCamEventInd_1());
    execute(tc_Cam_UtCamEventInd_2());
  }
  
} // End of module TestCodec_CAM 
