/** * @author ETSI / STF405 / STF449 * @version $URL$ * $Id$ * @desc Module containing functions for GeoNetworking * */ module LibItsGeoNetworking_Functions { // Libcommon import from LibCommon_BasicTypesAndValues all; import from LibCommon_VerdictControl {type FncRetCode;} import from LibCommon_Sync all; import from LibCommon_Time all; // LibIts import from LibItsCommon_Functions all; import from LibItsCommon_TestSystem all; import from LibItsGeoNetworking_Functions all; import from LibItsGeoNetworking_TestSystem all; import from LibItsGeoNetworking_TypesAndValues all; import from LibItsGeoNetworking_Templates all; import from LibItsGeoNetworking_Pixits all; import from LibItsGeoNetworking_Pics all; import from LibItsExternal_TypesAndValues {type MacAddress}; group utFuntions { /** * @desc Requests to bring the IUT in an initial state * @param p_init The initialisation to trigger. */ function f_utInitializeIut(template (value) UtInitialize p_init) runs on ItsBaseGeoNetworking { utPort.send(p_init); tc_wait.start; alt { [] utPort.receive(UtResult:true) { tc_wait.stop; log("*** f_utInitializeIut: INFO: IUT initialized ***"); } [] utPort.receive { tc_wait.stop; log("*** f_utInitializeIut: INFO: IUT could not be initialized ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] tc_wait.timeout { log("*** f_utInitializeIut: INFO: IUT could not be initialized in time ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); } [else] { // Shortcut defaults repeat; } } } /** * @desc Triggers event from the application layer * @param p_event The event to trigger. */ function f_utTriggerEvent(template (value) UtEvent p_event) runs on ItsGeoNetworking { var template (value) UtTrigger v_utMsg := { p_event }; utPort.send(v_utMsg); alt { [] utPort.receive(UtResult:true) { tc_wait.stop; } [] utPort.receive { tc_wait.stop; } [] tc_wait.timeout { } [else] { // Shortcut defaults repeat; } } } /** * @desc Checks that the event was indicated at the application layer * @param p_event The event to check. * @param p_discard The event should not appear. Default value: FALSE. */ function f_utCheckEvent(template (value) UtEvent p_event, boolean p_discard) runs on ItsGeoNetworking { var template (value) UtCheck v_utMsg := { p_event }; utPort.send(v_utMsg); tc_wait.start; alt { [] utPort.receive(UtResult:true) { tc_wait.stop; if (p_discard == false) { log("*** f_utCheckEvent: INFO: Event correctly indicated at application layer ***"); } else { log("*** f_utCheckEvent: ERROR: Event indicated at application layer where it should be discarded ***"); f_selfOrClientSyncAndVerdict("error", e_error); } } [] utPort.receive(UtResult:false) { tc_wait.stop; if (p_discard == false) { log("*** f_utCheckEvent: ERROR: Event not correctly indicated at application layer ***"); f_selfOrClientSyncAndVerdict("error", e_error); } else { log("*** f_utCheckEvent: INFO: Event not indicated at application layer***"); } } [] tc_wait.timeout { log("*** f_utCheckEvent: ERROR: Timeout while waiting for event check result ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); } [else] { // Shortcut defaults repeat; } } } } // End of group utFunctions 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 ItsGeoNetworking { // Variables var PositionTable v_positionTable := {}; var GeoAreaTable v_areaTable := {}; var LongPosVector v_longPosVectorIut, v_longPosVectorNodeA, v_longPosVectorNodeB, v_longPosVectorNodeD; // Map map(self:acPort, system:acPort); map(self:utPort, system:utPort); map(self:geoNetworkingPort, system:geoNetworkingPort); // Connect f_connect4SelfOrClientSync(); activate(a_cf01Down()); //Initialze the IUT f_initialState(); //Get positions v_longPosVectorIut := f_getIutLongPosVector(); v_longPosVectorNodeA := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeA, c_latitudeFactorNodeA); v_longPosVectorNodeB := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeB, c_latitudeFactorNodeB); v_longPosVectorNodeD := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeD, c_latitudeFactorNodeD); // Propagate GN addresses v_longPosVectorNodeA.gnAddr := f_getTsGnLocalAddress(c_compNodeA); v_longPosVectorNodeB.gnAddr := f_getTsGnLocalAddress(c_compNodeB); // Position table f_addPosition(v_positionTable, c_compIut, v_longPosVectorIut); f_addPosition(v_positionTable, c_compNodeA, v_longPosVectorNodeA); f_addPosition(v_positionTable, c_compNodeB, v_longPosVectorNodeB); f_addPosition(v_positionTable, c_compNodeD, v_longPosVectorNodeD); // Area table f_addArea(v_areaTable, c_area1, f_computeCircularArea(v_longPosVectorNodeD, float2int(1.1 * f_distance(v_longPosVectorNodeB, v_longPosVectorNodeD)))); f_addArea(v_areaTable, c_area2, f_computeCircularArea(v_longPosVectorNodeB, float2int(1.1 * f_distance(v_longPosVectorNodeB, v_longPosVectorNodeD)))); f_initialiseComponent(v_positionTable, v_areaTable, c_compNodeB); } // end f_cf01Up /** * @desc Deletes configuration cf01 */ function f_cf01Down() runs on ItsGeoNetworking { // Unmap unmap(self:acPort, system:acPort); unmap(self:utPort, system:utPort); unmap(self:geoNetworkingPort, system:geoNetworkingPort); // Disconnect f_disconnect4SelfOrClientSync(); } // end f_cf01Down /** * @desc This configuration features: * - one ITS node (IUT) * - one ITS node (NodeB) * - one ITS node (NodeD) * - Area1 which only includes NodeB, NodeD and IUT * - Area2 which only includes NodeB and NodeD * NodeB being close to the area center * * @param p_nodeB Component for NodeB * @param p_nodeD Component for NodeD */ function f_cf02Up(out ItsGeoNetworking p_nodeB, out ItsGeoNetworking p_nodeD) runs on ItsMtc { // Variables var PositionTable v_positionTable := {}; var GeoAreaTable v_areaTable := {}; var LongPosVector v_longPosVectorIut, v_longPosVectorNodeB, v_longPosVectorNodeC, v_longPosVectorNodeD; // Create p_nodeB := ItsGeoNetworking.create(c_compNodeB) alive; p_nodeD := ItsGeoNetworking.create(c_compNodeD) alive; // Map map(self:acPort, system:acPort); map(self:utPort, system:utPort); map(p_nodeB:acPort, system:acPort); map(p_nodeD:acPort, system:acPort); map(p_nodeB:utPort, system:utPort); map(p_nodeD:utPort, system:utPort); map(p_nodeB:geoNetworkingPort, system:geoNetworkingPort); map(p_nodeD:geoNetworkingPort, system:geoNetworkingPort); // Connect connect(p_nodeB:syncPort, self:syncPort); connect(p_nodeD:syncPort, self:syncPort); connect(self:syncPort, mtc:syncPort); activate(a_cf02Down(p_nodeB, p_nodeD)); //Initialze the IUT f_initialState(); //Get positions v_longPosVectorIut := f_getIutLongPosVector(); v_longPosVectorNodeB := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeB, c_latitudeFactorNodeB); v_longPosVectorNodeD := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeD, c_latitudeFactorNodeD); // Propagate GN addresses v_longPosVectorNodeB.gnAddr := f_getTsGnLocalAddress(c_compNodeB); v_longPosVectorNodeD.gnAddr := f_getTsGnLocalAddress(c_compNodeD); // Position table f_addPosition(v_positionTable, c_compIut, v_longPosVectorIut); f_addPosition(v_positionTable, c_compNodeB, v_longPosVectorNodeB); f_addPosition(v_positionTable, c_compNodeD, v_longPosVectorNodeD); // Area table f_addArea(v_areaTable, c_area1, f_computeCircularArea(v_longPosVectorNodeD, float2int(1.1 * f_distance(v_longPosVectorNodeB, v_longPosVectorNodeD)))); f_addArea(v_areaTable, c_area2, f_computeCircularArea(v_longPosVectorNodeB, float2int(1.1 * f_distance(v_longPosVectorNodeB, v_longPosVectorNodeD)))); p_nodeB.start(f_initialiseComponent(v_positionTable, v_areaTable, c_compNodeB)); p_nodeD.start(f_initialiseComponent(v_positionTable, v_areaTable, c_compNodeD)); p_nodeB.done; p_nodeD.done; } // end f_cf02Up /** * @desc Deletes configuration cf02 * @param p_nodeB Component for NodeB * @param p_nodeD Component for NodeD */ function f_cf02Down(in ItsGeoNetworking p_nodeB, in ItsGeoNetworking p_nodeD) runs on ItsMtc { // Unmap unmap(self:acPort, system:acPort); unmap(self:utPort, system:utPort); unmap(p_nodeB:acPort, system:acPort); unmap(p_nodeD:acPort, system:acPort); unmap(p_nodeB:utPort, system:utPort); unmap(p_nodeD:utPort, system:utPort); unmap(p_nodeB:geoNetworkingPort, system:geoNetworkingPort); unmap(p_nodeD:geoNetworkingPort, system:geoNetworkingPort); // Disconnect disconnect(p_nodeB:syncPort, self:syncPort); disconnect(p_nodeD:syncPort, self:syncPort); disconnect(self:syncPort, mtc:syncPort); } // end f_cf02Down /** * @desc This configuration features: * - one ITS node (IUT) * - one ITS node (NodeA) * - one ITS node in direction of NodeA (NodeB) * - one ITS node not in direction of NodeA (NodeC) * - Area1 which only includes NodeB and IUT * - Area2 which only includes NodeB * NodeB being close to the area center * @param p_nodeB Component for NodeB * @param p_nodeC Component for NodeC */ function f_cf03Up(out ItsGeoNetworking p_nodeB, out ItsGeoNetworking p_nodeC) runs on ItsMtc { // Variables var PositionTable v_positionTable := {}; var GeoAreaTable v_areaTable := {}; var LongPosVector v_longPosVectorIut, v_longPosVectorNodeA, v_longPosVectorNodeB, v_longPosVectorNodeC, v_longPosVectorNodeD; // Create p_nodeB := ItsGeoNetworking.create(c_compNodeB) alive; p_nodeC := ItsGeoNetworking.create(c_compNodeC) alive; // Map map(self:acPort, system:acPort); map(self:utPort, system:utPort); map(p_nodeB:acPort, system:acPort); map(p_nodeC:acPort, system:acPort); map(p_nodeB:utPort, system:utPort); map(p_nodeC:utPort, system:utPort); map(p_nodeB:geoNetworkingPort, system:geoNetworkingPort); map(p_nodeC:geoNetworkingPort, system:geoNetworkingPort); // Connect connect(p_nodeB:syncPort, self:syncPort); connect(p_nodeC:syncPort, self:syncPort); connect(self:syncPort, mtc:syncPort); activate(a_cf03Down(p_nodeB, p_nodeC)); //Initialze the IUT f_initialState(); //Get positions v_longPosVectorIut := f_getIutLongPosVector(); v_longPosVectorNodeA := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeA, c_latitudeFactorNodeA); v_longPosVectorNodeB := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeB, c_latitudeFactorNodeB); v_longPosVectorNodeC := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeC, c_latitudeFactorNodeC); v_longPosVectorNodeD := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeD, c_latitudeFactorNodeD); // Propagate GN addresses v_longPosVectorNodeA.gnAddr := f_getTsGnLocalAddress(c_compNodeA); v_longPosVectorNodeB.gnAddr := f_getTsGnLocalAddress(c_compNodeB); v_longPosVectorNodeC.gnAddr := f_getTsGnLocalAddress(c_compNodeC); // Position table f_addPosition(v_positionTable, c_compIut, v_longPosVectorIut); f_addPosition(v_positionTable, c_compNodeA, v_longPosVectorNodeA); f_addPosition(v_positionTable, c_compNodeB, v_longPosVectorNodeB); f_addPosition(v_positionTable, c_compNodeC, v_longPosVectorNodeC); // Area table f_addArea(v_areaTable, c_area1, f_computeCircularArea(v_longPosVectorNodeD, float2int(1.1 * f_distance(v_longPosVectorNodeB, v_longPosVectorNodeD)))); f_addArea(v_areaTable, c_area2, f_computeCircularArea(v_longPosVectorNodeB, float2int(1.1 * f_distance(v_longPosVectorNodeB, v_longPosVectorNodeD)))); p_nodeB.start(f_initialiseComponent(v_positionTable, v_areaTable, c_compNodeB)); p_nodeC.start(f_initialiseComponent(v_positionTable, v_areaTable, c_compNodeC)); p_nodeB.done; p_nodeC.done; } // end f_cf03Up /** * @desc Deletes configuration cf03 * @param p_nodeB Component for NodeB * @param p_nodeC Component for NodeC */ function f_cf03Down(in ItsGeoNetworking p_nodeB, in ItsGeoNetworking p_nodeC) runs on ItsMtc { // Unmap unmap(self:acPort, system:acPort); unmap(self:utPort, system:utPort); unmap(p_nodeB:acPort, system:acPort); unmap(p_nodeC:acPort, system:acPort); unmap(p_nodeB:utPort, system:utPort); unmap(p_nodeC:utPort, system:utPort); unmap(p_nodeB:geoNetworkingPort, system:geoNetworkingPort); unmap(p_nodeC:geoNetworkingPort, system:geoNetworkingPort); // Disconnect disconnect(p_nodeB:syncPort, self:syncPort); disconnect(p_nodeC:syncPort, self:syncPort); disconnect(self:syncPort, mtc:syncPort); } // end f_cf03Down /** * @desc This configuration features: * - one ITS node (IUT) * - one ITS node (NodeA) * - one ITS node in direction of NodeA and having * shortest distance to NodeA (NodeB) * - one ITS node in direction of NodeA (NodeD) * - one ITS node not in direction of NodeA (NodeC) * - Area1 which only includes NodeB, NodeD and IUT * - Area2 which only includes NodeA, NodeB and NodeD * NodeB being close to the area center * @param p_nodeB Component for NodeB * @param p_nodeC Component for NodeC * @param p_nodeD Component for NodeD */ function f_cf04Up(out ItsGeoNetworking p_nodeB, out ItsGeoNetworking p_nodeC, out ItsGeoNetworking p_nodeD) runs on ItsMtc { // Variables var PositionTable v_positionTable := {}; var GeoAreaTable v_areaTable := {}; var LongPosVector v_longPosVectorIut, v_longPosVectorNodeA, v_longPosVectorNodeB, v_longPosVectorNodeC, v_longPosVectorNodeD; // Create p_nodeB := ItsGeoNetworking.create(c_compNodeB) alive; p_nodeC := ItsGeoNetworking.create(c_compNodeC) alive; p_nodeD := ItsGeoNetworking.create(c_compNodeD) alive; // Map map(self:acPort, system:acPort); map(self:utPort, system:utPort); map(p_nodeB:acPort, system:acPort); map(p_nodeC:acPort, system:acPort); map(p_nodeD:acPort, system:acPort); map(p_nodeB:utPort, system:utPort); map(p_nodeC:utPort, system:utPort); map(p_nodeD:utPort, system:utPort); map(p_nodeB:geoNetworkingPort, system:geoNetworkingPort); map(p_nodeC:geoNetworkingPort, system:geoNetworkingPort); map(p_nodeD:geoNetworkingPort, system:geoNetworkingPort); // Connect connect(p_nodeB:syncPort, self:syncPort); connect(p_nodeC:syncPort, self:syncPort); connect(p_nodeD:syncPort, self:syncPort); connect(self:syncPort, mtc:syncPort); activate(a_cf04Down(p_nodeB, p_nodeC, p_nodeD)); //Initialze the IUT f_initialState(); //Get positions v_longPosVectorIut := f_getIutLongPosVector(); v_longPosVectorNodeA := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeA, c_latitudeFactorNodeA); v_longPosVectorNodeB := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeB, c_latitudeFactorNodeB); v_longPosVectorNodeC := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeC, c_latitudeFactorNodeC); v_longPosVectorNodeD := f_computePosition(v_longPosVectorIut, c_longitudeFactorNodeD, c_latitudeFactorNodeD); // Propagate GN addresses v_longPosVectorNodeA.gnAddr := f_getTsGnLocalAddress(c_compNodeA); v_longPosVectorNodeB.gnAddr := f_getTsGnLocalAddress(c_compNodeB); v_longPosVectorNodeC.gnAddr := f_getTsGnLocalAddress(c_compNodeC); v_longPosVectorNodeD.gnAddr := f_getTsGnLocalAddress(c_compNodeD); // Position table f_addPosition(v_positionTable, c_compIut, v_longPosVectorIut); f_addPosition(v_positionTable, c_compNodeA, v_longPosVectorNodeA); f_addPosition(v_positionTable, c_compNodeB, v_longPosVectorNodeB); f_addPosition(v_positionTable, c_compNodeC, v_longPosVectorNodeC); f_addPosition(v_positionTable, c_compNodeD, v_longPosVectorNodeD); // Area table f_addArea(v_areaTable, c_area1, f_computeCircularArea(v_longPosVectorNodeD, float2int(1.1 * f_distance(v_longPosVectorNodeB, v_longPosVectorNodeD)))); f_addArea(v_areaTable, c_area2, f_computeCircularArea(v_longPosVectorNodeB, float2int(1.1 * f_distance(v_longPosVectorNodeB, v_longPosVectorNodeD)))); p_nodeB.start(f_initialiseComponent(v_positionTable, v_areaTable, c_compNodeB)); p_nodeC.start(f_initialiseComponent(v_positionTable, v_areaTable, c_compNodeC)); p_nodeD.start(f_initialiseComponent(v_positionTable, v_areaTable, c_compNodeD)); p_nodeB.done; p_nodeC.done; p_nodeD.done; } // end f_cf04Up /** * @desc Deletes configuration cf04 * @param p_nodeB Component for NodeB * @param p_nodeC Component for NodeC * @param p_nodeD Component for NodeD */ function f_cf04Down(in ItsGeoNetworking p_nodeB, in ItsGeoNetworking p_nodeC, in ItsGeoNetworking p_nodeD) runs on ItsMtc { // Unmap unmap(self:acPort, system:acPort); unmap(self:utPort, system:utPort); unmap(p_nodeB:acPort, system:acPort); unmap(p_nodeC:acPort, system:acPort); unmap(p_nodeD:acPort, system:acPort); unmap(p_nodeB:utPort, system:utPort); unmap(p_nodeC:utPort, system:utPort); unmap(p_nodeD:utPort, system:utPort); unmap(p_nodeB:geoNetworkingPort, system:geoNetworkingPort); unmap(p_nodeC:geoNetworkingPort, system:geoNetworkingPort); unmap(p_nodeD:geoNetworkingPort, system:geoNetworkingPort); // Disonnect disconnect(p_nodeB:syncPort, self:syncPort); disconnect(p_nodeC:syncPort, self:syncPort); disconnect(p_nodeD:syncPort, self:syncPort); disconnect(self:syncPort, mtc:syncPort); } // end f_cf04Down /** * @desc Behavior function for initializing component's variables and tables * @param p_positionTable Table containing position vectors of all nodes * @param p_areaTable Table containing all defined geoAreas * @param p_componentName Name of the component */ function f_initialiseComponent( in PositionTable p_positionTable, in GeoAreaTable p_areaTable, in charstring p_componentName) runs on ItsGeoNetworking { vc_positionTable := p_positionTable; vc_areaTable := p_areaTable; vc_componentName := p_componentName; } // end f_initialiseComponent /** * @desc Makes the simulated ITS node behave as a neighbour of IUT */ function f_startBeingNeighbour() runs on ItsGeoNetworking { vc_neighbourDefault := activate(a_neighbourDefault()); f_acTriggerEvent(m_startBeaconing(m_beaconHeader(f_getPosition(vc_componentName)).beaconHeader)); f_sleepIgnoreDef(PX_NEIGHBOUR_DISCOVERY_DELAY); } // end f_startBeingNeighbour /** * @desc Makes the simulated ITS node behave as not being a neighbour of IUT */ function f_stopBeingNeighbour() runs on ItsGeoNetworking { f_acTriggerEvent(m_stopBeaconing); deactivate(vc_neighbourDefault); } // end f_stopBeingNeighbour } // end geoConfigurationFunctions group geoPositionFunctions { /** * @desc Add a position vector in position table * @param p_positionTable Position table to be updated * @param p_positionKey Reference key of the added position vector * @param p_positionValue Added position vector */ function f_addPosition( inout PositionTable p_positionTable, in charstring p_positionKey, in LongPosVector p_positionValue ) { p_positionTable[lengthof(p_positionTable)] := { key := p_positionKey, position := p_positionValue }; } /** * @desc Get the position vector corresponding to a key * @param p_positionKey Reference key of the searched position vector * @return LongPosVector - The serached position vector */ function f_getPosition( in charstring p_positionKey ) runs on ItsGeoNetworking return LongPosVector { var LongPosVector v_return; var integer i := 0; for (i:=0; i value v_msg { p_reqSrcPosVector := valueof(v_msg.msgIn.header.lsRequestHeader.srcPosVector); } } /** * @desc Receive any Location Service Request */ altstep a_receiveAnyLsRequest() runs on ItsGeoNetworking { var LongPosVector v_reqSrcPosVector; [] a_receiveLsRequest(?, ?, v_reqSrcPosVector) {} } /** * @desc Receive Location Service Request and send Location Service Reply * @param p_reqSeqNumber Expected sequence number of the received LS Request * @param p_gnAddress GN address expected in received LS Request * @param p_repSrcPosVector Source position vector of the sent LS Response * @param p_repSenderPosVector Sender position vector of the sent LS Response */ altstep a_receiveLsRequestAndReply( in template (present) UInt16 p_reqSeqNumber, in template (value) GN_Address.mid p_mid, in template (value) LongPosVector p_repSrcPosVector, in template (value) LongPosVector p_repSenderPosVector ) runs on ItsGeoNetworking { var LongPosVector v_repDstPosVector; [] a_receiveLsRequest(p_reqSeqNumber, p_mid, v_repDstPosVector) { f_sendGeoNetMessage(m_geoNwReq_linkLayerBroadcast(m_geoNwPduNoPayload( m_lsReplyHeader( p_repSrcPosVector, f_longPosVector2ShortPosVector(v_repDstPosVector), p_repSenderPosVector, vc_localSeqNumber )))); } } } // end geoLocationServiceAltsteps } // end geoAltsteps group preambles { /** * @desc The default preamble. */ function f_prDefault() runs on ItsGeoNetworking { activate(a_default()); } /** * @desc Preamble for non-neighbour nodes */ function f_prNonNeighbour() runs on ItsGeoNetworking { f_prDefault(); } /** * @desc Preamble for neighbour nodes */ function f_prNeighbour() runs on ItsGeoNetworking { f_prDefault(); f_startBeingNeighbour(); } /** * @desc Brings the IUT into an initial state. */ function f_initialState() runs on ItsBaseGeoNetworking { f_utInitializeIut(m_gnInitialize); } /** * @desc Receive and reply to LS Requests * @param p_reqSeqNumber Expected sequence number of the received LS Request * @param p_gnAddress GN address expected in received LS Request * @param p_repSrcPosVector Source position vector of the sent LS Response * @param p_repSenderPosVector Sender position vector of the sent LS Response */ function f_handleLocationService( in template (present) UInt16 p_reqSeqNumber, in template (value) GN_Address.mid p_mid, in template (value) LongPosVector p_repSrcPosVector, in template (value) LongPosVector p_repSenderPosVector ) runs on ItsGeoNetworking { tc_ac.start; alt { [] a_receiveLsRequestAndReply(p_reqSeqNumber, p_mid, p_repSrcPosVector, p_repSenderPosVector) { tc_ac.stop; } } } /** * @desc Send LS request and receive LS Reply * @param p_reqSrcPosVector Source position vector of the sent LS Request * @param p_reqSeqNumber Sequence number of the sent LS Request * @param p_gnAddress GN address for which the LS Request is sent * @param p_repSrcPosVector Expected source position vector in received LS Response * @return FncRetCode */ function f_processLocationService( in template (value) LongPosVector p_reqSrcPosVector, in template (value) UInt16 p_reqSeqNumber, in template (value) GN_Address p_gnAddress, out LongPosVector p_repSrcPosVector ) runs on ItsGeoNetworking return FncRetCode { var FncRetCode v_ret := e_error; var GeoNetworkingInd v_msg; f_sendGeoNetMessage( m_geoNwReq_linkLayerBroadcast( m_geoNwPduNoPayload( m_lsRequestHeader( p_reqSrcPosVector, p_reqSrcPosVector, p_reqSeqNumber, p_gnAddress ) ) ) ); tc_ac.start; alt { [] geoNetworkingPort.receive( mw_geoNwInd( mw_geoNwPdu( mw_lsReplyHeader( ?, mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(valueof(p_reqSrcPosVector))) ) ) ) ) -> value v_msg { tc_ac.stop; p_repSrcPosVector := valueof(v_msg.msgIn.header.lsReplyHeader.srcPosVector); v_ret := e_success; } } return v_ret; } } // end preambles group postambles { /** * @desc The default postamble. */ function f_poDefault() runs on ItsGeoNetworking { //empty } /** * @desc Postamble for neighbour nodes */ function f_poNeighbour() runs on ItsGeoNetworking { f_stopBeingNeighbour(); f_poDefault(); } } // end postambles group adapterControl { /** * @desc Triggers event in the test system adaptation. * @param p_event The event to trigger * @return FncRetCode */ function f_acTriggerEvent(template (value) AcGnPrimitive p_event) runs on ItsBaseGeoNetworking return FncRetCode { var FncRetCode v_ret := e_success; acPort.send(p_event); return v_ret; } /** * @desc Get the position vector corresponding to a specific GN address * @param p_gnAddress GN address for which the search is performed * @return LongPosVector - IUT's position */ function f_acGetLongPosVector(GN_Address p_gnAddress) runs on ItsBaseGeoNetworking return LongPosVector { var AcGnResponse v_result; f_acTriggerEvent(m_getLongPosVector(p_gnAddress)); tc_ac.start; alt { [] acPort.receive(mw_getLongPosVectorAny(p_gnAddress)) -> value v_result { tc_ac.stop; } [] acPort.receive { tc_ac.stop; log("*** f_acGetLongPosVector: ERROR: Received unexpected message ***"); f_selfOrClientSyncAndVerdict("error", e_error); } [] tc_ac.timeout { log("*** f_acGetLongPosVector: ERROR: Timeout while waiting for adapter control event result ***"); f_selfOrClientSyncAndVerdict("error", e_timeout); } } return v_result.getLongPosVector; } /** * @desc Triggers test adapter to send beacons for multiple neighbours * @param p_numberOfNeighbour Number of neighbours to simulate * @return FncRetCode */ function f_acStartBeaconingMultipleNeighbour(in integer p_numberOfNeighbour) runs on ItsGeoNetworking return FncRetCode { return f_acTriggerEvent(m_startBeaconingMultipleNeighbour(m_beaconHeader(f_getPosition(vc_componentName)).beaconHeader, p_numberOfNeighbour)); } } // end adapterControl group commonFunctions { /** * @desc Gets the value of the lifetime in seconds. * @param p_lifetime Lifetime to be converted * @return Lifetime in seconds */ function f_getLifetimeValue(in Lifetime p_lifetime) runs on ItsGeoNetworking return float { var float v_lifetime := 0.0; select (p_lifetime.ltBase) { case (e_50ms) { v_lifetime := int2float(p_lifetime.multiplier) * 0.5; } case (e_1s) { v_lifetime := int2float(p_lifetime.multiplier) * 1.0; } case (e_10s) { v_lifetime := int2float(p_lifetime.multiplier) * 10.0; } case (e_100s) { v_lifetime := int2float(p_lifetime.multiplier) * 100.0; } } return v_lifetime; } /** * @desc Computes GN timestamp based on current time * @return Unix-Epoch-Time mod 2^32 */ function f_computeGnTimestamp() return UInt32 { // Timestamp is 1s older than current time to avoid sending beacons coming from the future (time sync between nodes) var UInt32 v_timestamp := fx_computeGnTimestamp() - 1000; return v_timestamp; } } // end commonFunctions group testerFunctions { /** * @desc Gets the tester GN local address for a specific node * @param p_node Simulated node * @return GN address of simulated node */ function f_getTsGnLocalAddress(in charstring p_node) return GN_Address { var GN_Address v_gnAddr := valueof(m_dummyGnAddr); select (p_node) { case (c_compNodeA) { v_gnAddr := PX_TS_NODE_A_LOCAL_GN_ADDR; } case (c_compNodeB) { v_gnAddr := PX_TS_NODE_B_LOCAL_GN_ADDR; } case (c_compNodeC) { v_gnAddr := PX_TS_NODE_C_LOCAL_GN_ADDR; } case (c_compNodeD) { v_gnAddr := PX_TS_NODE_D_LOCAL_GN_ADDR; } case else { log("*** f_getTsGnLocalAddress: INFO: Unknown component " & p_node & " ***"); } } return v_gnAddr; } /** * @desc Sends a GeoNetworking message and in case of an included sequence number in the message the * local sequence number will be increased by one. * @param p_geoNetReq The message to send. */ function f_sendGeoNetMessage(in template (value) GeoNetworkingReq p_geoNetReq) runs on ItsGeoNetworking { geoNetworkingPort.send(p_geoNetReq); if (not (ischosen(p_geoNetReq.msgOut.header.shbHeader) or ischosen(p_geoNetReq.msgOut.header.beaconHeader))) { f_setLocalSequenceNumber(); } } /** * @desc Sets the value of the sequence number for the next event. */ function f_setLocalSequenceNumber() runs on ItsGeoNetworking { vc_localSeqNumber := (vc_localSeqNumber + 1) mod c_uInt16Max; } /** * @desc Creates an initial seqence number * @return Time based initial sequence number (increasing with time) */ function f_getInitialSequenceNumber() return UInt16 { return (f_computeGnTimestamp() / 1000) mod c_uInt16Max; } /** * @desc Number of messages to be sent * @return Number of messages to be sent */ function f_getMessageCount() return integer { return PX_MESSAGE_COUNT; } } // end testerFunctions group iutFunctions { /** * @desc Gets the IUT GN local address * @return IUT's GN_Address * @see PICS_GN_LOCAL_GN_ADDR */ function f_getIutGnLocalAddress() return GN_Address { return PICS_GN_LOCAL_GN_ADDR; } /** * @desc Gets the IUT GN local address configuration method * @return TypeOfAddress - IUT's GN local address configuration method * @see PICS_GN_LOCAL_ADDR_CONF_METHOD */ function f_getIutGnLocalAddressConfigurationMethod() return TypeOfAddress { return PICS_GN_LOCAL_ADDR_CONF_METHOD; } /** * @desc Gets the IUT MAc address * @return MacAddress - IUT's MAc Address * @see PICS_IUT_MAC_ADDRESS */ function f_getIutMacAddress() return MacAddress { return PICS_IUT_MAC_ADDRESS; } /** * @desc Gets the GeoUnicast forwarding algorithm * @return IUT's GeoUnicast forwarding algorithm * @see PICS_GN_GEOUNICAST_FORWARDING_ALGORITHM */ function f_getGeoUnicastForwardingAlgorithm() return GeoUnicastForwardingAlgorithm { return PICS_GN_GEOUNICAST_FORWARDING_ALGORITHM; } /** * @desc Gets the GeoBroadcast forwarding algorithm * @return IUT's GeoBroadcast forwarding algorithm * @see PICS_GN_GEOBROADCAST_FORWARDING_ALGORITHM */ function f_getGeoBroadcastForwardingAlgorithm() return GeoBroadcastForwardingAlgorithm { return PICS_GN_GEOBROADCAST_FORWARDING_ALGORITHM; } /** * @desc Gets the IUT default hop limit * @return IUT's default hop limit * @see PICS_GN_DEFAULT_HOP_LIMIT */ function f_getDefaultHopLimit() return UInt8 { return PICS_GN_DEFAULT_HOP_LIMIT; } /** * @desc Gets the LS retransmission timer.. Valid for NetRepInterval = default (cong. ctrl). * @return LS retransmission timer in seconds * @see PICS_GN_LOCATION_SERVICE_RETRANSMIT_TIMER */ function f_getLsRetransmitTimer() return float { var float v_itsGnLocationServiceRetransmitTimer := int2float(PICS_GN_LOCATION_SERVICE_RETRANSMIT_TIMER/1000); return v_itsGnLocationServiceRetransmitTimer; } /** * @desc Gets the LS retransmission timer for NetRepInterval = medium (cong. ctrl). * @return LS retransmission timer (medium) in seconds * @see PX_GN_LOCATION_SERVICE_TIMER_MEDIUM */ function f_getLsRetransmitTimerMedium() return float { var float v_itsGnLocationServiceRetransmitTimerMedium := int2float(PX_GN_LOCATION_SERVICE_TIMER_MEDIUM/1000); return v_itsGnLocationServiceRetransmitTimerMedium; } /** * @desc Gets the LS retransmission timer for NetRepInterval = maximum (cong. ctrl). * @return LS retransmission timer (maximum) in seconds * @see PX_GN_LOCATION_SERVICE_TIMER_MAXIMUM */ function f_getLsRetransmitTimerMaximum() return float { var float v_itsGnLocationServiceRetransmitTimerMaximum := int2float(PX_GN_LOCATION_SERVICE_TIMER_MAXIMUM/1000); return v_itsGnLocationServiceRetransmitTimerMaximum; } /** * @desc Gets the App retransmission timer. Valid for AppRepInterval = default (cong. ctrl). * @return App retransmission timer in seconds * @see PX_GN_APPLICATION_RETRANSMIT_TIMER */ function f_getAppRetransmitTimer() return float { var float v_itsGnLocationApplicationRetransmitTimer := int2float(PX_GN_APPLICATION_RETRANSMIT_TIMER/1000); return v_itsGnLocationApplicationRetransmitTimer; } /** * @desc Gets the App retransmission timer for AppRepInterval = medium (cong. ctrl). * @return App retransmission timer (medium) in seconds * @see PX_GN_APPLICATION_RETRANSMIT_TIMER_MEDIUM */ function f_getAppRetransmitTimerMedium() return float { var float v_itsGnLocationApplicationRetransmitTimerMedium := int2float(PX_GN_APPLICATION_RETRANSMIT_TIMER_MEDIUM/1000); return v_itsGnLocationApplicationRetransmitTimerMedium; } /** * @desc Gets the App retransmission timer for AppRepInterval = maximum (cong. ctrl). * @return App retransmission timer (maximum) in seconds * @see PX_GN_APPLICATION_RETRANSMIT_TIMER_MAXIMUM */ function f_getAppRetransmitTimerMaximum() return float { var float v_itsGnLocationApplicationRetransmitTimerMaximum := int2float(PX_GN_APPLICATION_RETRANSMIT_TIMER_MAXIMUM/1000); return v_itsGnLocationApplicationRetransmitTimerMaximum; } /** * @desc Gets the LS maximum retransmission number. * @return LS maximum retransmission number * @see PICS_GN_LOCATION_SERVICE_MAX_RETRANS */ function f_getLsMaxRetrans() return integer { var integer v_itsGnLocationServiceMaxRetrans := PICS_GN_LOCATION_SERVICE_MAX_RETRANS; return v_itsGnLocationServiceMaxRetrans; } /** * @desc Gets the Application maximum retransmission number. * @return Application maximum retransmission number * @see PX_GN_APPLICATION_MAX_RETRANS */ function f_getAppMaxRetrans() return integer { var integer v_itsGnApplicationMaxRetrans := PX_GN_APPLICATION_MAX_RETRANS; return v_itsGnApplicationMaxRetrans; } /** * @desc Gets the Location Service packet buffer size. * @return Location Service packet buffer size in Kbytes * @see PICS_GN_LOCATION_SERVICE_PACKET_BUFFER_SIZE */ function f_getLsPacketBufferSize() return integer { var integer v_itsGnLocationServicePacketBufferSize := PICS_GN_LOCATION_SERVICE_PACKET_BUFFER_SIZE; return v_itsGnLocationServicePacketBufferSize; } // end f_getLsPacketBufferSize /** * @desc Gets the UC forwarding packet buffer size. * @return UC forwarding packet buffer size in Kbytes * @see PICS_GN_UC_FORWARDING_PACKET_BUFFER_SIZE */ function f_getUcForwardingPacketBufferSize() return integer { var integer v_itsGnUcForwardingPacketBufferSize := PICS_GN_UC_FORWARDING_PACKET_BUFFER_SIZE; return v_itsGnUcForwardingPacketBufferSize; } // end f_getUcForwardingPacketBufferSize /** * @desc Gets the BC forwarding packet buffer size. * @return BC forwarding packet buffer size in Kbytes * @see PICS_GN_BC_FORWARDING_PACKET_BUFFER_SIZE */ function f_getBcForwardingPacketBufferSize() return integer { var integer v_itsGnBcForwardingPacketBufferSize := PICS_GN_BC_FORWARDING_PACKET_BUFFER_SIZE; return v_itsGnBcForwardingPacketBufferSize; } // end f_getBcForwardingPacketBufferSize /** * @desc Gets the maximum lifetime of a packet. * @return Maximum lifetime of a packet in seconds * @see PICS_GN_MAX_PACKET_LIFETIME */ function f_getMaxPacketLifeTime() return float { var float v_itsGnMaxPacketLifetime := int2float(PICS_GN_MAX_PACKET_LIFETIME); return v_itsGnMaxPacketLifetime; } /** * @desc Gets delta for timers. * @return Delta for timers in seconds * @see PX_T_DELTA */ function f_getDeltaTimer() return float { var float v_deltaTimer := PX_T_DELTA; return v_deltaTimer; } /** * @desc Gets the beacon service retransmit timer. * @return Beacon service retransmit timer */ function f_getBsRetransmitTimer() return float { var float v_itsGnBeaconServiceRetransmitTimer; v_itsGnBeaconServiceRetransmitTimer := int2float( (PICS_GN_BEACON_SERVICE_TIMER/1000)); return v_itsGnBeaconServiceRetransmitTimer; } /** * @desc Gets the beacon service retransmit timer for NetBeaconInterval = medium (cong. ctrl). * @return Beacon service retransmit timer (medium) */ function f_getBsRetransmitTimerMedium() return float { var float v_itsGnBeaconServiceRetransmitTimerMedium; // timer value increased (medium) v_itsGnBeaconServiceRetransmitTimerMedium := int2float( (PX_GN_BEACON_SERVICE_TIMER_MEDIUM+float2int((f_getBsMaxJitter() - 0.0 +1.0)*rnd()) + 0)/1000); return v_itsGnBeaconServiceRetransmitTimerMedium; } /** * @desc Gets the beacon service retransmit timer for NetBeaconInterval = maximum (cong. ctrl). * @return Beacon service retransmit timer (maximum) */ function f_getBsRetransmitTimerMaximum() return float { var float v_itsGnBeaconServiceRetransmitTimerMaximum; // timer value increased (maximum) v_itsGnBeaconServiceRetransmitTimerMaximum := int2float( (PX_GN_BEACON_SERVICE_TIMER_MAXIMUM+float2int((f_getBsMaxJitter() - 0.0 +1.0)*rnd()) + 0)/1000); return v_itsGnBeaconServiceRetransmitTimerMaximum; } /** * @desc Gets the maximum beacon service jitter. * @return Maximum beacon service jitter */ function f_getBsMaxJitter() return float { var float v_itsGnBeaconServiceMaxJitter := int2float(PICS_GN_BEACON_SERVICE_MAX_JITTER)/1000.0; return v_itsGnBeaconServiceMaxJitter; } /** * @desc Gets the Lifetime of a Location Table Entry. * @return Lifetime of a Location Table Entry in seconds * @see PICS_GN_LIFETIME_LOC_TE */ function f_getLifetimeLocTableEntry() return float { var float v_itsGnLifetimeLocTableEntry := int2float(PICS_GN_LIFETIME_LOC_TE); return v_itsGnLifetimeLocTableEntry; } // end f_getLifetimeLocTableEntry /** * @desc Gets the maximum communication range for CBF algorithm * @return Maximum communication range for CBF algorithm in meters * @see PICS_GN_DEFAULT_MAX_COMMUNICATION_RANGE */ function f_getCbfMaxCommunicationRange() return integer { var integer v_maxCommunicationRange := PICS_GN_DEFAULT_MAX_COMMUNICATION_RANGE; return v_maxCommunicationRange; } // end f_getCbfMaxCommunicationRange function f_getGeoUnicastCbfMaxTime() return integer { var integer v_cbfMaxTime := PICS_GN_GEOUNICAST_CBF_MAX_TIME; return v_cbfMaxTime; } // end f_getGeoUnicastCbfMaxTime function f_getGeoUnicastCbfMinTime() return integer { var integer v_cbfMinTime := PICS_GN_GEOUNICAST_CBF_MIN_TIME; return v_cbfMinTime; } // end f_getGeoUnicastCbfMinTime /** * @desc Set the number of neighbour in the Location Table. * @see PX_MIN_NR_NEIGHBOUR */ function f_setNrNeighbourLocTableDefault() runs on ItsGeoNetworking { var integer v_nrNeighbour := f_random (0, PX_MIN_NR_NEIGHBOUR); f_acStartBeaconingMultipleNeighbour(v_nrNeighbour); } // end f_setNrNeighbourLocTableDefault /** * @desc Set the number of neighbour in the Location Table (medium). * @see PX_MIN_NR_NEIGHBOUR * @see PX_MAX_NR_NEIGHBOUR */ function f_setNrNeighbourLocTableMedium() runs on ItsGeoNetworking { var integer v_nrNeighbour := f_random (PX_MIN_NR_NEIGHBOUR, PX_MAX_NR_NEIGHBOUR); f_acStartBeaconingMultipleNeighbour(v_nrNeighbour); } // end f_setNrNeighbourLocTableMedium /** * @desc Set the number of neighbour in the Location Table (maximum). * @see PX_MAX_NR_NEIGHBOUR * @see PX_MIN_NR_NEIGHBOUR */ function f_setNrNeighbourLocTableMaximum() runs on ItsGeoNetworking { var integer v_nrNeighbour := f_random (PX_MAX_NR_NEIGHBOUR, (2*PX_MIN_NR_NEIGHBOUR)); f_acStartBeaconingMultipleNeighbour(v_nrNeighbour); } // end f_setNrNeighbourLocTableMaximum } // end iutFunctions group posVectorFunctions { /** * @desc Convert long position vector to short position vector * @param p_longPosVector Long position vector to be converted * @return Short position vector */ function f_longPosVector2ShortPosVector(in LongPosVector p_longPosVector) return ShortPosVector { var ShortPosVector v_shortPosVector; v_shortPosVector := { gnAddr := p_longPosVector.gnAddr, timestamp := p_longPosVector.timestamp, latitude := p_longPosVector.latitude, longitude := p_longPosVector.longitude }; return v_shortPosVector; } /** * @desc Get IUT's long position vector * @return IUT's long position vector */ function f_getIutLongPosVector() runs on ItsBaseGeoNetworking return LongPosVector { return f_acGetLongPosVector(f_getIutGnLocalAddress()); } /** * @desc Get IUT's short position vector * @return IUT's short position vector */ function f_getIutShortPosVector() runs on ItsBaseGeoNetworking return ShortPosVector { return f_longPosVector2ShortPosVector(f_getIutLongPosVector()); } /** * @desc Compute a position using a reference position, a distance and an orientation * @param p_iutLongPosVector Reference position * @param p_distance Distance to the reference position (in meter) * @param p_orientation direction of the computed position (0 to 359; 0 means North) * @return LongPosVector */ function f_computePositionUsingDistance(in LongPosVector p_iutLongPosVector, in integer p_distance, in integer p_orientation) return LongPosVector { var LongPosVector v_result := p_iutLongPosVector; log("*** f_computePositionUsingDistance: INFO: calling fx_computePositionUsingDistance() ***"); fx_computePositionUsingDistance(p_iutLongPosVector.latitude, p_iutLongPosVector.longitude, p_distance, p_orientation, v_result.latitude, v_result.longitude); return v_result; } } // end posVectorFunctions group externalFunctions { /** * @desc External function to compute timestamp based on current time * @return Unix-Epoch-Time mod 2^32 */ external function fx_computeGnTimestamp() return UInt32; } } // end LibItsGeoNetworking_Functions