module ItsRSUsSimulator_Functions { // LibCommon import from LibCommon_BasicTypesAndValues all; import from LibCommon_DataStrings all; import from LibCommon_VerdictControl all; import from LibCommon_Sync all; import from LibCommon_Time all; // LibIts import from ITS_Container language "ASN.1:1997" all; import from CAM_PDU_Descriptions language "ASN.1:1997" all; import from DENM_PDU_Descriptions language "ASN.1:1997" all; import from MAPEM_PDU_Descriptions language "ASN.1:1997" all; import from SPATEM_PDU_Descriptions language "ASN.1:1997" all; import from IVIM_PDU_Descriptions language "ASN.1:1997" all; import from SREM_PDU_Descriptions language "ASN.1:1997" all; import from SSEM_PDU_Descriptions language "ASN.1:1997" all; import from DSRC language "ASN.1:1997" all; // LibItsCommon import from LibItsCommon_Functions all; // LibItsBtp import from LibItsBtp_TypesAndValues all; import from LibItsBtp_Templates all; // LibItsCam import from LibItsCam_Templates all; // LibItsDenm import from LibItsDenm_Templates all; // LibItsMapemSpatemm import from LibItsMapemSpatem_Templates all; // LibItsMapemSpatemm import from LibItsIvim_Templates all; // LibItsMapemSpatemm import from LibItsSremSsem_Templates all; // LibItsGeoNetworking import from LibItsGeoNetworking_TestSystem all; import from LibItsGeoNetworking_Functions all; import from LibItsGeoNetworking_Templates all; import from LibItsGeoNetworking_TypesAndValues all; import from LibItsGeoNetworking_Pixits all; // AtsRSUsSimulator import from ItsRSUsSimulator_TypesAndValues all; import from ItsRSUsSimulator_TestSystem all; import from ItsRSUsSimulator_Templates all; import from ItsRSUsSimulator_Pics all; import from ItsRSUsSimulator_Pixits all; group rsuConfigurationFunctions { /** * @desc This configuration features: * - one ITS node (IUT) * - two ITS nodes (nodeA, nodeB) * - Area1 which only includes NodeB and IUT * - Area2 which only includes NodeB * NodeB being close to the area center */ function f_cf01Up() runs on ItsRSUsSimulator { // Local variables // Map map(self:acPort, system:acPort); map(self:cfPort, system:cfPort); map(self:geoNetworkingPort, system:geoNetworkingPort); // Connect f_connect4SelfOrClientSync(); activate(a_cf01Down()); // Initialise secured mode f_initialiseSecuredMode(); //Initialze the Config module cfPort.send(CfInitialize:{}); // Initialisations f_setup_rsu(vc_rsu_id); } // End of function f_cf01Up function f_cf01Down() runs on ItsRSUsSimulator { vc_rsuMessagesValueList := {}; f_uninitialiseSecuredMode(); // Unmap unmap(self:acPort, system:acPort); unmap(self:cfPort, system:cfPort); unmap(self:geoNetworkingPort, system:geoNetworkingPort); // Disconnect f_disconnect4SelfOrClientSync(); } // End of function f_cf01Down } // End of group rsuConfigurationFunctions function f_initialiseVehicleSimulatorComponent( in ItsRSUsSimulator p_component, out template (omit) CAM p_cam ) runs on ItsRSUsSimulator { p_cam := m_camMsg_vehicle( f_getTsStationId(), f_getCurrentTime() mod 65536, // Shall be updated in function f_prepare_vehicle_cam m_rsuPosition( PICS_USECASE6_VEHICLE_POSITIONS[0].latitude, // Shall be updated in function f_prepare_vehicle_cam PICS_USECASE6_VEHICLE_POSITIONS[0].longitude // Shall be updated in function f_prepare_vehicle_cam ) ); map(p_component:geoNetworkingPort, system:geoNetworkingPort); } // End of function f_initialiseVehicleSimulatorComponent function f_uninitialiseVehicleSimulatorComponent( in ItsRSUsSimulator p_component ) runs on ItsRSUsSimulator { p_component.done; unmap(p_component:geoNetworkingPort, system:geoNetworkingPort); } // End of function f_uninitialiseVehicleSimulatorComponent function f_setup_rsu( in integer p_rsu_id ) runs on ItsRSUsSimulator { // Local variables var template (value) DenmParmContainers v_denmParmContainers; var template (omit) octetstring v_beacon := omit; var template (omit) DENMs v_denms := omit; var template (omit) CAM v_cam := omit; var template (omit) MAPEM v_mapem := omit; var template (omit) SPATEMs v_spatems := omit; var template (omit) IVIM v_ivim := omit; var template (omit) SSEM v_ssem := omit; var integer v_counter; vc_longPosVectorRsu := PICS_RSU_PARAMS[p_rsu_id].longPosVector; // MAPEM, only if PX_ETSI_USE_CASE_ID is set to 3 if ((vc_mapem == true) and (PX_ETSI_USE_CASE_ID == 3) and ispresent(PICS_MAPEM_PARMS_RSUs[p_rsu_id].intersections)) { // Build the list of the MAPEM events v_mapem := m_mapemParm( PICS_RSU_PARAMS[vc_rsu_id].stationID, m_mapem( f_getMsgIssueRevision(), PICS_MAPEM_PARMS_RSUs[p_rsu_id].intersections, PICS_MAPEM_PARMS_RSUs[p_rsu_id].roadSegments )); // Update revision fields v_mapem.map_.intersections[0].revision := f_incMsgIssueRevision(); // TODO Add more? } else { vc_mapem := false; } // SPATEM, only if PX_ETSI_USE_CASE_ID is set to 3 if ((vc_spatem == true) and (PX_ETSI_USE_CASE_ID == 3) and (lengthof(PICS_SPATEM_PARMS_RSUs[p_rsu_id]) != 0)) { // Reset counter vc_currentPhaseStartTime := 36001; vc_endPhaseStartTime := 0; vc_spatemStatesId := 0; // Build the list of the SPATEM events for (v_counter := 0; v_counter < lengthof(PICS_SPATEM_PARMS_RSUs[p_rsu_id]); v_counter := v_counter + 1) { v_spatems[v_counter] := m_spatemParm( PICS_RSU_PARAMS[p_rsu_id].stationID, m_spatem( PICS_SPATEM_PARMS_RSUs[p_rsu_id][v_counter].intersections, "SignalGroupID #" & int2str(PICS_SPATEM_PARMS_RSUs[p_rsu_id][v_counter].signalGroupID) )); for (var integer v_intersection := 0; v_intersection < lengthof(v_spatems[v_counter].spat.intersections); v_intersection := v_intersection + 1) { vc_states[v_counter][v_intersection] := v_spatems[v_counter].spat.intersections[v_intersection].states; } // End of 'for' statement // TODO Build SPATEM with dynamic values } // End of 'for' statement // TODO Build SPATEM with dynamic values } else { vc_spatem := false; } // IVIM, only if PX_ETSI_USE_CASE_ID is set to 5 if ((vc_ivim == true) and (PX_ETSI_USE_CASE_ID == 5) and ispresent(PICS_IVIM_PARMS_RSUs[p_rsu_id].provider)) { // Build the list of the IVIM events v_ivim := m_ivimParm( PICS_RSU_PARAMS[p_rsu_id].stationID, m_ivimStructure( m_iviManagementContainer( PICS_IVIM_PARMS_RSUs[p_rsu_id].provider, PICS_IVIM_PARMS_RSUs[p_rsu_id].iviIdentificationNumber, 0//IviStatus_new_ ), PICS_IVIM_PARMS_RSUs[p_rsu_id].iviContainers )); // Update ivi status v_ivim.ivi.mandatory.validFrom := f_getCurrentTime(); v_ivim.ivi.mandatory.validTo := valueof(v_ivim.ivi.mandatory.validFrom) + 43200000; // 12hours } else { vc_ivim := false; } // DENM, only if PX_ETSI_USE_CASE_ID is set to 1 if ((vc_denm == true) and (PX_ETSI_USE_CASE_ID == 1)) { // Build the list of the DENM events for the specified RSU (PX_RSU_ID) and the given zone (PX_ETSI_ZONE_ID) for (v_counter := 0; v_counter < lengthof(PICS_DENM_EVENTS_RSU[p_rsu_id][PX_ETSI_ZONE_ID - 1]); v_counter := v_counter + 1) { var DenmEventsParmsPerZone v_denmEventsParmsPerZone := PICS_DENM_EVENTS_RSU[p_rsu_id][PX_ETSI_ZONE_ID - 1]; v_denmParmContainers := m_denmParmContainers( PICS_RSU_PARAMS[p_rsu_id].stationID, f_incDenmSequenceNumber(), PICS_DENM_REPETITION_INTERVAL, v_denmEventsParmsPerZone[v_counter].eventPosition, v_denmEventsParmsPerZone[v_counter].causeCodeType, v_denmEventsParmsPerZone[v_counter].eventHistory, v_denmEventsParmsPerZone[v_counter].traces, PICS_DENM_VALIDITY_DURATION, PICS_DENM_RELEVANCE_DISTANCE, PICS_DENM_RELEVANCE_TRAFFIC_DIRECTION ); v_denms[v_counter] := valueof( m_denmPdu_rsu( PICS_RSU_PARAMS[p_rsu_id].stationID, m_denm( v_denmParmContainers.managementContainer, v_denmParmContainers.situationContainer, v_denmParmContainers.locationContainer ))); if (ispresent(v_denmEventsParmsPerZone[v_counter].roadWorksContainerExtended)) { v_denms[v_counter].denm.alacarte := m_alacarte(v_denmEventsParmsPerZone[v_counter].roadWorksContainerExtended); } } // End of 'for' statement // Update referenceDenms field, all except the current one for (v_counter := 0; v_counter < lengthof(PICS_DENM_EVENTS_RSU[p_rsu_id][PX_ETSI_ZONE_ID - 1]); v_counter := v_counter + 1) { if (ispresent(v_denms[v_counter].denm.alacarte.roadWorks)) { var integer v_referenceDenms := 0; for (var integer v_counter1 := 0; v_counter1 < lengthof(PICS_DENM_EVENTS_RSU[p_rsu_id][PX_ETSI_ZONE_ID - 1]); v_counter1 := v_counter1 + 1) { if (v_counter1 == v_counter) { continue; } v_denms[v_counter].denm.alacarte.roadWorks.referenceDenms[v_referenceDenms] := v_denms[v_counter1].denm.management.actionID; v_referenceDenms := v_referenceDenms + 1; } // End of 'for' statement } } // End of 'for' statement } else { vc_denm := false; } // CAM if (vc_cam == true) { // Build the list of the CAM events if (PX_ETSI_USE_CASE_ID == 9) { v_cam := m_camParm( PICS_RSU_PARAMS[p_rsu_id].stationID, m_rsuPosition( vc_longPosVectorRsu.latitude, vc_longPosVectorRsu.longitude ), PICS_RSU_PARAMS[p_rsu_id].pathHistory, m_highFrequencyContainer_rsuContainerHighFrequency( m_rSUContainerHighFrequency( PICS_USECASE9_PCZ ))); } else { v_cam := m_camParm( PICS_RSU_PARAMS[p_rsu_id].stationID, m_rsuPosition( vc_longPosVectorRsu.latitude, vc_longPosVectorRsu.longitude ), PICS_RSU_PARAMS[p_rsu_id].pathHistory, { rsuContainerHighFrequency := { protectedCommunicationZonesRSU := omit } } ); } } if (vc_beacon == true) { // Build the list of the BeACON events v_beacon := 'AAAAAAAA'O; // TODO Use a PICS } // Build the messages value list for this RSU vc_rsuMessagesValueList[p_rsu_id] := m_rsuProfile( v_beacon, v_cam, v_denms, v_mapem, v_spatems, v_ivim, v_ssem ); if (PICS_RSU_PARAMS[p_rsu_id].geoShape == e_geoCircle) { vc_geoArea := { shape := e_geoCircle, area := { geoAreaPosLatitude := vc_longPosVectorRsu.latitude, geoAreaPosLongitude := vc_longPosVectorRsu.longitude, distanceA := PICS_RSU_PARAMS[p_rsu_id].geoParms.radius, distanceB := PICS_RSU_PARAMS[p_rsu_id].geoParms.radius, angle := 0 } } } else { log("*** " & testcasename() & ": INCONC: Wrong PICS_RSU_GEOAREA_FORM event initialisation ***"); setverdict(inconc); stop; } } // End of function f_setup_rsu function f_process_cf_event( in CfEvent p_cfEvent ) runs on ItsRSUsSimulator return boolean { var template (value) CfResult v_result := true; // Terminate simulation if (p_cfEvent == "stop") { if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].beacon)) { tc_beacon.stop; } if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].cam)) { tc_cam.stop; } if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].denms)) { tc_denm.stop; } if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].mapem)) { tc_mapem.stop; } if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].spatems)) { tc_spatem.stop; } if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].ivim)) { tc_ivim.stop; } } else { v_result := false; } cfPort.send(v_result); return false; } // End of function f_process_cf_event function f_prepare_beacon( out template (value) Payload p_payload ) runs on ItsRSUsSimulator { p_payload := valueof( f_adaptPayload( vc_rsuMessagesValueList[vc_rsu_id].beacon, 0, -, e_any ) ); } // End of function f_prepare_beacon function f_prepare_cam( out template (value) Payload p_payload ) runs on ItsRSUsSimulator { vc_rsuMessagesValueList[vc_rsu_id].cam.cam.generationDeltaTime := f_getCurrentTime() mod 65536; // See ETSI EN 302 637-2 V1.3.0 - Clause B.3 generationDelatTime p_payload := valueof( f_adaptPayload( bit2oct( encvalue( valueof( vc_rsuMessagesValueList[vc_rsu_id].cam ))), PICS_CAM_BTP_DESTINATION_PORT, PICS_CAM_BTP_SOURCE_PORT ) ); } // End of function f_prepare_cam function f_prepare_denm( out template (value) Payload p_payload, in boolean p_cancellation := false ) runs on ItsRSUsSimulator { // Update dynamic parms vc_rsuMessagesValueList[vc_rsu_id].denms[vc_denmEventCounter].denm.management.referenceTime := f_getCurrentTime(); if (p_cancellation == true) { vc_rsuMessagesValueList[vc_rsu_id].denms[vc_denmEventCounter].denm.management.termination := isCancellation; } p_payload := valueof( f_adaptPayload( bit2oct( encvalue( valueof(vc_rsuMessagesValueList[vc_rsu_id].denms[vc_denmEventCounter] ))), PICS_DENM_BTP_DESTINATION_PORT, PICS_DENM_BTP_SOURCE_PORT ) ); vc_denmEventCounter := (vc_denmEventCounter + 1) mod lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms); } // End of function f_prepare_denm function f_prepare_mapem( out template (value) Payload p_payload ) runs on ItsRSUsSimulator { p_payload := valueof( f_adaptPayload( bit2oct( encvalue( valueof( vc_rsuMessagesValueList[vc_rsu_id].mapem ))), PICS_MAPEM_BTP_DESTINATION_PORT, PICS_MAPEM_BTP_SOURCE_PORT ) ); } // End of function f_prepare_mapem function f_computeEndPhaseStartTime( in TimeMark p_timeMark, in UInt32 p_inc ) return TimeMark { var UInt32 v_endPhaseStartTime := p_timeMark + p_inc; return v_endPhaseStartTime mod 36000; } function f_prepare_spatem( in template (value) SPATEM p_spatem, out template (value) Payload p_payload ) runs on ItsRSUsSimulator { var template (omit) SPATEM v_spatem := p_spatem; // Make a copy var TimeMark v_currentTimeMark := f_getCurrentTimeMark(); if (vc_currentPhaseStartTime == 36001) { vc_currentPhaseStartTime := v_currentTimeMark; vc_endPhaseStartTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, vc_repitition_duration[vc_spatemStatesId]); } if (v_currentTimeMark >= vc_endPhaseStartTime) { vc_spatemStatesId := (vc_spatemStatesId + 1) mod vc_spatemStatesNum; // Change state vc_currentPhaseStartTime := v_currentTimeMark; vc_endPhaseStartTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, vc_repitition_duration[vc_spatemStatesId]); } log("vc_currentPhaseStartTime = ", vc_currentPhaseStartTime); log("vc_endPhaseStartTime = ", vc_endPhaseStartTime); log("v_currentTimeMark = ", v_currentTimeMark); log("vc_spatemStatesId = ", vc_spatemStatesId); log("mintime#1 = ", vc_currentPhaseStartTime + vc_repitition_duration[(vc_spatemStatesId + 1) mod vc_spatemStatesNum]); log("mintime#2 = ", vc_currentPhaseStartTime + vc_repitition_duration[(vc_spatemStatesId + 2) mod vc_spatemStatesNum]); // Rebuild SPATEM message for (var integer v_intersection := 0; v_intersection < lengthof(v_spatem.spat.intersections); v_intersection := v_intersection + 1) { var template (omit) MovementList v_states := vc_states[vc_signalGroupParmId][v_intersection]; select (vc_spatemStatesId) { case (0) { v_spatem.spat.intersections[v_intersection].states[0] := v_states[0]; v_spatem.spat.intersections[v_intersection].states[1] := v_states[1]; v_spatem.spat.intersections[v_intersection].states[2] := v_states[2]; } case (1) { v_spatem.spat.intersections[v_intersection].states[0] := v_states[1]; v_spatem.spat.intersections[v_intersection].states[1] := v_states[2]; v_spatem.spat.intersections[v_intersection].states[2] := v_states[0]; } case (2) { v_spatem.spat.intersections[v_intersection].states[0] := v_states[2]; v_spatem.spat.intersections[v_intersection].states[1] := v_states[0]; v_spatem.spat.intersections[v_intersection].states[2] := v_states[1]; } case else { } } // End of 'select' statement // Update 'minEndTime' field v_spatem.spat.intersections[v_intersection].states[0].state_time_speed[0].timing.minEndTime := vc_currentPhaseStartTime; v_spatem.spat.intersections[v_intersection].states[1].state_time_speed[0].timing.minEndTime := vc_currentPhaseStartTime + vc_repitition_duration[(vc_spatemStatesId + 1) mod vc_spatemStatesNum]; v_spatem.spat.intersections[v_intersection].states[2].state_time_speed[0].timing.minEndTime := vc_currentPhaseStartTime + vc_repitition_duration[(vc_spatemStatesId + 2) mod vc_spatemStatesNum]; v_spatem.spat.intersections[v_intersection].timeStamp := f_getCurrentTime() mod 65536; v_spatem.spat.intersections[v_intersection].moy := f_getMinuteOfTheYear(); } // End of 'for' statement p_payload := valueof( f_adaptPayload( bit2oct( encvalue( valueof( v_spatem ))), PICS_SPATEM_BTP_DESTINATION_PORT, PICS_SPATEM_BTP_SOURCE_PORT ) ); } // End of function f_prepare_spatem function f_prepare_ivim( out template (value) Payload p_payload ) runs on ItsRSUsSimulator { p_payload := valueof( f_adaptPayload( bit2oct( encvalue( valueof( vc_rsuMessagesValueList[vc_rsu_id].ivim ))), PICS_IVIM_BTP_DESTINATION_PORT, PICS_IVIM_BTP_SOURCE_PORT ) ); } // End of function f_prepare_ivim function f_adaptPayload( in template (value) octetstring p_finalPayload, in template (value) BtpPortId p_destPort, in template (value) BtpPortId p_srcPort := 0, in NextHeader p_nextHeader := PX_GN_UPPER_LAYER ) return template (value) Payload { var template (value) Payload v_payload; if(p_nextHeader == e_any) { v_payload := { decodedPayload := omit, rawPayload := p_finalPayload}; return v_payload; } if(p_nextHeader == e_ipv6) { log("*** " & testcasename() & ": INCONC: Layer IPv6 not supported ***"); setverdict(inconc); stop; } if(p_nextHeader == e_btpA) { v_payload := { decodedPayload := { btpPacket := m_btpAWithPorts( p_destPort, p_srcPort, { decodedPayload := omit, rawPayload := p_finalPayload } ) }, rawPayload := ''O }; return v_payload; } if(p_nextHeader == e_btpB) { v_payload := { decodedPayload := { btpPacket := m_btpBWithPorts( p_destPort, p_srcPort, { decodedPayload := omit, rawPayload := p_finalPayload } ) }, rawPayload := ''O }; return v_payload; } return v_payload; } // End of function f_adaptPayload function f_send_vehicle_cam( in template (value) CAM p_camSimu, in CAM p_camVehicle ) runs on ItsRSUsSimulator { // Local variables var LongPosVector v_vehiclePosition := PICS_UC6_VEHICLE_POSITION; var float v_distanceToCollision; var SpeedValue v_vehicleSpeed := p_camVehicle.cam.camParameters.highFrequencyContainer.basicVehicleContainerHighFrequency.speed.speedValue; var template (value) Payload v_payload; // Compute distance to collision point v_vehiclePosition.latitude := p_camVehicle.cam.camParameters.basicContainer.referencePosition.latitude; v_vehiclePosition.longitude := p_camVehicle.cam.camParameters.basicContainer.referencePosition.longitude; v_distanceToCollision := LibItsGeoNetworking_Functions.f_distance( v_vehiclePosition, PICS_UC6_COLLISION_POINT ); // Compute time to collision point if (v_vehicleSpeed != 0) { var float v_timeToCollision := v_distanceToCollision / int2float(v_vehicleSpeed); // Updade simulated CAM to setup the same distance to the collision point // FIXME p_camSimu.cam.camParameters.basicContainer.referencePosition := PICS_USECASE6_VEHICLE_POSITIONS[p_idx]; // Update generationDeltaTime p_camSimu.cam.generationDeltaTime := f_getCurrentTime() mod 65536; // See ETSI EN 302 637-2 V1.3.0 - Clause B.3 generationDelatTime v_payload := valueof( f_adaptPayload( bit2oct( encvalue( valueof( p_camSimu ))), PICS_CAM_BTP_DESTINATION_PORT, PICS_CAM_BTP_SOURCE_PORT ) ); // Update GN vc_longPosVectorRsu := PICS_UC6_VEHICLE_POSITION; vc_longPosVectorRsu.latitude := valueof(p_camSimu.cam.camParameters.basicContainer.referencePosition.latitude); vc_longPosVectorRsu.longitude := valueof(p_camSimu.cam.camParameters.basicContainer.referencePosition.longitude); vc_geoArea := PICS_UC6_VEHICLE_GEOAREA; vc_geoArea.area.geoAreaPosLatitude := valueof(p_camSimu.cam.camParameters.basicContainer.referencePosition.latitude); vc_geoArea.area.geoAreaPosLongitude := valueof(p_camSimu.cam.camParameters.basicContainer.referencePosition.longitude); // And send it f_send(v_payload, PICS_CAM_ITS_AID); } else { } } // End of function f_send_vehicle_cam function f_send( in template (value) Payload p_payload, in UInt32 p_its_aid ) runs on ItsRSUsSimulator { var GeoNetworkingPdu v_geoNetworkingPdu; if (p_its_aid == 36) { // CAM v_geoNetworkingPdu := valueof(m_geoNwPdu( // FIXME Use PIXIT parameter to get a fully configurable template m_geoNwShbPacket_payload( vc_longPosVectorRsu, valueof(p_payload) ), m_defaultLifetime, c_defaultHopLimit )); } else { v_geoNetworkingPdu := valueof(m_geoNwPdu( // FIXME Use PIXIT parameter to get a fully configurable template m_geoNwBroadcastPacket_payload( // TODO modifes 'template (value) GnNonSecuredPacket m_geoNwBroadcastPacket' to set the field vc_longPosVectorRsu, f_incLocalSeqNumber(), f_geoArea2GeoBroadcastArea(vc_geoArea), -, -, valueof(p_payload) ), m_defaultLifetime, c_hopLimit1 )); } f_sendGeoNetMessage(valueof(m_geoNwReq_linkLayerBroadcast(v_geoNetworkingPdu, p_its_aid))); } // End of function f_send function f_processSrem( in GeoNetworkingPdu p_geoNetworkingPdu ) runs on ItsRSUsSimulator { log("SREM=", p_geoNetworkingPdu); if (ispresent(p_geoNetworkingPdu.gnPacket.packet.payload.decodedPayload)) { if (ispresent(p_geoNetworkingPdu.gnPacket.packet.payload.decodedPayload.btpPacket.payload.decodedPayload)) { if (ischosen(p_geoNetworkingPdu.gnPacket.packet.payload.decodedPayload.btpPacket.payload.decodedPayload.sremPacket)) { var SignalRequestMessage v_signalRequestMessage := p_geoNetworkingPdu.gnPacket.packet.payload.decodedPayload.btpPacket.payload.decodedPayload.sremPacket.srm; var template (value) Payload v_payload; log(v_signalRequestMessage); // Build response // TODO v_ssem.ssm.status v_payload := valueof( f_adaptPayload( bit2oct( encvalue( valueof( m_ssem( v_signalRequestMessage )))), PICS_SSEM_BTP_DESTINATION_PORT, PICS_SSEM_BTP_SOURCE_PORT ) ); // Send SSEM f_send(v_payload, PICS_SSEM_ITS_AID); } // else, ignore message } // else, ignore message } // else, ignore message } // End of function f_processSrem function f_incLocalSeqNumber() runs on ItsRSUsSimulator return UInt16 { vc_localSeqNumber := (vc_localSeqNumber + 1) mod 65536; return vc_localSeqNumber; } function f_incMsgIssueRevision() runs on ItsRSUsSimulator return MsgCount { vc_msgIssueRevision := (vc_msgIssueRevision + 1) mod 128; // See MsgCount declaration return vc_msgIssueRevision; } function f_getMsgIssueRevision() runs on ItsRSUsSimulator return MsgCount { return vc_msgIssueRevision; } function f_incDenmSequenceNumber() runs on ItsRSUsSimulator return SequenceNumber { vc_sequenceNumber := (vc_sequenceNumber + 1) mod 65536; // See SequenceNumber declaration return vc_sequenceNumber; } function f_getDenmSequenceNumber() runs on ItsRSUsSimulator return SequenceNumber { return vc_sequenceNumber; } } // End of module ItsRSUsSimulator_Functions