module ItsAutoInterop_Functions { // LibCommon import from LibCommon_BasicTypesAndValues all; import from LibCommon_DataStrings all; import from LibCommon_VerdictControl all; import from LibCommon_Sync all; // LibIts import from ITS_Container language "ASN.1:1997" all; import from DENM_PDU_Descriptions language "ASN.1:1997" all; import from CAM_PDU_Descriptions language "ASN.1:1997" all; import from IEEE1609dot2BaseTypes language "ASN.1:1997" all; import from IEEE1609dot2 language "ASN.1:1997" all; import from EtsiTs103097Module language "ASN.1:1997" all; // LibItsCommon import from LibItsCommon_TypesAndValues all; import from LibItsCommon_Templates all; import from LibItsCommon_Functions all; import from LibItsCommon_Pixits all; import from LibItsCommon_TestSystem all; import from LibItsCommon_ASN1_NamedNumbers all; // LibItsGeoNetworking import from LibItsGeoNetworking_TypesAndValues all; import from LibItsGeoNetworking_Templates all; import from LibItsGeoNetworking_Pics all; import from LibItsGeoNetworking_Functions all; import from LibItsGeoNetworking_TestSystem all; // LibItsBtp import from LibItsBtp_TypesAndValues all; // LibItsSecurity import from LibItsSecurity_TypesAndValues all; import from LibItsSecurity_Templates all; import from LibItsSecurity_Functions all; import from LibItsSecurity_Pixits all; // ItsInterop import from ItsAutoInterop_TypesAndValues all; import from ItsAutoInterop_Templates all; import from ItsAutoInterop_TestSystem all; import from ItsAutoInterop_Pixits all; group utFunctions { /** * @desc Triggers event from the application layer * @param p_event The event to trigger. */ function f_utTriggerEvent(template (value) UtAutoInteropTrigger p_event) runs on ItsBaseGeoNetworking { //deactivate autoInteropPort default alts vc_gnDefaultActive := false; utPort.send(p_event); tc_wait.start; alt { [] utPort.receive(UtGnResults: { utAutoInteropTriggerResult := true }) { tc_wait.stop; } [] utPort.receive(UtGnResults: { utAutoInteropTriggerResult := false }) { tc_wait.stop; log("*** f_utTriggerEvent: INFO: IUT trigger was not successful ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] utPort.receive { tc_wait.stop; log("*** f_utTriggerEvent: INFO: IUT trigger was not successful ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] tc_wait.timeout { } } //activate autoInteropPort default alts vc_gnDefaultActive := true; } } // End of group utFunctions group hmiFunctions { /** * @desc Requests to bring the HMI in an initial state * @param p_init The initialisation to trigger. */ function f_hmiInitializeIut(template (value) HmiInitialize p_init) runs on ItsAutoInteropGeonetworking { //deactivate autoInteropPort default alts vc_gnDefaultActive := false; hmiPort.send(p_init); tc_wait.start; alt { //FIXME RGY As discussed, port in type is changed to a top-level union type // [] hmiPort.receive(HmiInitializeResult:true) { [] hmiPort.receive(HmiAutoInteropResults:{hmiInitializeResult:=true}) { tc_wait.stop; log("*** f_hmiInitializeIhmi: INFO: EUT's HMI initialized ***"); } [] hmiPort.receive { tc_wait.stop; log("*** f_hmiInitializeIhmi: INFO: EUT's HMI could not be initialized ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] tc_wait.timeout { log("*** f_hmiInitializeIhmi: INFO: EUT's HMI could not be initialized in time ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); } } //activate autoInteropPort default alts vc_gnDefaultActive := true; } } // End of group hmiFunctions group preambles { /** * @desc Set up an EUT component * @param p_eut The component reference * @param p_scenario The GNSS scenario. Default: e_staticPosition */ function f_cfPtcUp( in ItsAutoInteropGeonetworking p_eut, in Scenario p_scenario := e_staticPosition // TODO Not used ) runs on ItsAutoInteropGeonetworking /* TITAN TODO: mtc ItsMtc system ItsAutoInteropGeoNetworkingSystem */ { // EUT if (PX_CAPTURE_MODE == "on-link") { map(p_eut:acPort, system:acPort); map(p_eut:utPort, system:utPort); map(p_eut:hmiPort, system:hmiPort); } map(p_eut:geoNetworkingPort, system:geoNetworkingPort); //activate(a_cfPtcDown()); // FIXME To be done //Initialze the IUT LibItsGeoNetworking_Functions.f_initialiseSecuredMode(); // MTC intializes IUT ItsAutoInterop_Functions.f_initialState(p_scenario); // TODO Create an AtsAtoInterop f_initialState function } // End of function f_cfPtcUp /** * @desc Set up MTC for configuration #1 * @param p_eut1 The component reference for EUT1 * @param p_eut2 The component reference for EUT2 * @param p_eut3 The component reference for EUT3 * @param p_eut4 The component reference for EUT4 * @see Draft ETSI TS yyy xxx-2 V0.0.8 (2017-02) Clause 5.3.1 CF-01: Verify complete forwarding message scenario */ function f_mtcCf01Up( inout ItsAutoInteropGeonetworking p_eut1, inout ItsAutoInteropGeonetworking p_eut2, inout ItsAutoInteropGeonetworking p_eut3, inout ItsAutoInteropGeonetworking p_eut4 ) runs on ItsMtc /* TITAN TODO: mtc ItsMtc system ItsAutoInteropGeoNetworkingSystem */ { // Create components p_eut1 := ItsAutoInteropGeonetworking.create(c_compNodeB) alive; p_eut2 := ItsAutoInteropGeonetworking.create(c_compNodeC) alive; p_eut3 := ItsAutoInteropGeonetworking.create(c_compNodeD) alive; p_eut4 := ItsAutoInteropGeonetworking.create(c_compNodeE) alive; // Map & Connect if (PX_CAPTURE_MODE == "on-link") { map(self:acPort, system:acPort); map(self:utPort, system:utPort); } connect(self:syncPort, mtc:syncPort); connect(p_eut1:syncPort, self:syncPort); connect(p_eut2:syncPort, self:syncPort); connect(p_eut3:syncPort, self:syncPort); connect(p_eut4:syncPort, self:syncPort); // EUT1/EUT2/EUT3/EUT4 connect(p_eut1:eutGeoNetworkingPort, p_eut2:eutGeoNetworkingPort); // EUT1 & EUT2 are on-link connect(p_eut1:eutGeoNetworkingPort, p_eut3:eutGeoNetworkingPort); // EUT1 & EUT3 are on-link connect(p_eut2:eutGeoNetworkingPort, p_eut3:eutGeoNetworkingPort); // EUT2 & EUT3 are on-link connect(p_eut2:eutGeoNetworkingPort, p_eut4:eutGeoNetworkingPort); // EUT2 & EUT4 are on-link connect(p_eut3:eutGeoNetworkingPort, p_eut3:eutGeoNetworkingPort); // EUT3 & EUT4 are on-link // EUT1 & EUT4 are of-link activate(a_mtcCf01Down()); } // End of function f_mtcCf01Up /** * @desc Set up MTC for configuration #2 * @param p_eut1 The component reference for EUT1 * @param p_eut2 The component reference for EUT2 * @see Draft ETSI TS yyy xxx-2 V0.0.8 (2017-02) Clause 5.3.2 CF-02: Road Works Warning configuration */ function f_mtcCf02Up( inout ItsAutoInteropGeonetworking p_eut1, inout ItsAutoInteropGeonetworking p_eut2 ) runs on ItsMtc /* TITAN TODO: mtc ItsMtc system ItsAutoInteropGeoNetworkingSystem */ { // Create components p_eut1 := ItsAutoInteropGeonetworking.create(c_compNodeB); p_eut2 := ItsAutoInteropGeonetworking.create(c_compNodeC); // Map & Connect if (PX_CAPTURE_MODE == "on-link") { map(self:acPort, system:acPort); map(self:utPort, system:utPort); } connect(self:syncPort, mtc:syncPort); connect(p_eut1:syncPort, self:syncPort); connect(p_eut2:syncPort, self:syncPort); // EUT1/EUT2 connect(p_eut1:eutGeoNetworkingPort, p_eut2:eutGeoNetworkingPort); activate(a_mtcCf02Down()); } // End of function f_mtcCf02Up /** * @desc Set up MTC for configuration #3 * @param p_eut1 The component reference for EUT1 * @param p_eut2 The component reference for EUT2 * @param p_eut3 The component reference for EUT3 * @see Draft ETSI TS yyy xxx-2 V0.0.8 (2017-02) Clause 5.3.3 CF-03: CA messages */ function f_mtcCf03Up( inout ItsAutoInteropGeonetworking p_eut1, inout ItsAutoInteropGeonetworking p_eut2, inout ItsAutoInteropGeonetworking p_eut3 ) runs on ItsMtc /* TITAN TODO: mtc ItsMtc system ItsAutoInteropGeoNetworkingSystem */ { // Create components p_eut1 := ItsAutoInteropGeonetworking.create(c_compNodeB) alive; p_eut2 := ItsAutoInteropGeonetworking.create(c_compNodeC) alive; p_eut3 := ItsAutoInteropGeonetworking.create(c_compNodeD) alive; // Map & Connect if (PX_CAPTURE_MODE == "on-link") { map(self:acPort, system:acPort); map(self:utPort, system:utPort); } connect(self:syncPort, mtc:syncPort); connect(p_eut1:syncPort, self:syncPort); connect(p_eut2:syncPort, self:syncPort); connect(p_eut3:syncPort, self:syncPort); // EUT1/EUT2/EUT3 connect(p_eut1:eutGeoNetworkingPort, p_eut2:eutGeoNetworkingPort); connect(p_eut1:eutGeoNetworkingPort, p_eut3:eutGeoNetworkingPort); connect(p_eut2:eutGeoNetworkingPort, p_eut3:eutGeoNetworkingPort); activate(a_mtcCf03Down()); } // End of function f_mtcCf03Up /** * @desc Brings the IUT into an initial state. * @remark Component variable vc_hashedId8ToBeUsed shall be set with the IUT certificate to be used */ function f_initialState(Scenario p_scenario := e_staticPosition) runs on ItsBaseGeoNetworking { if (PICS_GN_SECURITY) { var Oct8 v_hashedId8ToBeUsed := f_setupIutCertificate(vc_hashedId8ToBeUsed); if (oct2int(v_hashedId8ToBeUsed) == 0) { v_hashedId8ToBeUsed := 'FFFFFFFFFFFFFFFF'O; // Reset to unknown value, the IUT will use its own certificates } if (PX_CAPTURE_MODE == "on-link") { f_utInitializeIut(m_secGnInitialize(v_hashedId8ToBeUsed)); } } // else, default behavior else { if (PX_CAPTURE_MODE == "on-link") { f_utInitializeIut(m_gnInitialize); } } f_acLoadScenario(p_scenario); f_acStartScenario(); } /** * @desc The default preamble. */ function f_prDefault() runs on ItsAutoInteropGeonetworking { activate(ItsAutoInterop_Functions.a_default()); activate(LibItsGeoNetworking_Functions.a_default()); if (PX_CAPTURE_MODE == "on-link") { activate(LibItsGeoNetworking_Functions.a_utDefault()); activate(a_hmiDefault()); } } } // End of group preambles group postambles { /** * @desc Shutdown an EUT component * @param p_eut The component reference */ function f_cfPtcDown( inout ItsAutoInteropGeonetworking p_eut ) runs on ItsAutoInteropGeonetworking /* TITAN TODO: mtc ItsMtc system ItsAutoInteropGeoNetworkingSystem */ { // Wait components done deactivate; // EUT if (PX_CAPTURE_MODE == "on-link") { unmap(p_eut:acPort, system:acPort); unmap(p_eut:utPort, system:utPort); unmap(p_eut:hmiPort, system:hmiPort); } unmap(p_eut:geoNetworkingPort, system:geoNetworkingPort); disconnect(p_eut:syncPort, self:syncPort); } // End of function f_cfPtcDown /** * @desc Shutdown MTC for configuration #1 * @param p_eut1 The component reference for EUT1 * @param p_eut2 The component reference for EUT2 * @param p_eut3 The component reference for EUT3 * @param p_eut4 The component reference for EUT4 * @see Draft ETSI TS yyy xxx-2 V0.0.8 (2017-02) Clause 5.3.1 CF-01: Verify complete forwarding message scenario */ function f_mtcCf01Down( inout ItsAutoInteropGeonetworking p_eut1, inout ItsAutoInteropGeonetworking p_eut2, inout ItsAutoInteropGeonetworking p_eut3, inout ItsAutoInteropGeonetworking p_eut4 ) runs on ItsMtc /* TITAN TODO: mtc ItsMtc system ItsAutoInteropGeoNetworkingSystem */ { // Wait components done p_eut1.done; p_eut2.done; p_eut3.done; p_eut4.done; deactivate; // Unmap & disconnect if (PX_CAPTURE_MODE == "on-link") { unmap(self:acPort, system:acPort); unmap(self:utPort, system:utPort); } disconnect(self:syncPort, mtc:syncPort); // EUT1/EUT2/EUT3/EUT4 disconnect(p_eut1:eutGeoNetworkingPort, p_eut2:eutGeoNetworkingPort); disconnect(p_eut1:eutGeoNetworkingPort, p_eut3:eutGeoNetworkingPort); disconnect(p_eut2:eutGeoNetworkingPort, p_eut3:eutGeoNetworkingPort); disconnect(p_eut2:eutGeoNetworkingPort, p_eut4:eutGeoNetworkingPort); disconnect(p_eut3:eutGeoNetworkingPort, p_eut3:eutGeoNetworkingPort); } // End of function f_mtcCf01Down /** * @desc Shutdown MTC for configuration #2 * @param p_eut1 The component reference for EUT1 * @param p_eut2 The component reference for EUT2 * @see Draft ETSI TS yyy xxx-2 V0.0.8 (2017-02) Clause 5.3.2 CF-02: Road Works Warning configuration */ function f_mtcCf02Down( inout ItsAutoInteropGeonetworking p_eut1, inout ItsAutoInteropGeonetworking p_eut2 ) runs on ItsMtc /* TITAN TODO: mtc ItsMtc system ItsAutoInteropGeoNetworkingSystem */ { // Wait components done p_eut1.done; p_eut2.done; deactivate; // Unmap & disconnect if (PX_CAPTURE_MODE == "on-link") { unmap(self:acPort, system:acPort); unmap(self:utPort, system:utPort); } disconnect(self:syncPort, mtc:syncPort); // EUT1/EUT2 disconnect(p_eut1:eutGeoNetworkingPort, p_eut2:eutGeoNetworkingPort); } // End of function f_mtcCf02Down /** * @desc Shutdown MTC with three components * @param p_eut1 The component reference for EUT1 * @param p_eut2 The component reference for EUT2 * @param p_eut3 The component reference for EUT3 */ function f_mtcCf03Down( inout ItsAutoInteropGeonetworking p_eut1, inout ItsAutoInteropGeonetworking p_eut2, inout ItsAutoInteropGeonetworking p_eut3 ) runs on ItsMtc /* TITAN TODO: mtc ItsMtc system ItsAutoInteropGeoNetworkingSystem */ { // Wait components done p_eut1.done; p_eut2.done; p_eut3.done; deactivate; // Unmap & disconnect if (PX_CAPTURE_MODE == "on-link") { unmap(self:acPort, system:acPort); unmap(self:utPort, system:utPort); } disconnect(self:syncPort, mtc:syncPort); // EUT1/EUT2/EUT3 disconnect(p_eut1:eutGeoNetworkingPort, p_eut2:eutGeoNetworkingPort); disconnect(p_eut1:eutGeoNetworkingPort, p_eut3:eutGeoNetworkingPort); disconnect(p_eut3:eutGeoNetworkingPort, p_eut3:eutGeoNetworkingPort); } // End of function f_mtcCf03Down /** * @desc The default postamble. */ function f_poDefault() runs on ItsAutoInteropGeonetworking { deactivate; LibItsGeoNetworking_Functions.f_acStopScenario(); } } // End of group postambles group checkFunctions { function f_payload_template( in BtpPortId p_dst_port, in BtpPortId p_src_port, in ItsPduHeader.messageID p_messageID, in integer p_stationID ) return template octetstring { var template octetstring v_out := int2oct(p_dst_port, 2) & int2oct(p_src_port, 2) & int2oct(LibItsCommon_ASN1_NamedNumbers.ItsPduHeader_protocolVersion_currentVersion_, 1) & int2oct(p_messageID, 1) & int2oct(p_stationID, 4) & ? length (1) & ?; return v_out; } function f_check_payload_cam( in GeoNetworkingInd v_gnInd, template (present) CAM p_cam, out ThreeDLocation p_position ) return boolean { var bitstring v_btp_payload := oct2bit(substr(v_gnInd.msgIn.gnPacket.packet.payload, 0, 4)); // FIXMEM Skip BTP, check if it is acceptable in an ATS var bitstring v_cam_payload := oct2bit(substr(v_gnInd.msgIn.gnPacket.packet.payload, 4, lengthof(v_gnInd.msgIn.gnPacket.packet.payload) - 4)); // FIXMEM Skip BTP, check if it is acceptable in an ATS var CAM v_decoded_cam; // TODO Check BTP // Check Btp paylod if (decvalue(v_cam_payload, v_decoded_cam) == 0) { log("f_check_payload_cam: checking ", v_decoded_cam); if (match(valueof(v_decoded_cam), p_cam) == true) { p_position.latitude := v_decoded_cam.cam.camParameters.basicContainer.referencePosition.latitude; p_position.longitude := v_decoded_cam.cam.camParameters.basicContainer.referencePosition.longitude; p_position.elevation := 0;//v_decoded_cam.cam.camParameters.basicContainer.referencePosition.altitude; log("<<< f_check_payload_cam: true"); return true; } } else { log("f_check_payload_cam: decvalue failed: ", bit2oct(v_cam_payload)); } log("<<< f_check_payload_cam: false"); return false; } // End of function f_check_payload_cam function f_check_payload_denm( in GeoNetworkingInd v_gnInd, template (present) DENM p_denm ) return boolean { var bitstring v_btp_payload := oct2bit(substr(v_gnInd.msgIn.gnPacket.packet.payload,0, 4)); // FIXMEM Skip BTP, check if it is acceptable in an ATS var bitstring v_denm_payload := oct2bit(substr(v_gnInd.msgIn.gnPacket.packet.payload, 4, lengthof(v_gnInd.msgIn.gnPacket.packet.payload) - 4)); // FIXMEM Skip BTP, check if it is acceptable in an ATS var DENM v_decoded_denm; // TODO Check BTP // Check Btp paylod log(">>> f_check_payload_denm"); if (decvalue(v_denm_payload, v_decoded_denm) == 0) { log("f_check_payload_denm: checking ", v_decoded_denm); if (match(valueof(v_decoded_denm), p_denm) == true) { log("<<< f_check_payload_denm: true"); return true; } } else { log("f_check_payload_denm: decvalue failed: ", bit2oct(v_denm_payload)); } log("<<< f_check_payload_denm: false"); return false; } // End of function f_check_payload_denm } // End of group checkFunctions group autoInteropPosition { /** * @desc Compute distance between two points * @param p_pointA First point * @param p_pointB Second point * @return Computed distance in meters * @see fx_computeDistance */ function f_distance( in ThreeDLocation p_pointA, in ThreeDLocation p_pointB ) return float { log("*** f_distance: INFO: calling PointA: ", p_pointA); log("*** f_distance: INFO: calling PointB: ", p_pointB); return fx_computeDistance(p_pointA.latitude, p_pointA.longitude, p_pointB.latitude, p_pointB.longitude); } } // End of group autoInteropPosition group autoInteropAltsteps { /** * @desc The base default. */ altstep a_default() runs on ItsAutoInteropGeonetworking { // Local variables var GeoNetworkingInd v_gnInd; [vc_gnDefaultActive] geoNetworkingPort.receive( mw_geoNwInd( ? )) -> value v_gnInd { // Unexpected GeoNetworking message ==> require refine filtering above log("*** a_default: ERROR: Received a GN message", v_gnInd, " ***"); f_selfOrClientSyncAndVerdict("error", e_error); // Re-send DEN message to the other EUTs // eutGeoNetworkingPort.send( // m_forward_geoNetworkingInd( // v_gnInd // )); } [] eutGeoNetworkingPort.receive( mw_eutGeoNwInd( mw_geoNwPdu( mw_geoNwBroadcastPacketWithNextHeaderAndPayload(?, ?, ?, ?) ))) { log("*** a_default: INFO: Received a GeoBroadcast message ***"); repeat; } [] eutGeoNetworkingPort.receive( mw_eutGeoNwInd( mw_geoNwPdu( mw_geoNwShbPacketWithNextHeaderAndPayload ))) { log("*** a_default: INFO: Received a SHB message ***"); repeat; } [] eutGeoNetworkingPort.receive { // Unexpected EutGeoNetworking message ==> require refine filtering above log("*** a_default: INFO: Received an unexpected message ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] a_shutdown() { log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***"); stop; } } /** * @desc The default for handling HMI messages. */ altstep a_hmiDefault() runs on ItsAutoInteropGeonetworking { var HmiNeighborEventInds v_hmiNeighborEventInds; var HmiSignageEventInd v_hmiSignageEventInd; [vc_hmiDefaultActive] hmiPort.receive(HmiNeighborEventInds:?) -> value v_hmiNeighborEventInds { //store every upper tester indication received vc_hmiNeighborEventIndsList[lengthof(vc_hmiNeighborEventIndsList)] := v_hmiNeighborEventInds; repeat; } [vc_hmiDefaultActive] hmiPort.receive { log("*** " & testcasename() & ": INFO: Received unexpected UT message from IUT ***"); repeat; } [vc_hmiDefaultActive] hmiPort.receive(HmiSignageEventInd:?) -> value v_hmiSignageEventInd { //store every upper tester indication received vc_hmiSignageEventIndList[lengthof(vc_hmiSignageEventIndList)] := v_hmiSignageEventInd; repeat; } [vc_hmiDefaultActive] hmiPort.receive { log("*** " & testcasename() & ": INFO: Received unexpected UT message from IUT ***"); repeat; } } /** * @desc Default handling cf01 de-initialisation. */ altstep a_mtcCf01Down(/* inout ItsAutoInteropGeonetworking p_eut1, inout ItsAutoInteropGeonetworking p_eut2, inout ItsAutoInteropGeonetworking p_eut3, inout ItsAutoInteropGeonetworking p_eut4*/ ) runs on ItsMtc /* TITAN TODO: mtc ItsMtc system ItsAutoInteropGeoNetworkingSystem */ { [] a_shutdown() { // f_mtcCf01Down(p_eut1, p_eut2, p_eut3, p_eut4); log("*** a_mtcCf01Down: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***"); stop; } } /** * @desc Default handling cf02 de-initialisation. */ altstep a_mtcCf02Down( /*inout ItsAutoInteropGeonetworking p_eut1, inout ItsAutoInteropGeonetworking p_eut2*/ ) runs on ItsMtc /* TITAN TODO: mtc ItsMtc system ItsAutoInteropGeoNetworkingSystem */ { [] a_shutdown() { // f_mtcCf02Down(p_eut1, p_eut2); log("*** a_mtcCf02Down: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***"); stop; } } /** * @desc Default handling cf03 de-initialisation. */ altstep a_mtcCf03Down( /*inout ItsAutoInteropGeonetworking p_eut1, inout ItsAutoInteropGeonetworking p_eut2, inout ItsAutoInteropGeonetworking p_eut3*/ ) runs on ItsMtc /* TITAN TODO: mtc ItsMtc system ItsAutoInteropGeoNetworkingSystem */ { [] a_shutdown() { // f_mtcCf03Down(p_eut1, p_eut2, p_eut3); log("*** a_mtcCf03Down: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***"); stop; } } } // End of group autoInteropAltsteps } // End of module ItsAutoInterop_Functions