/** * @author ETSI / STF481 * @version $URL$ * $Id$ * @desc Module containing functions for the secured GN ATS * */ module AtsSecurity_Functions { // LibIts import from DENM_PDU_Descriptions language "ASN.1:1997" all; import from ITS_Container language "ASN.1:1997" all; // LibCommon import from LibCommon_BasicTypesAndValues all; import from LibCommon_Time all; // LibItsCommon import from LibItsCommon_TypesAndValues all; import from LibItsCommon_TestSystem all; import from LibItsCommon_Functions all; // LibItsDenm import from LibItsDenm_TypesAndValues all; import from LibItsDenm_Templates all; import from LibItsDenm_Functions all; import from LibItsDenm_TestSystem all; // LibItsCam // import from LibItsCam_TypesAndValues all; import from LibItsCam_Templates all; import from LibItsCam_Functions all; import from LibItsCam_TestSystem all; // LibItsGeoNetworking import from LibItsGeoNetworking_TestSystem all; import from LibItsGeoNetworking_Functions all; import from LibItsGeoNetworking_Templates all; import from LibItsGeoNetworking_TypesAndValues all; // LibItsSecurity import from LibItsSecurity_TypesAndValues all; import from LibItsSecurity_Templates all; import from LibItsSecurity_Functions all; import from LibItsSecurity_Pixits all; group secCam { /** * @desc Prepare a secured CAM * @param p_configId The configuration identifier to be used * @param p_headerFields HeaderFields to be inserted in the message * @param p_signerInfoType Add digest or AT certificate or certificate chain * @param p_addMissingHeaders Whether to add mandatory headers not present in p_headerFields * @return Secured GeoNetworking packet containing a CAM */ function f_prepareSecuredCam( in charstring p_configId, in template (omit) HeaderFields p_headerFields := omit, in SignerInfoType p_signerInfoType := e_certificate_digest_with_sha256, in boolean p_addMissingHeaders := true ) runs on ItsGeoNetworking return GeoNetworkingPdu { // Local variables var GnNonSecuredPacket v_gnNonSecuredPacket; var octetstring v_gnPayload; var template (value) SecuredMessage v_securedMessage; // Build signed SecuredMessage v_gnNonSecuredPacket := valueof(m_geoNwShbPacket( f_getPosition(c_compNodeC) )); // Add CAM payload v_gnNonSecuredPacket.payload := valueof( f_adaptPayload_m( bit2oct( encvalue( m_camReq( m_camMsg_vehicle_HF_BV( f_getTsStationId(), f_getCurrentTime() mod 65536, // See ETSI EN 302 637-2 V1.3.0 - Clause B.3 generationDelatTime LibItsCam_Templates.m_tsPosition )))))); // Encode it v_gnPayload := bit2oct( encvalue( v_gnNonSecuredPacket ) ); f_buildGnSecuredCam( v_securedMessage, m_payload_signed(v_gnPayload), p_signerInfoType, p_headerFields, p_configId, p_addMissingHeaders ); // Return secured Gn packet return valueof(m_geoNwSecPdu(v_gnNonSecuredPacket, v_securedMessage)); } // End of function f_prepareSecuredCam /** * @desc Sends a secured CAM * @param p_configId The configuration identifier to be used * @param p_headerFields Additional HeaderFields * @param p_signerInfoType Add digest or AT certificate or certificate chain * @return GeoNetworking payload */ function f_sendSecuredCam( in charstring p_configId, in template (omit) HeaderFields p_headerFields := omit, in SignerInfoType p_signerInfoType := e_certificate_digest_with_sha256 ) runs on ItsGeoNetworking return GeoNetworkingPdu { // Local variables var GeoNetworkingPdu v_securedGnPdu := f_prepareSecuredCam(p_configId, p_headerFields, p_signerInfoType); f_sendGeoNetMessage(m_geoNwReq_linkLayerBroadcast(v_securedGnPdu)); return v_securedGnPdu; } // End of function f_sendSecuredCam } // End of group secCam group secDenm { /** * @desc Prepare a secured CENM * @param p_configId The configuration identifier to be used * @param p_headerFields HeaderFields to be inserted in the message * @param p_signerInfoType Add digest or AT certificate or certificate chain * @param p_addMissingHeaders Whether to add mandatory headers not present in p_headerFields * @return Secured GeoNetworking packet containing a CAM */ function f_prepareSecuredDenm( in charstring p_configId, in template (omit) HeaderFields p_headerFields := omit, in SignerInfoType p_signerInfoType := e_certificate_digest_with_sha256, in boolean p_addMissingHeaders := true ) runs on ItsGeoNetworking return GeoNetworkingPdu { // Local variables var GnNonSecuredPacket v_gnNonSecuredPacket; var octetstring v_gnPayload; var LongPosVector v_longPosVectorNodeC := f_getPosition(c_compNodeC); var template (value) SecuredMessage v_securedMessage; var template (value) SituationContainer v_situation := m_situation(c_causeVehicleBreakdown, c_subCauseCode_Unavailable); // Build signed SecuredMessage v_gnNonSecuredPacket := valueof( m_geoNwBroadcastPacket( v_longPosVectorNodeC, vc_localSeqNumber, f_getGeoBroadcastArea( c_area2 ))); // Add the DENM payload v_gnNonSecuredPacket.payload := valueof( f_adaptPayload_m( bit2oct( encvalue( m_denmReq( m_denmPdu( m_denm( m_denmMgmtCon( m_tsActionId ), v_situation, m_denmLocation_zeroDelta ))))))); // Encode it v_gnPayload := bit2oct( encvalue( v_gnNonSecuredPacket ) ); f_buildGnSecuredDenm( v_securedMessage, m_payload_signed(v_gnPayload), p_signerInfoType, valueof(m_threeDLocation( v_longPosVectorNodeC.latitude, v_longPosVectorNodeC.longitude, '0000'O )), p_headerFields, p_configId, p_addMissingHeaders ); // Return secured Gn packet return valueof(m_geoNwSecPdu(v_gnNonSecuredPacket, v_securedMessage)); } // End of function f_prepareSecuredDenm /** * @desc Sends a secured DENM * @param p_configId The configuration identifier to be used * @param p_headerFields Additional HeaderFields * @param p_signerInfoType Add digest or AT certificate or certificate chain * @return GeoNetworking payload */ function f_sendSecuredDenm( in charstring p_configId, in template (omit) HeaderFields p_headerFields := omit, in SignerInfoType p_signerInfoType := e_certificate_digest_with_sha256 ) runs on ItsGeoNetworking return GeoNetworkingPdu { // Local variables var GeoNetworkingPdu v_securedGnPdu := f_prepareSecuredDenm(p_configId, p_headerFields, p_signerInfoType); f_sendGeoNetMessage(m_geoNwReq_linkLayerBroadcast(v_securedGnPdu)); return v_securedGnPdu; } // End of function f_sendSecuredDenm } // End of group secDenm group camTrigger { /** * @desc Triggers a CAM change speed event to get a CAM frequency greather than 1 Hz (i.e. more than one CAM per seconds) * @remark This function spawns an ItsCam component in alive mode * @see fb_changeCamFrequencyGreatherThan1Hz() * @return Reference to the component used to send the trigger */ function f_setCamFrequencyGreatherThan1Hz() runs on ItsBaseComponent return ItsCam { var ItsCam v_camComponent; v_camComponent := ItsCam.create("CAM Trigger"); v_camComponent.start(fb_setCamFrequencyGreatherThan1Hz()); v_camComponent.done; return v_camComponent; } // End of function f_setCamFrequencyGreatherThan1Hz /** * @desc Behaviour function for triggering a CAM change speed event on IUT */ function fb_setCamFrequencyGreatherThan1Hz() runs on ItsCam { // Local variables var SpeedValue v_speedValue := 1667; // in cm/s, e.g. 60Km/h = 1667 cm/s map(self:utPort, system:camUtPort); LibItsCam_Functions.f_utTriggerEvent(valueof(m_changeSpeed(v_speedValue))); unmap(self:utPort, system:camUtPort); } // End of function fb_setCamFrequencyGreatherThan1Hz } // End of group camTrigger group denmTrigger { /** * @desc Triggers a DENM event on IUT * @remark This function spawns an ItsDenm component in alive mode * @see fb_secTriggerDenmEvent() * @return Reference to the component used to send the trigger */ function f_triggerDenmEvent() runs on ItsBaseComponent return ItsDenm { var ItsDenm v_denmComponent; v_denmComponent := ItsDenm.create("DENM Trigger") alive; v_denmComponent.start(fb_secTriggerDenmEvent()); v_denmComponent.done; return v_denmComponent; } // End of function f_triggerDenmEvent /** * @desc Cancels all previously triggered DENM events on IUT * @param p_denmComponent Reference of the component previously used to trigger DENM events * @see fb_secCancelDenmEvent() */ function f_cancelDenmEvent(ItsDenm p_denmComponent) runs on ItsBaseComponent { p_denmComponent.start(fb_secCancelDenmEvent()); p_denmComponent.done; p_denmComponent.kill; } // End of function f_cancelDenmEvent /** * @desc Behaviour function for triggering a DENM event on IUT */ function fb_secTriggerDenmEvent() runs on ItsDenm { // Local variables var template (value) SituationContainer v_situation := m_situation(c_causeVehicleBreakdown, c_subCauseCode_Unavailable); map(self:utPort, system:denmUtPort); vc_default := activate(LibItsDenm_Functions.a_utDefault()); vc_utActionIDs[0] := LibItsDenm_Functions.f_utTriggerEvent(m_utTriggerEvent(v_situation, m_denmLocation_zeroDelta)); log("actionId=", vc_utActionIDs[0]); } // End of function f_secTriggerDenmEvent /** * @desc Behaviour function for cancelling previously triggered DENM events on IUT */ function fb_secCancelDenmEvent() runs on ItsDenm { // Local variables var integer v_counter; for (v_counter := 0; v_counter < lengthof(vc_utActionIDs); v_counter := v_counter + 1) { LibItsDenm_Functions.f_utTerminateEvent(m_utEventCancellation(vc_utActionIDs[v_counter])); } // End of 'for' statement unmap(self:utPort, system:denmUtPort); deactivate(vc_default); } // End of function f_secTriggerDenmEvent } // End of group denmTrigger } // End of module AtsSecurity_Functions