LibItsGeoNetworking_Functions.ttcn 113 KB
Newer Older
garciay's avatar
garciay committed
    /**
     * @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 of group commonFunctions
garciay's avatar
garciay committed
    
  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 (c_compNodeE) {
      v_gnAddr := PX_TS_NODE_E_LOCAL_GN_ADDR;
      }
      case (c_compNodeF) {
      v_gnAddr := PX_TS_NODE_F_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.gnPacket.packet.extendedHeader.shbHeader)
               or ischosen(p_geoNetReq.msgOut.gnPacket.packet.extendedHeader.beaconHeader))) {
        f_setLocalSequenceNumber();
      }
    }
        
    /**
     * @desc    Sends a GeoNetworking message with a payload 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.
     * @param   p_payload   The payload to include.
     */
    function f_sendGeoNetMessageWithPayload(
                                            in template (value) GeoNetworkingReq p_geoNetReq,
                                            in template (value) GnRawPayload p_payload
                                            ) runs on ItsGeoNetworking {
    p_geoNetReq.msgOut.gnPacket.packet.payload := p_payload;
      geoNetworkingPort.send(p_geoNetReq);
      if (not (ischosen(p_geoNetReq.msgOut.gnPacket.packet.extendedHeader.shbHeader)
               or ischosen(p_geoNetReq.msgOut.gnPacket.packet.extendedHeader.beaconHeader))) {
        f_setLocalSequenceNumber();
      }
    }
        
    /**
     * @desc    Receive a GeoNetworking message with a payload and in case of an included sequence number in the message the
     *          local sequence number will be increased by one.
     * @param   p_geoNetInd The message to receive.
     * @param   p_payload   The payload to include.
     */
    function f_receiveGeoNetMessageWithPayload(
                                               in template (present) GeoNetworkingInd p_geoNetInd,
                                               in template (present) GnRawPayload p_payload
                                               ) return template (present) GeoNetworkingInd {
      var template (present) GeoNetworkingInd v_geoNetInd := p_geoNetInd;
            
    v_geoNetInd.msgIn.gnPacket.packet.payload := p_payload;
            
      return v_geoNetInd;
    }
        
    /**
     * @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 of group testerFunctions
garciay's avatar
garciay committed
    
  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  GnAddressConfigurationMethod - IUT's GN local address configuration method
     * @see     PICS_GN_LOCAL_ADDR_CONF_METHOD
     */
    function f_getIutGnLocalAddressConfigurationMethod() return GnAddressConfigurationMethod {
      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_NON_AREA_FORWARDING_ALGORITHM
garciay's avatar
garciay committed
     */
        function f_getNonAreaForwardingAlgorithm() return NonAreaForwardingAlgorithm {
            return PICS_GN_NON_AREA_FORWARDING_ALGORITHM;
garciay's avatar
garciay committed
    }
        
    /**
     * @desc    Gets the GeoBroadcast forwarding algorithm
     * @return  IUT's GeoBroadcast forwarding algorithm
         * @see     PICS_GN_AREA_FORWARDING_ALGORITHM
garciay's avatar
garciay committed
     */
        function f_getAreaForwardingAlgorithm() return AreaForwardingAlgorithm {
            return PICS_GN_AREA_FORWARDING_ALGORITHM;
garciay's avatar
garciay committed
    }
        
    /**
     * @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    Is the ITS-S mobile or stationary?
     * @return  Flags indicating whether the ITS-S is mobile or stationary.
     * @see     PICS_GN_IS_MOBILE
     */
    function f_isMobile() return Bit8 {
      if (PICS_GN_IS_MOBILE) {
        return '10000000'B;
      }
      return '00000000'B;
    }
        
    /**
     * @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 of function f_getLsPacketBufferSize
garciay's avatar
garciay committed
        
    /**
     * @desc    Gets the UC forwarding packet buffer size.
     * @return  UC forwarding packet buffer size in bytes
     * @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 * 1024;
        } // End of function f_getUcForwardingPacketBufferSize
garciay's avatar
garciay committed
        
    /**
     * @desc    Gets the BC forwarding packet buffer size.
     * @return  BC forwarding packet buffer size in bytes
     * @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 * 1024;
        } // End of function f_getBcForwardingPacketBufferSize
garciay's avatar
garciay committed
        
    /**
     * @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_RETRANSMIT_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 of function f_getLifetimeLocTableEntry
garciay's avatar
garciay 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
     */
    function f_getCbfMaxCommunicationRange() return integer {
      var integer v_maxCommunicationRange := PICS_GN_DEFAULT_MAX_COMMUNICATION_RANGE;
            
      return v_maxCommunicationRange;
    } // End of function f_getCbfMaxCommunicationRange
garciay's avatar
garciay committed
        
    function f_getCbfMaxTime() return integer {
        var integer v_cbfMaxTime := PICS_GN_CBF_MAX_TIME;
garciay's avatar
garciay committed
            
        return v_cbfMaxTime;
    } // End of function f_getCbfMaxTime
garciay's avatar
garciay committed
        
    function f_getCbfMinTime() return integer {
        var integer v_cbfMinTime := PICS_GN_CBF_MIN_TIME;
garciay's avatar
garciay committed
            
        return v_cbfMinTime;
        } // End of function f_getCbfMinTime
garciay's avatar
garciay committed
        
    function f_getGnMaxAreaSize() return float {
      var float v_maxAreaSize := PICS_GN_MAX_GEO_AREA_SIZE;
            
      return v_maxAreaSize;
        } // End of function f_getGnMaxAreaSize
garciay's avatar
garciay committed
        
    function f_getAdvancedGbcForwardingMaxCounter() return integer {        
      var integer v_maxCounter := PICS_GN_ADVANCED_BC_FORWARDING_MAX_COUNTER;
            
      return v_maxCounter;  
    }
        
    /**
     * @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 of function f_setNrNeighbourLocTableDefault
garciay's avatar
garciay committed
        
    /**
     * @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 of function f_setNrNeighbourLocTableMedium
garciay's avatar
garciay committed
        
    /**
     * @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 of function f_setNrNeighbourLocTableMaximum
garciay's avatar
garciay committed
                
  } // End of group iutFunctions
garciay's avatar
garciay 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
     */
    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());
    }
    function f_getIutLongPosVector_1(inout LongPosVector p_longPosVectorIut) runs on ItsGeoNetworking {
      p_longPosVectorIut := f_acGetLongPosVector(f_getIutGnLocalAddress());
    }
    
    /**
     * @desc    Get IUT's short position vector
     * @return  IUT's short position vector
     */
    function f_getIutShortPosVector() runs on ItsGeoNetworking return ShortPosVector {
      var LongPosVector v_longPosVectorIut := f_getPosition(c_compIut);
            
      if (not isbound(v_longPosVectorIut)) {
      v_longPosVectorIut := f_getIutLongPosVector();
      }
      return f_longPosVector2ShortPosVector(v_longPosVectorIut);
    }
        
    /**
     * @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 float 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 of group posVectorFunctions
garciay's avatar
garciay committed
    
  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 of group externalFunctions
    
  group security {
        
    /**
     * @desc    Waiting for the GN message with Security
     * @param   p_InSecMsg  SecurityMessage template 
     * @param   p_received  returns received SecurityMessage 
     */
    altstep a_securedMessage (
                              in template (present) EtsiTs103097Data p_InSecMsg,
                              out EtsiTs103097Data p_received
                              ) runs on ItsGeoNetworking {
      var GeoNetworkingInd v_geoNw;
      [] geoNetworkingPort.receive(mw_geoNwInd(
                                               mw_geoNwSecPdu(
                                                              p_InSecMsg,
                                                              mw_geoNwAnyPacket_withPayload(?)
                                                              ))) -> value v_geoNw {
      p_received := f_getSecuredMessage(v_geoNw.msgIn);
      }
    } // End of 'altstep' statement
        
    /**
     * @desc         Receive GN message with security containing certificate as a signer info
     * @param p_cert returns the certificate used for sign received message
     */
    altstep a_securedMessageWithCertificate(
                                            out EtsiTs103097Data p_received
                                            ) runs on ItsGeoNetworking {
            
      [] a_securedMessage (
                            mw_etsiTs103097Data_signed(
                                mw_signedData(
                                    -, 
                                    mw_toBeSignedData(
                                        mw_signedDataPayload
                                    ),
                                    mw_signerIdentifier_certificate // containing certificate
                                )
                            ), 
                            p_received
                           ) {
        // Nothing to do
      }
    } // End of 'altstep' a_securedMessageWithCertificate
