Skip to content
LibItsGeoNetworking_Functions.ttcn 69.7 KiB
Newer Older
berge's avatar
berge committed
                }
            }
          
        } // end geoLocationServiceAltsteps
        
        
    } // end geoAltsteps
    
    group preambles {
        
        /**
         * @desc The default preamble.
         */
        function f_prDefault() runs on ItsNt {
            activate(a_default());
        }

        /**
         * @desc Preamble for non-neighbour nodes
         */        
        function f_prNonNeighbour() runs on ItsNt {
            f_prDefault();
        }

        /**
         * @desc Preamble for neighbour nodes
         */        
        function f_prNeighbour() runs on ItsNt {
            f_prDefault();
berge's avatar
berge committed
            f_startBeingNeighbour();        
        /**
         * @desc Brings the IUT into an initial state.
         */
        function f_initialState() {
berge's avatar
berge committed
           
            f_utInitializeIut(m_gnInitialize);
berge's avatar
berge committed
			f_sleep(10.0);
        
        /**
         * @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
                [] a_receiveLsRequestAndReply(p_reqSeqNumber, p_mid, p_repSrcPosVector, p_repSenderPosVector) {
        /**
         * @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,
berge's avatar
berge committed
          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_reqSeqNumber,
                            p_gnAddress
                        )
                    )
                )
            );
            
            tc_ac.start;
            alt {
                [] geoNetworkingPort.receive(
                        mw_geoNwInd(
                            mw_geoNwPdu(
                                mw_lsReplyHeader(
                                    ?,
                                    mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(valueof(p_reqSrcPosVector)))
berge's avatar
berge committed
                    p_repSrcPosVector := valueof(v_msg.msgIn.header.lsReplyHeader.srcPosVector);
    } // end preambles
    
    group postambles {
        
        /**
         * @desc The default postamble.
         */
        function f_poDefault() runs on ItsNt {

        /**
         * @desc Postamble for neighbour nodes
         */          
        function f_poNeighbour() runs on ItsNt {
berge's avatar
berge committed
            f_stopBeingNeighbour();
    group adapterControl {
berge's avatar
berge committed
        /**
         * @desc    Triggers event in the test system adaptation.
         * @param   p_event The event to trigger
         * @return  FncRetCode
berge's avatar
berge committed
        function f_acTriggerEvent(template (value) AcGnPrimitive p_event) runs on ItsAdapterComponent return FncRetCode {
            var FncRetCode v_ret := e_success;
            acPort.send(p_event);
         * @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 ItsAdapterComponent return LongPosVector {
berge's avatar
berge committed
            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;
berge's avatar
berge committed
                    log("*** f_acGetLongPosVector: ERROR: Received unexpected message ***");
                    f_selfOrClientSyncAndVerdict("error", e_error);
berge's avatar
berge committed
                    log("*** f_acGetLongPosVector: ERROR: Timeout while waiting for adapter control event result ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
        /**
         * @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 ItsNt return FncRetCode {
            
            return f_acTriggerEvent(m_startBeaconingMultipleNeighbour(m_beaconHeader(f_getPosition(vc_componentName)).beaconHeader, p_numberOfNeighbour));
            
        }
        
    } // end adapterControl
         * @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 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;
        }
        
        /**
         * @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;	
berge's avatar
berge committed
    group testerFunctions {
berge's avatar
berge committed
        
         * @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 & " ***");
berge's avatar
berge committed
        /**
         * @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.
tepelmann's avatar
tepelmann committed
         */
        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();
            }
berge's avatar
berge committed
        }
         * @desc    Sets the value of the sequence number for the next event.
         */
        function f_setLocalSequenceNumber() runs on ItsNt {
tepelmann's avatar
tepelmann committed
            vc_localSeqNumber := (vc_localSeqNumber + 1) mod c_uInt16Max;
         * @desc    Gets the IUT GN local address
         * @return  IUT's GN_Address
         * @see     PICS_GN_LOCAL_GN_ADDR
berge's avatar
berge committed
        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 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 {
tepelmann's avatar
tepelmann committed
            var float v_itsGnLocationServiceRetransmitTimer := int2float(PICS_GN_LOCATION_SERVICE_RETRANSMIT_TIMER/1000);
            
            return v_itsGnLocationServiceRetransmitTimer;
        }
        
fischer's avatar
fischer committed
        /**
         * @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
fischer's avatar
fischer committed
         */
        function f_getLsRetransmitTimerMedium() return float {
berge's avatar
berge committed
            var float v_itsGnLocationServiceRetransmitTimerMedium := int2float(PX_GN_LOCATION_SERVICE_TIMER_MEDIUM/1000);
fischer's avatar
fischer committed
            
tepelmann's avatar
tepelmann committed
            return v_itsGnLocationServiceRetransmitTimerMedium;
fischer's avatar
fischer committed
        }
        
        /**
         * @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
fischer's avatar
fischer committed
         */
        function f_getLsRetransmitTimerMaximum() return float {
berge's avatar
berge committed
            var float v_itsGnLocationServiceRetransmitTimerMaximum := int2float(PX_GN_LOCATION_SERVICE_TIMER_MAXIMUM/1000);
fischer's avatar
fischer committed
            
tepelmann's avatar
tepelmann committed
            return v_itsGnLocationServiceRetransmitTimerMaximum;
fischer's avatar
fischer committed
        }
fischer's avatar
fischer committed

        /**
         * @desc    Gets the App retransmission timer. Valid for AppRepInterval = default (cong. ctrl).
         * @return  App retransmission timer in seconds
         * @see     PX_GN_APPLICATION_RETRANSMIT_TIMER
fischer's avatar
fischer committed
         */
        function f_getAppRetransmitTimer() return float {
tepelmann's avatar
tepelmann committed
            var float v_itsGnLocationApplicationRetransmitTimer := int2float(PX_GN_APPLICATION_RETRANSMIT_TIMER/1000);
fischer's avatar
fischer committed
            
tepelmann's avatar
tepelmann committed
            return v_itsGnLocationApplicationRetransmitTimer;
fischer's avatar
fischer committed
        }
        
        /**
         * @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
fischer's avatar
fischer committed
         */
        function f_getAppRetransmitTimerMedium() return float {
            var float v_itsGnLocationApplicationRetransmitTimerMedium := int2float(PX_GN_APPLICATION_RETRANSMIT_TIMER_MEDIUM/1000);
fischer's avatar
fischer committed
            
            return v_itsGnLocationApplicationRetransmitTimerMedium;
fischer's avatar
fischer committed
        }
        
        /**
         * @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
fischer's avatar
fischer committed
         */
        function f_getAppRetransmitTimerMaximum() return float {
            var float v_itsGnLocationApplicationRetransmitTimerMaximum := int2float(PX_GN_APPLICATION_RETRANSMIT_TIMER_MAXIMUM/1000);
fischer's avatar
fischer committed
            
            return v_itsGnLocationApplicationRetransmitTimerMaximum;
fischer's avatar
fischer committed
        }
fischer's avatar
fischer committed
        
         * @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;
        }
fischer's avatar
fischer committed

        /**
         * @desc    Gets the Application maximum retransmission number.
         * @return  Application maximum retransmission number
         * @see     PX_GN_APPLICATION_MAX_RETRANS
fischer's avatar
fischer committed
         */
        function f_getAppMaxRetrans() return integer {
            var integer v_itsGnApplicationMaxRetrans := PX_GN_APPLICATION_MAX_RETRANS;
fischer's avatar
fischer committed
            
            return v_itsGnApplicationMaxRetrans;
fischer's avatar
fischer committed
        }
         * @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;
tepelmann's avatar
tepelmann committed
            
            return v_itsGnLocationServicePacketBufferSize;
        } // end f_getLsPacketBufferSize
berge's avatar
berge committed
        /**
         * @desc    Gets the UC forwarding packet buffer size.
         * @return  UC forwarding packet buffer size in Kbytes
         * @see     PICS_GN_UC_FORWARDING_PACKET_BUFFER_SIZE
berge's avatar
berge committed
         */        
        function f_getUcForwardingPacketBufferSize() return integer {
            var integer v_itsGnUcForwardingPacketBufferSize := PICS_GN_UC_FORWARDING_PACKET_BUFFER_SIZE;
berge's avatar
berge committed
            
            return v_itsGnUcForwardingPacketBufferSize;
        } // end f_getUcForwardingPacketBufferSize
        
berge's avatar
berge committed
        /**
         * @desc    Gets the BC forwarding packet buffer size.
         * @return  BC forwarding packet buffer size in Kbytes
         * @see     PICS_GN_BC_FORWARDING_PACKET_BUFFER_SIZE
berge's avatar
berge committed
         */        
        function f_getBcForwardingPacketBufferSize() return integer {
            var integer v_itsGnBcForwardingPacketBufferSize := PICS_GN_BC_FORWARDING_PACKET_BUFFER_SIZE;
berge's avatar
berge committed
            
            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);
         * @desc    Gets delta for timers.
         * @return  Delta for timers in seconds
         * @see     PX_T_DELTA
         */
        function f_getDeltaTimer() return float {
tepelmann's avatar
tepelmann committed
            var float v_deltaTimer := PX_T_DELTA;
        /**
         * @desc Gets the beacon service retransmit timer.
         * @return  Beacon service retransmit timer 
        function f_getBsRetransmitTimer() return float {
            var float v_itsGnBeaconServiceRetransmitTimer;
            v_itsGnBeaconServiceRetransmitTimer := int2float(
         * @desc    Gets the beacon service retransmit timer for NetBeaconInterval = medium (cong. ctrl).
         * @return  Beacon service retransmit timer (medium)
        function f_getBsRetransmitTimerMedium() return float {
tepelmann's avatar
tepelmann committed
            var float v_itsGnBeaconServiceRetransmitTimerMedium; // timer value increased (medium)
tepelmann's avatar
tepelmann committed
            v_itsGnBeaconServiceRetransmitTimerMedium := int2float(
                (PX_GN_BEACON_SERVICE_TIMER_MEDIUM+float2int((f_getBsMaxJitter() - 0.0 +1.0)*rnd()) + 0)/1000);
tepelmann's avatar
tepelmann committed
            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 {
tepelmann's avatar
tepelmann committed
            var float v_itsGnBeaconServiceRetransmitTimerMaximum; // timer value increased (maximum)
tepelmann's avatar
tepelmann committed
            v_itsGnBeaconServiceRetransmitTimerMaximum := int2float(
                (PX_GN_BEACON_SERVICE_TIMER_MAXIMUM+float2int((f_getBsMaxJitter() - 0.0 +1.0)*rnd()) + 0)/1000);
tepelmann's avatar
tepelmann committed
            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;
         * @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
berge's avatar
berge committed
        /**
         * @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
berge's avatar
berge committed
         */
        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 ItsNt {
fischer's avatar
fischer committed
            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 ItsNt {
            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 ItsNt {
            var integer v_nrNeighbour := f_random (PX_MAX_NR_NEIGHBOUR, (2*PX_MIN_NR_NEIGHBOUR));
            
            f_acStartBeaconingMultipleNeighbour(v_nrNeighbour);
            
        } // end f_setNrNeighbourLocTableMaximum
berge's avatar
berge committed
    group posVectorFunctions {
        
        /**
         * @desc    Convert long position vector to short position vector 
         * @param   p_longPosVector Long position vector to be converted
         * @return  Short position vector
         */
berge's avatar
berge committed
        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
            };
            
berge's avatar
berge committed
            return v_shortPosVector; 
        }
        
        /**
         * @desc    Get IUT's long position vector
         * @return  IUT's long position vector
         */
        function f_getIutLongPosVector() runs on ItsAdapterComponent 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 ItsAdapterComponent return ShortPosVector {
            return f_longPosVector2ShortPosVector(f_getIutLongPosVector()); 
berge's avatar
berge committed
        /**
         * @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);
berge's avatar
berge committed
            return v_result;
        }
        
berge's avatar
berge committed
    } // end posVectorFunctions
    
    group externalFunctions {

        /**
         * @desc    External function to compute distance between two points
         * @param   p_latitudeA   Latitude of first point
         * @param   p_longitudeA  Longitude of first point
         * @param   p_latitudeB   Latitude of second point
         * @param   p_longitudeB  Longitude of second point
         * @return  Computed distance in meters
         */
        external function fx_computeDistance(
            in UInt32 p_latitudeA, in UInt32 p_longitudeA, 
            in UInt32 p_latitudeB, in UInt32 p_longitudeB
        ) return float;
berge's avatar
berge committed
        
        /**
         * @desc    External function to 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)
         * @param   p_latitude          Computed position's latitude
         * @param   p_longitude         Computed position's longitude
berge's avatar
berge committed
         * @return  LongPosVector
         */        
        external function fx_computePositionUsingDistance(
            in UInt32 p_refLatitude, 
            in UInt32 p_refLongitude, 
berge's avatar
berge committed
            in integer p_distance, 
            in integer p_orientation,
            out UInt32 p_latitude,
            out UInt32 p_longitude
        );
        
        /**
         * @desc    External function to compute timestamp based on current time
         * @return  Unix-Epoch-Time mod 2^32
         */
        external function fx_computeGnTimestamp() return UInt32;       
berge's avatar
berge committed
} // end LibItsGeoNetworking_Functions