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; // 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 geoConfigurationFunctions { /** * @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 var template (value) DenmParmContainers v_denmParmContainers; 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; // Map map(self:acPort, system:acPort); map(self:utPort, system:utPort); map(self:geoNetworkingPort, system:geoNetworkingPort); // Connect f_connect4SelfOrClientSync(); activate(a_cf01Down()); // Initialise secured mode f_initialiseSecuredMode(); //Initialze the IUT // f_initialState(); // Initialisations vc_longPosVectorRsu := PICS_RSU_PARAMS[PX_RSU_ID - 1].longPosVector; // MAPEM if (PICS_GENERATE_MAPEM) { // Build the list of the MAPEM events v_mapem := m_mapemParm( PICS_RSU_PARAMS[PX_RSU_ID - 1].stationID, m_mapem( f_getMsgIssueRevision(), PICS_MAPEM_PARMS_RSUs[PX_RSU_ID - 1].intersections, PICS_MAPEM_PARMS_RSUs[PX_RSU_ID - 1].roadSegments )); // Update revision fields v_mapem.map_.intersections[0].revision := f_incMsgIssueRevision(); // TODO Add more? } // SPATEM if (PICS_GENERATE_SPATEM) { // Build the list of the DENM events for (v_counter := 0; v_counter < lengthof(PICS_SPATEM_PARMS_RSUs[PX_RSU_ID - 1]); v_counter := v_counter + 1) { v_spatems[v_counter] := m_spatemParm( PICS_RSU_PARAMS[PX_RSU_ID - 1].stationID, m_spatem( PICS_SPATEM_PARMS_RSUs[PX_RSU_ID - 1][v_counter].intersections, "SignalGroupID #" & int2str(PICS_SPATEM_PARMS_RSUs[PX_RSU_ID - 1][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 } // IVIM if (PICS_GENERATE_IVIM) { // Build the list of the MAPEM events v_ivim := m_ivimParm( PICS_RSU_PARAMS[PX_RSU_ID - 1].stationID, m_ivimStructure( m_iviManagementContainer( PICS_IVIM_PARMS_RSUs[PX_RSU_ID - 1].provider, PICS_IVIM_PARMS_RSUs[PX_RSU_ID - 1].iviIdentificationNumber, 0//IviStatus_new_ ))); // Update ivi status v_ivim.ivi.mandatory.validFrom := f_getCurrentTime(); // TODO Add more? } // DENM if (PICS_GENERATE_DENM) { // Build the list of the DENM events for (v_counter := 0; v_counter < lengthof(PICS_DENM_EVENTS_RSU[PX_RSU_ID - 1][PX_ETSI_ZONE_ID]); v_counter := v_counter + 1) { var DenmEventsParmsPerZone v_denmEventsParmsPerZone := PICS_DENM_EVENTS_RSU[PX_RSU_ID - 1][PX_ETSI_ZONE_ID]; v_denmParmContainers := m_denmParmContainers( PICS_RSU_PARAMS[PX_RSU_ID - 1].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 ); v_denms[v_counter] := valueof( m_denmPdu( 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 } // CAM if (PICS_GENERATE_CAM) { // Build the list of the CAM events v_cam := m_camParm( PICS_RSU_PARAMS[PX_RSU_ID - 1].stationID, m_rsuPosition( vc_longPosVectorRsu.latitude, vc_longPosVectorRsu.longitude ), PICS_RSU_PARAMS[PX_RSU_ID - 1].pathHistory ); } // Build the messages value list for this RSU vc_rsuMessagesValueList[PX_RSU_ID - 1] := m_rsuProfile( v_cam, v_denms, v_mapem, v_spatems, v_ivim, v_ssem ); if (PICS_RSU_PARAMS[PX_RSU_ID - 1].geoShape == e_geoCircle) { vc_geoArea := f_computeCircularArea(vc_longPosVectorRsu, PICS_RSU_PARAMS[PX_RSU_ID - 1].geoParms.radius); } else { log("*** " & testcasename() & ": INCONC: Wrong PICS_RSU_GEOAREA_FORM event initialisation ***"); setverdict(inconc); stop; } } // End of function f_cf01Up function f_cf01Down() runs on ItsRSUsSimulator { vc_longPosVectorRsu := {}; vc_geoArea := {}; vc_rsuMessagesValueList := {}; f_uninitialiseSecuredMode(); // Unmap unmap(self:acPort, system:acPort); unmap(self:utPort, system:utPort); unmap(self:geoNetworkingPort, system:geoNetworkingPort); // Disconnect f_disconnect4SelfOrClientSync(); } // End of function f_cf01Down } // End of group geoConfigurationFunctions function f_prepare_cam( out template (value) Payload p_payload ) runs on ItsRSUsSimulator { vc_rsuMessagesValueList[PX_RSU_ID - 1].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[PX_RSU_ID - 1].cam ))), PICS_CAM_BTP_DESTINATION_PORT, PICS_CAM_BTP_SOURCE_PORT ) ); } function f_prepare_denm( out template (value) Payload p_payload ) runs on ItsRSUsSimulator { // Update dynamic parms vc_rsuMessagesValueList[PX_RSU_ID - 1].denms[vc_denmEventCounter].denm.management.referenceTime := f_getCurrentTime(); p_payload := valueof( f_adaptPayload( bit2oct( encvalue( valueof(vc_rsuMessagesValueList[PX_RSU_ID - 1].denms[vc_denmEventCounter] ))), PICS_DENM_BTP_DESTINATION_PORT, PICS_DENM_BTP_SOURCE_PORT ) ); vc_denmEventCounter := (vc_denmEventCounter + 1) mod lengthof(vc_rsuMessagesValueList[PX_RSU_ID - 1].denms); } function f_prepare_mapem( out template (value) Payload p_payload ) runs on ItsRSUsSimulator { p_payload := valueof( f_adaptPayload( bit2oct( encvalue( valueof( vc_rsuMessagesValueList[PX_RSU_ID - 1].mapem ))), PICS_MAPEM_BTP_DESTINATION_PORT, PICS_MAPEM_BTP_SOURCE_PORT ) ); } function f_prepare_spatem( in template (value) SPATEM p_spatem, out template (value) Payload p_payload ) runs on ItsRSUsSimulator { var template (value) SPATEM v_spatem := p_spatem; // Make a copy // Rebuild SPATEM message for (var integer v_intersection := 0; v_intersection < lengthof(v_spatem.spat.intersections); v_intersection := v_intersection + 1) { var template (value) MovementList v_states := vc_states[PX_RSU_ID - 1][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 } // End of 'for' statement vc_spatemStatesId := (vc_spatemStatesId + 1) mod 4; // TODO To be refined p_payload := valueof( f_adaptPayload( bit2oct( encvalue( valueof( v_spatem ))), PICS_SPATEM_BTP_DESTINATION_PORT, PICS_SPATEM_BTP_SOURCE_PORT ) ); } function f_prepare_ivim( out template (value) Payload p_payload ) runs on ItsRSUsSimulator { p_payload := valueof( f_adaptPayload( bit2oct( encvalue( valueof( vc_rsuMessagesValueList[PX_RSU_ID - 1].ivim ))), PICS_IVIM_BTP_DESTINATION_PORT, PICS_IVIM_BTP_SOURCE_PORT ) ); } function f_adaptPayload( in template (value) octetstring p_finalPayload, in template (value) BtpPortId p_destPort, in template (value) BtpPortId p_srcPort := 0 ) return template (value) Payload { var template (value) Payload v_payload; if(PX_GN_UPPER_LAYER == e_any) { v_payload := { decodedPayload := omit, rawPayload := p_finalPayload}; return v_payload; } if(PX_GN_UPPER_LAYER == e_ipv6) { log("*** " & testcasename() & ": INCONC: Layer IPv6 not supported ***"); setverdict(inconc); stop; } if(PX_GN_UPPER_LAYER == e_btpA) { v_payload := { decodedPayload := { btpPacket := m_btpAWithPorts( p_destPort, p_srcPort, { decodedPayload := omit, rawPayload := p_finalPayload } ) }, rawPayload := ''O }; return v_payload; } if(PX_GN_UPPER_LAYER == 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; } function f_send( in template (value) Payload p_payload ) runs on ItsRSUsSimulator { var GeoNetworkingPdu v_geoNetworkingPdu; 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_defaultHopLimit )); f_sendGeoNetMessage(valueof(m_geoNwReq_linkLayerBroadcast(v_geoNetworkingPdu))); } 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 ) ); } // else, ignore message } // else, ignore message } // else, ignore message // TODO Process message, and send SSEM } 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