garciay's avatar
garciay committed

    /**
     * @desc         Receive GN message with security containing digest as a signer info
     * @param p_cert returns the certificate used for sign received message
     */
    altstep a_securedMessageWithDigest(
                                       out EtsiTs103097Data p_received
                                       ) runs on ItsGeoNetworking {
      [] a_securedMessage (
                            mw_etsiTs103097Data_signed(
                                mw_signedData(
                                    -, 
                                    mw_toBeSignedData(
                                        mw_signedDataPayload
                                    ),
                                    mw_signerIdentifier_digest // containing digest
                                )
                            ), 
                            p_received
                           ) {
        // Nothing to do
      }
    } // End of altstep a_securedMessageWithDigest
        
  } // End of group altSteps
    
  group waitingHelpers {
        
    /**
     * @desc  Wait for GN message with security containing certificate as a signer info
     * @return the certificate used for sign received message
     */
    function f_waitForCertificate(
                                  out EtsiTs103097Certificate p_cert
                                  ) runs on ItsGeoNetworking return boolean {
      var EtsiTs103097Data v_recv;
      var boolean v_ret := false;
            
      alt {
        [] a_securedMessageWithCertificate(v_recv) {
          var SignerIdentifier v_signerIdentifier;
          if (f_getMsgSignerIdentifier(v_recv, v_signerIdentifier) == true) { 
            if (ischosen(v_signerIdentifier.certificate)) {
              p_cert :=  v_signerIdentifier.certificate[0];
              v_ret := true;
            }
          }
        }
      } // End of 'alt' statement
            
      return v_ret;
    } // End of function f_waitForCertificate
        
    /**
     * @desc  Ask for the certificate chain and wait for GN message with security containing certificate chain as a signer info
     * @return the certificate chain used for sign received message
     */
        function f_askForCertificateChain(
                                          in template(value) octetstring p_CamPayload
        ) runs on ItsGeoNetworking return boolean {
garciay's avatar
garciay committed
      var EtsiTs103097Data v_recv;
      var boolean v_ret := false;
        
      alt {
        [] a_securedMessageWithCertificate(v_recv) {
          var SignerIdentifier v_signerIdentifier;
          if (f_getMsgSignerIdentifier(v_recv, v_signerIdentifier) == true) { // Get AT certificate
            if(ischosen(v_signerIdentifier.digest)) {
              f_sendCertificateRequest(v_signerIdentifier.digest, p_CamPayload); // Request issuer
              if(tc_ac.running) {
                tc_ac.stop;
                tc_ac.start;
              }
              v_ret := true;
            }
          }
        }
      }
      return v_ret;
    } // End of function f_askForCertificateChain
      
    /**
     * @desc  Ask for the certificate chain and wait for GN message with security containing certificate chain as a signer info
     * @return the certificate chain used for sign received message
     */
    function f_askAndWaitForCertificateChain(
                                             out SequenceOfCertificate p_chain, 
                                             in template(value) octetstring p_CamPayload
                                             ) runs on ItsGeoNetworking return boolean {
      // Local variables
      var EtsiTs103097Data v_recv;
      var SignerIdentifier v_signerIdentifier;
      var boolean v_ret := false;
      
      f_askForCertificateChain(p_CamPayload); // Get AT certificate and request for the issuer
      alt {
        [] a_securedMessageWithCertificate(v_recv) { // Get AA certificate
          tc_ac.stop;
          
          if (f_getMsgSignerIdentifier(v_recv, v_signerIdentifier) == true) { 
            p_chain := v_signerIdentifier.certificate;
          }
        }
      } // End of 'alt' statement
            
      return v_ret;
    } // End of function f_askAndWaitForCertificateChain
        
    /**
     * @desc Send a CAM message with a certificate and wait the certificate chain request message
     * @remark  This function is used only for testing against another ATS
     * @param p_certificate The certificate identifier
     * @param p_CamPayload  The CAM paylaod
     * @return true on success, flase otherwise
     */
    function f_sendCertificateAndWaitForCertificateChainRequest(
                                                                in charstring p_certificate, 
                                                                in template(value) octetstring p_CamPayload
                                                                ) runs on ItsGeoNetworking return boolean {
      // Local variables
      var EtsiTs103097Data v_recv;
            
      f_sendCertificate(p_certificate, p_CamPayload);
      /* FIXME To be reviewed alt {
        [] a_securedMessage (
                             mw_securedMessage(
                                                superset(
                                                         mw_header_field_unrecognised_certificate
                                                         )),
                             v_recv
                             ) {
          // Nothing to do
          log("*** " & testcasename() & ": DEBUG: Receive certificate ***")
          }
      }*/ // End of 'alt' statement
            
      return true;
    } // End of function f_sendCertificateAndWaitForCertificateChainRequest
        
  } // End of group waitingHelpers
        
  group CertRequests{
        
    function f_sendCertificateRequest(
                                      in template (value) HashedId8 p_digest,
                                      in template (value) octetstring p_payload
                                      ) runs on ItsGeoNetworking {
      var GeoNetworkingReq v_gnReq;
      var GnNonSecuredPacket v_gnNonSecuredPacket;
      var template (value) ToBeSignedData v_toBeSignedData;
      var template (value) EtsiTs103097Data v_securedMessage;
                
      // Build signed EtsiTs103097Data
    v_gnNonSecuredPacket := valueof(m_geoNwShbPacket(
                                                     f_getPosition(c_compNodeC) // FIXME To be verified YANN
                                                     ));
      // Add CAM payload
    v_gnNonSecuredPacket.payload := valueof(p_payload);
            
      /* FIXME To be reviewed f_buildGnSecuredCam(
                          v_securedMessage,
                          m_payload_signed(bit2oct(encvalue(v_gnNonSecuredPacket))),
                          e_certificate,
                          { 
                            m_header_field_unrecognised_certificate(
                                                                    f_HashedId3FromHashedId8(
                                                                                             valueof(p_digest)
                                                                                             )) 
                            },
                          ""
                          );
                
      // Build secured Gn packet
    v_gnReq := valueof(m_geoNwReq_linkLayerBroadcast(
                                                     m_geoNwSecPdu(
                                                                   v_gnNonSecuredPacket,
                                                                   v_securedMessage
garciay's avatar
garciay committed
                                                     )); // End of template m_geoNwReq_linkLayerBroadcast
            
      // Send Message
      f_sendGeoNetMessage(v_gnReq);*/
            
    } // End of function f_sendCertificateRequest
        
    /**
     * @desc Send a CAM message with a certificate
     * @remark  This function is used only for testing against another ATS
     * @param p_certificate The certificate identifier
     * @param p_CamPayload  The CAM paylaod
     * @return true on success, flase otherwise
     * @see     f_sendCertificateAndWaitForCertificateChainRequest
     */
    function f_sendCertificate(
                               in charstring p_certificate,
                               in template (value) octetstring p_payload
                               ) runs on ItsGeoNetworking {
      var GeoNetworkingReq v_gnReq;
      var GnNonSecuredPacket v_gnNonSecuredPacket;
      var template (value) ToBeSignedData v_toBeSignedData;
      var template (value) EtsiTs103097Data v_securedMessage;
                
      // Build signed EtsiTs103097Data
    /* FIXME To be reviewed v_gnNonSecuredPacket := valueof(m_geoNwShbPacket(
                                                     f_getPosition(c_compNodeC) // FIXME To be verified YANN
                                                     ));
      // Add CAM payload
    v_gnNonSecuredPacket.payload := valueof(p_payload);
            
      f_buildGnSecuredCam(
                          v_securedMessage,
                          m_payload_signed(bit2oct(encvalue(v_gnNonSecuredPacket))),
                          e_certificate,
                          -,
                          p_certificate
                          );
                
      // Build secured Gn packet
    v_gnReq := valueof(m_geoNwReq_linkLayerBroadcast(
                                                     m_geoNwSecPdu(
                                                                   v_gnNonSecuredPacket,
                                                                   v_securedMessage
                                                                   ) // End of template m_geoNwSecPdu
                                                     )); // End of template m_geoNwReq_linkLayerBroadcast
            
      // Send Message
      f_sendGeoNetMessage(v_gnReq);*/
            
    } // End of function f_sendCertificate
        
  } // End of group CertRequests 
    
  group messageGetters {
        
    /**
     * @desc    return EtsiTs103097Data field of GeoNetworking packet 
     * @param   p_msg GeoNetworking packet
     * @return  the EtsiTs103097Data if any
     */
        function f_getSecuredMessage(
                                     in GeoNetworkingPdu p_msg
        ) return EtsiTs103097Data {
garciay's avatar
garciay committed
      return p_msg.gnPacket.securedMsg;
    }
        
  }
    
} // End of module LibItsGeoNetworking_Functions