/** * @author ETSI / STF405 * @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 {altstep all}; // LibIts import from LibIts_TestSystem all; import from LibIts_Interface all; import from LibItsCommon_Functions all; import from LibItsGeoNetworking_TypesAndValues all; import from LibItsGeoNetworking_Templates all; import from LibItsGeoNetworking_Pixits all; /** * @desc Create Facility component and connects GeoNetworking port * @remark Only used when ItsFa is a PTC * @param p_ptcDenm returned Facility component variable */ function f_ptcGeoNetworkingUp(out ItsNt p_ptcGeoNetworking) { // Create Facility component p_ptcGeoNetworking := ItsNt.create("GeoNetworking Tester"); // map ports map(p_ptcGeoNetworking:geoNetworkingPort, system:geoNetworkingPort); } // end f_ptcGeoNetworkingUp /** * @desc Wait for component to finish and unmap GeoNetworking ports * @remark Only used when ItsFa is a PTC * @param p_camPtc Facility component variable */ function f_ptcGeoNetworkingDown(in ItsNt p_ptcGeoNetworking) runs on ItsMtc { tc_guard.start; alt { [] p_ptcGeoNetworking.done { tc_guard.stop; } [] tc_guard.timeout { log("*** f_ptcGeoNetworkingDown: ERROR: Timeout while waiting for component ***"); setverdict(inconc); } } unmap(p_ptcGeoNetworking:geoNetworkingPort); } // end f_ptcGeoNetworkingDown 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 ItsNt { // Variables var PositionTable v_positionTable := {}; // Map map(self:geoNetworkingPort, system:geoNetworkingPort); // Position table f_addPosition(v_positionTable, c_compIut, f_getIutLongPosVector()); f_addPosition(v_positionTable, c_compNodeA, f_computePosition()); f_addPosition(v_positionTable, c_compNodeB, f_computePosition()); f_initialiseComponent(v_positionTable, c_compNodeB); } // end f_cf01Up /** * @desc Deletes configuration cf01 */ function f_cf01Down() runs on ItsNt { // Map unmap(self:geoNetworkingPort, system:geoNetworkingPort); } // 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 * @param p_nodeD */ function f_cf02Up(out ItsNt p_nodeB, out ItsNt p_nodeD) runs on ItsMtc { // Variables var PositionTable v_positionTable := {}; // Create p_nodeB := ItsNt.create(c_compNodeB) alive; p_nodeD := ItsNt.create(c_compNodeD) alive; // Map 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); // Position table f_addPosition(v_positionTable, c_compIut, f_getIutLongPosVector()); f_addPosition(v_positionTable, c_compNodeB, f_computePosition()); f_addPosition(v_positionTable, c_compNodeD, f_computePosition()); p_nodeB.start(f_initialiseComponent(v_positionTable, c_compNodeB)); p_nodeD.start(f_initialiseComponent(v_positionTable, c_compNodeD)); p_nodeD.done; p_nodeD.done; } // end f_cf02Up /** * @desc Deletes configuration cf02 * @param p_nodeB * @param p_nodeD */ function f_cf02Down(in ItsNt p_nodeB, in ItsNt p_nodeD) runs on ItsMtc { // Map unmap(p_nodeB:geoNetworkingPort, system:geoNetworkingPort); unmap(p_nodeD:geoNetworkingPort, system:geoNetworkingPort); // Connect disconnect(p_nodeB:syncPort, self:syncPort); disconnect(p_nodeD:syncPort, self: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 */ function f_cf03Up(out ItsNt p_nodeB, out ItsNt p_nodeC) runs on ItsMtc { // Variables var PositionTable v_positionTable := {}; // Create p_nodeB := ItsNt.create(c_compNodeB) alive; p_nodeC := ItsNt.create(c_compNodeC) alive; // Map 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); // Position table f_addPosition(v_positionTable, c_compIut, f_getIutLongPosVector()); f_addPosition(v_positionTable, c_compNodeA, f_computePosition()); f_addPosition(v_positionTable, c_compNodeB, f_computePosition()); f_addPosition(v_positionTable, c_compNodeC, f_computePosition()); p_nodeB.start(f_initialiseComponent(v_positionTable, c_compNodeB)); p_nodeC.start(f_initialiseComponent(v_positionTable, c_compNodeC)); p_nodeB.done; p_nodeC.done; } // end f_cf03Up /** * @desc Deletes configuration cf03 * @param p_nodeA * @param p_nodeB * @param p_nodeC */ function f_cf03Down(in ItsNt p_nodeB, in ItsNt p_nodeC) runs on ItsMtc { // Map unmap(p_nodeB:geoNetworkingPort, system:geoNetworkingPort); unmap(p_nodeC:geoNetworkingPort, system:geoNetworkingPort); // Connect disconnect(p_nodeB:syncPort, self:syncPort); disconnect(p_nodeC:syncPort, self: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 */ function f_cf04Up(out ItsNt p_nodeB, out ItsNt p_nodeC, out ItsNt p_nodeD) runs on ItsMtc { // Variables var PositionTable v_positionTable := {}; // Create p_nodeB := ItsNt.create(c_compNodeB) alive; p_nodeC := ItsNt.create(c_compNodeC) alive; p_nodeD := ItsNt.create(c_compNodeD) alive; // Map 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); // Position table f_addPosition(v_positionTable, c_compIut, f_getIutLongPosVector()); f_addPosition(v_positionTable, c_compNodeA, f_computePosition()); f_addPosition(v_positionTable, c_compNodeB, f_computePosition()); f_addPosition(v_positionTable, c_compNodeC, f_computePosition()); f_addPosition(v_positionTable, c_compNodeD, f_computePosition()); p_nodeB.start(f_initialiseComponent(v_positionTable, c_compNodeB)); p_nodeC.start(f_initialiseComponent(v_positionTable, c_compNodeC)); p_nodeD.start(f_initialiseComponent(v_positionTable, c_compNodeD)); p_nodeB.done; p_nodeC.done; p_nodeD.done; } // end f_cf04Up /** * @desc Deletes configuration cf04 * @param p_nodeB * @param p_nodeC * @param p_nodeD */ function f_cf04Down(in ItsNt p_nodeB, in ItsNt p_nodeC, in ItsNt p_nodeD) runs on ItsMtc { // Map unmap(p_nodeB:geoNetworkingPort, system:geoNetworkingPort); unmap(p_nodeC:geoNetworkingPort, system:geoNetworkingPort); unmap(p_nodeD:geoNetworkingPort, system:geoNetworkingPort); // Connect disconnect(p_nodeB:syncPort, self:syncPort); disconnect(p_nodeC:syncPort, self:syncPort); disconnect(p_nodeD:syncPort, self:syncPort); } // end f_cf04Down function f_initialiseComponent( in PositionTable p_positionTable, in charstring p_componentName) runs on ItsNt { vc_positionTable := p_positionTable; vc_componentName := p_componentName; } // end f_initialiseComponent function f_startBeingNeighbour() runs on ItsNt { activate(a_neighbourDefault()); f_taStartBeaconing( m_beaconHeader( f_getPosition(vc_componentName) ) ); } // end f_startBeingNeighbour function f_stopBeingNeighbour() runs on ItsNt { f_taStopBeaconing(vc_componentName); deactivate; // FIXME: probably too brutal activate(a_default()); } // end f_stopBeingNeighbour } // end geoConfigurationFunctions group geoPositionFunctions { function f_addPosition( in PositionTable v_positionTable, in charstring p_positionKey, in LongPosVector p_positionValue ) { v_positionTable[lengthof(v_positionTable)] := { key := p_positionKey, position := p_positionValue }; } function f_getPosition( in charstring p_positionKey ) runs on ItsNt 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 ItsNt { var LongPosVector v_reqSrcPosVector; [] a_receiveLsRequest(?, ?, ?, v_reqSrcPosVector) {} } /** * @desc Receive Location Service Request and send Location Service Reply */ altstep a_receiveLsRequestAndReply( in template (present) StationTypeIdentifier p_reqStationType, in template (present) UInt16 p_reqSeqNumber, in template (value) GN_Address p_gnAddress, in template (value) LongPosVector p_repSrcPosVector, in template (value) LongPosVector p_repSenderPosVector, in template (value) StationTypeIdentifier p_repStationType ) runs on ItsNt { var LongPosVector v_repDstPosVector; [] a_receiveLsRequest(p_reqStationType, p_reqSeqNumber, p_gnAddress, v_repDstPosVector) { f_sendGeoNetMessage(m_geoNwReq(m_geoNwPdu( m_lsReplyHeader( p_repSrcPosVector, v_repDstPosVector, p_repSenderPosVector, p_repStationType, vc_localSeqNumber )))); } } } // end geoLocationServiceAltsteps } // end geoAltsteps group preambles { /** * @desc The default preamble. */ function f_prDefault() runs on ItsNt { activate(a_default()); } function f_prNonNeighbour() runs on ItsNt { f_prDefault(); } function f_prNeighbour() runs on ItsNt { f_startBeingNeighbour(); } /** * @desc Brings the IUT into an initial state. * @return */ function f_prInitialState() { // TODO: any specific action ? setverdict(pass); } function f_handleLocationService( in template (present) StationTypeIdentifier p_reqStationType, in template (present) UInt16 p_reqSeqNumber, in template (value) GN_Address p_gnAddress, in template (value) LongPosVector p_repSrcPosVector, in template (value) LongPosVector p_repSenderPosVector, in template (value) StationTypeIdentifier p_repStationType ) runs on ItsNt { tc_ac.start; alt { [] a_receiveLsRequestAndReply(p_reqStationType, p_reqSeqNumber, p_gnAddress, p_repSrcPosVector, p_repSenderPosVector, p_repStationType) { tc_ac.stop; } } } function f_processLocationService( in template (value) LongPosVector p_reqSrcPosVector, in template (value) StationTypeIdentifier p_reqStationType, in template (value) UInt16 p_reqSeqNumber, in template (value) GN_Address p_gnAddress, out LongPosVector p_repSrcPosVector ) runs on ItsNt return FncRetCode { var FncRetCode v_ret := e_error; var GeoNetworkingInd v_msg; f_sendGeoNetMessage( m_geoNwReq( m_geoNwPdu( m_lsRequestHeader( p_reqSrcPosVector, p_reqSrcPosVector, p_reqStationType, p_reqSeqNumber, p_gnAddress ) ) ) ); tc_ac.start; alt { [] geoNetworkingPort.receive( mw_geoNwInd( mw_geoNwPdu( mw_lsReplyHeader( ?, p_reqSeqNumber, ?, p_reqSrcPosVector ) ) ) ) -> value v_msg { tc_ac.stop; p_repSrcPosVector := valueof(v_msg.msgIn.header.lsRequestHeader.srcPosVector); v_ret := e_success; } } return v_ret; } } // end preambles group postambles { /** * @desc The default postamble. */ function f_poDefault() runs on ItsNt { setverdict(pass); } function f_poNeighbour() runs on ItsNt { f_stopBeingNeighbour(); f_poDefault(); } } // end postambles group upperTester { function f_utGenerateGeoUnicastMessage(in GN_Address p_destinationGnAddr) runs on ItsNt { //TODO } // p_lifetime in seconds function f_utGenerateGeoUnicastMessageWithLifetime(in GN_Address p_destinationGnAddr, UInt6 p_lifetime) runs on ItsNt { //TODO } function f_utGenerateGeoUnicastMessageWithPayload(in GN_Address p_destinationGnAddr, in octetstring p_payload) runs on ItsNt { //TODO } function f_utGenerateGeoBroadcastMessage(in charstring p_area) runs on ItsNt { //TODO } function f_utGenerateGeoBroadcastMessageWithPayload(in charstring p_area) runs on ItsNt { //TODO } function f_utGenerateGeoAnycastMessage(in charstring p_area) runs on ItsNt { //TODO } function f_utGenerateGeoAnycastMessageWithPayload(in charstring p_area) runs on ItsNt { //TODO } function f_utGenerateSHBMessage() runs on ItsNt { //TODO } function f_utGenerateSHBMessageWithPayload() runs on ItsNt { //TODO } function f_utGenerateTSBMessage() runs on ItsNt { //TODO } function f_utCheckEvent(/*FIXME*/) runs on ItsNt return FncRetCode { var FncRetCode v_ret := e_error; //TODO return v_ret; } } // end upperTester group testAdapter { function f_taStartBeaconing(in template (value) Header p_beaconHeader) { //TODO } function f_taStopBeaconing(in charstring p_compName) { //TODO } function f_taStartPassBeaconing(in template (value) Header p_beaconHeader) { //TODO } function f_taStopPassBeaconing() { //TODO } } // end testAdapter group commonFunctions { /** * @desc Gets the value of the lifetime in seconds. * @return */ function f_getLifetimeValue(in Lifetime p_lifetime) runs on ItsNt 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; } } // end commonFunctions group testerFunctions { /** * @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 sent. */ function f_sendGeoNetMessage(in template (value) GeoNetworkingReq p_geoNetReq) runs on ItsNt { 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. * @return */ function f_setLocalSequenceNumber() runs on ItsNt { vc_localSeqNumber := (vc_localSeqNumber + 1) mod c_uInt16Max; //TODO check if c_uInt16Max should be replaced by module parameter } } // end testerFunctions group iutFunctions { function f_getIutGnLocalAddress() return GN_Address { // TODO return valueof(m_dummyGnAddr); } /** * @desc Gets the LS retransmission timer. * @return */ function f_getLSRetransmitTimer() return float { var float v_itsGnLocationServiceRetransmitTimer := 1.0; //TODO get the value from PIXIT or MIB return v_itsGnLocationServiceRetransmitTimer; } /** * @desc Gets the LS retransmission timer for NetBeaconInterval = medium (cong. ctrl). * @return */ function f_getLSRetransmitTimerMedium() return float { var float v_itsGnLocationServiceRetransmitTimer := 2.0; //TODO get the value from PIXIT or MIB return v_itsGnLocationServiceRetransmitTimer; } /** * @desc Gets the LS retransmission timer for NetBeaconInterval = maximum (cong. ctrl). * @return */ function f_getLSRetransmitTimerMaximum() return float { var float v_itsGnLocationServiceRetransmitTimer := 3.0; //TODO get the value from PIXIT or MIB return v_itsGnLocationServiceRetransmitTimer; } /** * @desc Gets the LS maximum retransmission number. * @return */ function f_getLSMaxRetrans() return integer { var integer v_itsGnLocationServiceMaxRetrans := 10; //TODO get the value from PIXIT or MIB return v_itsGnLocationServiceMaxRetrans; } /** * @desc Gets the Location Service packet buffer size. * @return */ function f_getLSPacketBufferSize() return integer { var integer v_itsGnLocationServicePacketBufferSize := 1024; //TODO get the value from PIXIT or MIB return v_itsGnLocationServicePacketBufferSize; } // end f_getLSPacketBufferSize /** * @desc Gets the UC forwarding packet buffer size. * @return */ function f_getUcForwardingPacketBufferSize() return integer { var integer v_itsGnUcForwardingPacketBufferSize := 1024; //TODO get the value from PIXIT or MIB return v_itsGnUcForwardingPacketBufferSize; } // end f_getUcForwardingPacketBufferSize /** * @desc Gets the BC forwarding packet buffer size. * @return */ function f_getBcForwardingPacketBufferSize() return integer { var integer v_itsGnBcForwardingPacketBufferSize := 1024; //TODO get the value from PIXIT or MIB return v_itsGnBcForwardingPacketBufferSize; } // end f_getBcForwardingPacketBufferSize /** * @desc Gets the upper limit of the maximum lifetime. * @return */ function f_getMaxPacketLifeTime() return float { var float v_itsGnMaxPacketLifetime := 600.0; //TODO get the value from PIXIT or MIB return v_itsGnMaxPacketLifetime; } /** * @desc Gets delta for timers. * @return */ function f_getDeltaTimer() return float { var float v_deltaTimer := 0.1; //TODO get the value from PIXIT return v_deltaTimer; } /** * @desc Gets the beacon service retransmit timer. * @return */ function f_getBSRetransmitTimer() return float { var float v_itsGnBeaconServiceRetransmitTimer := 3.0; //TODO get the value from PIXIT return v_itsGnBeaconServiceRetransmitTimer; } /** * @desc Gets the beacon service retransmit timer for NetBeaconInterval = medium (cong. ctrl). * @return */ function f_getBSRetransmitTimerMedium() return float { var float v_itsGnBeaconServiceRetransmitTimer := 5.0; // timer value increased (medium) //TODO get the value from PIXIT return v_itsGnBeaconServiceRetransmitTimer; } /** * @desc Gets the beacon service retransmit timer for NetBeaconInterval = maximum (cong. ctrl). * @return */ function f_getBSRetransmitTimerMaximum() return float { var float v_itsGnBeaconServiceRetransmitTimer := 8.0; // timer value increased (maximum) //TODO get the value from PIXIT return v_itsGnBeaconServiceRetransmitTimer; } /** * @desc Gets the maximum beacon service jitter. * @return */ function f_getBSMaxJitter() return float { var float v_itsGnBeaconServiceMaxJitter := f_getMaxPacketLifeTime()/4.0; //TODO get the value from PIXIT or from the above calculation return v_itsGnBeaconServiceMaxJitter; } /** * @desc Gets the Lifetime of a Location Table Entry. * @return */ function f_getLifetimeLocTE() return float { var float v_itsGnLifetimeLocTE := 20.0; //TODO get the value from PIXIT or from the above calculation return v_itsGnLifetimeLocTE; } // end f_getLifetimeLocTE /** * @desc Set the number of neighbour in the Location Table. * @return */ function f_setNrNeighbourLocTableDefault() { var integer v_nrNeighbour := f_random (0, PX_MIN_NR_NEIGHBOUR); //TODO set the number of Neighbour in the IUT Location Table to v_nrNeighbour } // end f_setNrNeighbourLT /** * @desc Set the number of neighbour in the Location Table. * @return */ function f_setNrNeighbourLocTableMedium() { var integer v_nrNeighbour := f_random (PX_MIN_NR_NEIGHBOUR, PX_MAX_NR_NEIGHBOUR); //TODO set the number of Neighbour in the IUT Location Table to v_nrNeighbour } // end f_setNrNeighbourLT /** * @desc Set the number of neighbour in the Location Table. * @return */ function f_setNrNeighbourLocTableMaximum() { var integer v_nrNeighbour := f_random (PX_MAX_NR_NEIGHBOUR, (2*PX_MIN_NR_NEIGHBOUR)); //TODO set the number of Neighbour in the IUT Location Table to v_nrNeighbour } // end f_setNrNeighbourLT } // end iutFunctions group posVectorFunctions { function f_longPosVector2ShortPosVector(in LongPosVector p_longPosVector) return ShortPosVector { var ShortPosVector v_shortPosVector; v_shortPosVector := { gnAddr := p_longPosVector.gnAddr, timestamp := p_longPosVector.timestamp, latitute := p_longPosVector.latitute, longitude := p_longPosVector.longitude }; return v_shortPosVector; } function f_getIutLongPosVector() return LongPosVector { var LongPosVector v_longPosVector := valueof(m_dummyLongPosVector); //TODO return v_longPosVector; } function f_getIutShortPosVector() return ShortPosVector { return f_longPosVector2ShortPosVector(f_getIutLongPosVector()); } } // end posVectorFunctions } // end LibItsGeoNetworking_Functions