ItsRSUsSimulator_Functions.ttcn 84.9 KB
Newer Older
YannGarcia's avatar
YannGarcia committed
                                in integer p_dest_port,
garciay's avatar
garciay committed
                                in integer p_src_port
    ) return template (present) octetstring {
YannGarcia's avatar
YannGarcia committed
      //log(">>> f_payload_template: ", p_dest_port, " - ", p_src_port);
      var template (value) Oct2 v_t1 := int2oct(p_dest_port, 2);
      var template (value) Oct2 v_t2 := int2oct(p_src_port, 2);
      var template (present) octetstring v_t3 := ? /*? length (5 .. 65535)*/;
      var template (present) octetstring v_out := valueof(v_t1) & valueof(v_t2) & v_t3;
      //log("<<< f_payload_template: v_out=", v_out);
      return v_out
garciay's avatar
garciay committed
    }
    altstep a_process_cf_ut_command() runs on ItsRSUsSimulator {
garciay's avatar
garciay committed
      var UtGnInitialize v_utGnInitialize;
YannGarcia's avatar
YannGarcia committed
      var UtCamInitialize v_utCamInitialize;
      var UtDenmInitialize v_utDenmInitialize;
      var UtPkiInitialize v_utPkiInitialize;
garciay's avatar
garciay committed
      var UtGnTrigger v_utGnTrigger;
garciay's avatar
garciay committed
      var UtCamTrigger v_utCamTrigger;
YannGarcia's avatar
YannGarcia committed
      var UtDenmTrigger v_utDenmTrigger;
      var UtDenmUpdate v_utDenmUpdate;
      var UtDenmTermination v_utDenmTermination;
      var UtPkiTrigger v_utPkiTrigger;
garciay's avatar
garciay committed
        [] cfPort.receive(UtGnInitialize:?) -> value v_utGnInitialize {
YannGarcia's avatar
YannGarcia committed
          var GeoNetworkingPdu v_geoNwPdu;

YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utGnInitialize = ", v_utGnInitialize);
YannGarcia's avatar
YannGarcia committed
          v_geoNwPdu :=valueof(
                               m_geoNwPdu(
                                          m_geoNwBeaconPacket(
                                                              vc_longPosVectorRsu
                                                              ),
                                          m_defaultLifetime,
                                          1
                                          )
                               );
          v_geoNwPdu.gnPacket.packet.commonHeader.flags := f_isMobile();
          vc_rsuMessagesValueList[vc_rsu_id].beacon := v_geoNwPdu;
garciay's avatar
garciay committed
          cfPort.send(UtGnResults: { utGnInitializeResult := true } );
          repeat;
        }
garciay's avatar
garciay committed
        [] cfPort.receive(UtGnTrigger:?) -> value v_utGnTrigger {
YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utGnTrigger = ", v_utGnTrigger);
garciay's avatar
garciay committed
          if (ischosen(v_utGnTrigger.geoUnicast)) {
            var GnNonSecuredPacket v_geoNwUnicastPacket := valueof(
                                                                   m_geoNwUnicastPacket_with_payload(
                                                                                                     vc_longPosVectorRsu,
                                                                                                     f_getIutShortPosVector(),
                                                                                                     f_incLocalSeqNumber(),
                                                                                                     c_defaultHopLimit,
                                                                                                     v_utGnTrigger.geoUnicast.trafficClass,
                                                                                                     v_utGnTrigger.geoUnicast.payload
YannGarcia's avatar
YannGarcia committed
                                                                                                     ));
garciay's avatar
garciay committed
            var GeoNetworkingPdu v_geoNwPdu := valueof(
                                                       m_geoNwPdu(
                                                                  v_geoNwUnicastPacket,
YannGarcia's avatar
YannGarcia committed
                                                                  m_lifetimeBase1s(v_utGnTrigger.geoUnicast.lifetime / 1000),
garciay's avatar
garciay committed
                                                                  c_defaultHopLimit
garciay's avatar
garciay committed
            v_geoNwPdu.gnPacket.packet.commonHeader.nextHeader := e_any;
YannGarcia's avatar
YannGarcia committed
            v_geoNwPdu.gnPacket.packet.commonHeader.flags := f_isMobile();
garciay's avatar
garciay committed
            v_geoNwPdu.gnPacket.packet.extendedHeader.geoUnicastHeader.dstPosVector.gnAddr := v_utGnTrigger.geoUnicast.gnAddress;
YannGarcia's avatar
YannGarcia committed
            vc_rsuMessagesValueList[vc_rsu_id].beacon := v_geoNwPdu;
            cfPort.send(UtGnResults: { utGnTriggerResult := true } );
garciay's avatar
garciay committed
          } else if (ischosen(v_utGnTrigger.geoBroadcast)) {
            var GeoBroadcastArea v_broadcastArea;
            var GnNonSecuredPacket v_geoNwBroadcastPacket;
            var GeoNetworkingPdu v_geoNwPdu;

            if (v_utGnTrigger.geoBroadcast.shape == e_geoCircle) {
              v_broadcastArea.geoBroadcastSubType := e_geoBroadcastCircle;
            } else if (v_utGnTrigger.geoBroadcast.shape == e_geoRect) {
              v_broadcastArea.geoBroadcastSubType := e_geoBroadcastRect;
            } else if (v_utGnTrigger.geoBroadcast.shape == e_geoElip) {
              v_broadcastArea.geoBroadcastSubType := e_geoBroadcastElip;
            } else {
              v_broadcastArea.geoBroadcastSubType := e_reserved;
            }
            v_broadcastArea.geoBroadcastArea := v_utGnTrigger.geoBroadcast.area;
            v_geoNwBroadcastPacket := valueof(
                                              m_geoNwBroadcastPacket_payload(
                                                                             vc_longPosVectorRsu,
                                                                             f_incLocalSeqNumber(),
                                                                             v_broadcastArea,
                                                                             c_defaultHopLimit,
                                                                             v_utGnTrigger.geoBroadcast.trafficClass,
                                                                             v_utGnTrigger.geoBroadcast.payload
                                                                             ));
YannGarcia's avatar
YannGarcia committed
            v_geoNwBroadcastPacket.commonHeader.flags := f_isMobile();
garciay's avatar
garciay committed
            v_geoNwPdu := valueof(
                                  m_geoNwPdu(
                                             v_geoNwBroadcastPacket,
YannGarcia's avatar
YannGarcia committed
                                             m_lifetimeBase1s(v_utGnTrigger.geoBroadcast.lifetime / 1000),
                                             c_defaultHopLimit
                                             ));
            v_geoNwPdu.gnPacket.packet.commonHeader.nextHeader := e_any;
            v_geoNwPdu.gnPacket.packet.commonHeader.flags := f_isMobile();
            vc_rsuMessagesValueList[vc_rsu_id].beacon := v_geoNwPdu;
            cfPort.send(UtGnResults: { utGnTriggerResult := true } );
          } else if (ischosen(v_utGnTrigger.geoAnycast)) {
            var GeoAnycastArea v_anycastArea;
            var GnNonSecuredPacket v_geoNwAnycastPacket;
            var GeoNetworkingPdu v_geoNwPdu;

            if (v_utGnTrigger.geoAnycast.shape == e_geoCircle) {
              v_anycastArea.geoAnycastSubType := e_geoAnycastCircle;
            } else if (v_utGnTrigger.geoAnycast.shape == e_geoRect) {
              v_anycastArea.geoAnycastSubType := e_geoAnycastRect;
            } else if (v_utGnTrigger.geoAnycast.shape == e_geoElip) {
              v_anycastArea.geoAnycastSubType := e_geoAnycastElip;
            } else {
              v_anycastArea.geoAnycastSubType := e_reserved;
            }
            v_anycastArea.geoAnycastArea := v_utGnTrigger.geoAnycast.area;
            v_geoNwAnycastPacket := valueof(
                                            m_geoNwAnycastPacket_payload(
                                                                         vc_longPosVectorRsu,
                                                                         f_incLocalSeqNumber(),
                                                                         v_anycastArea,
                                                                         c_defaultHopLimit,
                                                                         v_utGnTrigger.geoAnycast.trafficClass,
                                                                         v_utGnTrigger.geoAnycast.payload
                                                                         ));
            v_geoNwPdu := valueof(
                                  m_geoNwPdu(
                                             v_geoNwAnycastPacket,
                                             m_lifetimeBase1s(v_utGnTrigger.geoAnycast.lifetime / 1000),
garciay's avatar
garciay committed
                                             c_defaultHopLimit
                                             ));
YannGarcia's avatar
YannGarcia committed
            v_geoNwPdu.gnPacket.packet.commonHeader.flags := f_isMobile();
            v_geoNwPdu.gnPacket.packet.commonHeader.nextHeader := e_any;
            vc_rsuMessagesValueList[vc_rsu_id].beacon := v_geoNwPdu;
            cfPort.send(UtGnResults: { utGnTriggerResult := true } );
          } else if (ischosen(v_utGnTrigger.shb)) {
            var GnNonSecuredPacket v_geoShbPacket;
            var GeoNetworkingPdu v_geoNwPdu;

            v_geoShbPacket :=  valueof(
                                       m_geoNwShbPacket_payload(
                                                                vc_longPosVectorRsu,
                                                                v_utGnTrigger.shb.payload
                                                                ));
            v_geoShbPacket.commonHeader.maxHopLimit := 1;
            v_geoShbPacket.commonHeader.trafficClass.scf := v_utGnTrigger.shb.trafficClass.scf;
            v_geoShbPacket.commonHeader.trafficClass.channelOffload := v_utGnTrigger.shb.trafficClass.channelOffload;
            v_geoShbPacket.commonHeader.trafficClass.tcId := v_utGnTrigger.shb.trafficClass.tcId;
            v_geoNwPdu := valueof(
                                  m_geoNwPdu(
                                             v_geoShbPacket,
                                             m_defaultLifetime,
                                             1
                                             ));
            v_geoNwPdu.gnPacket.packet.commonHeader.flags := f_isMobile();
            v_geoNwPdu.gnPacket.packet.commonHeader.nextHeader := e_any;
            vc_rsuMessagesValueList[vc_rsu_id].beacon := v_geoNwPdu;
            cfPort.send(UtGnResults: { utGnTriggerResult := true } );
          } else if (ischosen(v_utGnTrigger.tsb)) {
            var GnNonSecuredPacket v_geoTsbPacket;
            var GeoNetworkingPdu v_geoNwPdu;

            v_geoTsbPacket :=  valueof(
                                       m_geoNwTsbPacket_payload(
                                                                f_incLocalSeqNumber(),
                                                                vc_longPosVectorRsu,
                                                                -,
                                                                -,
                                                                v_utGnTrigger.tsb.payload
                                                                ));
            v_geoTsbPacket.commonHeader.trafficClass.scf := v_utGnTrigger.tsb.trafficClass.scf;
            v_geoTsbPacket.commonHeader.trafficClass.channelOffload := v_utGnTrigger.tsb.trafficClass.channelOffload;
            v_geoTsbPacket.commonHeader.trafficClass.tcId := v_utGnTrigger.tsb.trafficClass.tcId;
            v_geoNwPdu := valueof(
                                  m_geoNwPdu(
                                             v_geoTsbPacket,
                                             m_defaultLifetime,
                                             c_defaultHopLimit
                                             ));
            v_geoNwPdu.gnPacket.packet.commonHeader.nextHeader := e_any;
            v_geoNwPdu.gnPacket.packet.commonHeader.flags := f_isMobile();
            vc_rsuMessagesValueList[vc_rsu_id].beacon := v_geoNwPdu;
            cfPort.send(UtGnResults: { utGnTriggerResult := true } );
          } else {
            cfPort.send(UtGnResults: { utGnTriggerResult := false } );
garciay's avatar
garciay committed
          }
          repeat;
        }
YannGarcia's avatar
YannGarcia committed
        [vc_cam == true] cfPort.receive(UtCamInitialize:?) -> value v_utCamInitialize {
YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utCamInitialize = ", v_utCamInitialize);
          if (oct2int(v_utCamInitialize.hashedId8) != 0) {
            var charstring v_certificate_id;
            var EtsiTs103097Certificate v_certificate;
            log("a_process_cf_ut_command: Looking for certificate ", v_utCamInitialize.hashedId8);
            f_getCertificateFromDigest(v_utCamInitialize.hashedId8, v_certificate, v_certificate_id);
            log("a_process_cf_ut_command (pki): Change certificate to ", v_certificate_id);
            f_acTriggerSecEvent(m_acEnableSecurity(v_certificate_id));
          }
YannGarcia's avatar
YannGarcia committed
          vc_cam_timer_value := 1.0; // Reset CAM timer
          vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.highFrequencyContainer.basicVehicleContainerHighFrequency.curvature.curvatureValue := 0
          vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.highFrequencyContainer.basicVehicleContainerHighFrequency.heading.headingValue := 0;
          vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.lowFrequencyContainer.basicVehicleContainerLowFrequency.vehicleRole := default_;
          vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.specialVehicleContainer := omit;
          cfPort.send(UtCamResults: { utCamInitializeResult := true } );
          repeat;
YannGarcia's avatar
YannGarcia committed
        [vc_cam == true] cfPort.receive(UtCamTrigger: { changeSpeed := ? }) -> value v_utCamTrigger {
YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utCamTrigger = ", v_utCamTrigger);
          cfPort.send(UtCamResults: { utCamTriggerResult := true } );
garciay's avatar
garciay committed
          vc_cam_timer_value := vc_cam_timer_value / 2.0;
          repeat;
        }
        [vc_cam == true] cfPort.receive(UtCamTrigger: { changeCurvature := ? }) -> value v_utCamTrigger {
YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utCamTrigger = ", v_utCamTrigger);
YannGarcia's avatar
YannGarcia committed
          if (ischosen(vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.highFrequencyContainer.basicVehicleContainerHighFrequency)) {
garciay's avatar
garciay committed
            cfPort.send(UtCamResults: { utCamTriggerResult := true } );
            vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.highFrequencyContainer.basicVehicleContainerHighFrequency.curvature.curvatureValue := v_utCamTrigger.changeCurvature;
          } else {
            cfPort.send(UtCamResults: { utCamTriggerResult := false } );
          }
garciay's avatar
garciay committed
        [vc_cam == true] cfPort.receive(UtCamTrigger: { changeHeading := ? }) -> value v_utCamTrigger {
YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utCamTrigger = ", v_utCamTrigger);
YannGarcia's avatar
YannGarcia committed
          if (ischosen(vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.highFrequencyContainer.basicVehicleContainerHighFrequency)) {
garciay's avatar
garciay committed
            cfPort.send(UtCamResults: { utCamTriggerResult := true } );
garciay's avatar
garciay committed
            vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.highFrequencyContainer.basicVehicleContainerHighFrequency.heading.headingValue := valueof(vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.highFrequencyContainer.basicVehicleContainerHighFrequency.heading.headingValue) + v_utCamTrigger.changeHeading;
garciay's avatar
garciay committed
          } else {
            cfPort.send(UtCamResults: { utCamTriggerResult := false } );
          }
          repeat;
        }
YannGarcia's avatar
YannGarcia committed
        [vc_cam == true] cfPort.receive(UtCamTrigger: { setVehicleRole := ? }) -> value v_utCamTrigger {
YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utCamTrigger = ", v_utCamTrigger);
YannGarcia's avatar
YannGarcia committed
          vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.lowFrequencyContainer.basicVehicleContainerLowFrequency.vehicleRole := v_utCamTrigger.setVehicleRole;
          vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.specialVehicleContainer := { publicTransportContainer := { embarkationStatus := true, ptActivation := omit } };
garciay's avatar
garciay committed
          cfPort.send(UtCamResults: { utCamTriggerResult := true } );
          repeat;
YannGarcia's avatar
YannGarcia committed
        }
        [] cfPort.receive(UtDenmInitialize:?) -> value v_utDenmInitialize {
YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utDenmInitialize = ", v_utDenmInitialize);
YannGarcia's avatar
YannGarcia committed
          vc_rsuMessagesValueList[vc_rsu_id].denms := {};
          vc_denmEventCounter := 0;
          vc_denm := true;
          cfPort.send(UtDenmResults: { utDenmInitializeResult := true } );
          repeat;
YannGarcia's avatar
YannGarcia committed
        [vc_denm == true] cfPort.receive(UtDenmTrigger:?) -> value v_utDenmTrigger {
          var template (value) DenmParmContainers v_denmParmContainers;
          var DenmEventsParmsPerZone v_denmEventsParmsPerZone := PICS_DENM_EVENTS_RSU_UC1[vc_rsu_id][PX_ETSI_ZONE_ID - 1];
          var integer seq_number := f_incDenmSequenceNumber();

YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utDenmTrigger: ", v_utDenmTrigger);
YannGarcia's avatar
YannGarcia committed
          v_denmParmContainers := m_denmParmContainers(
                                                       PICS_RSU_PARAMS[vc_rsu_id].stationID,
                                                       seq_number,
                                                       v_utDenmTrigger.repetitionInterval,
                                                       v_denmEventsParmsPerZone[0].eventPosition,
                                                       v_utDenmTrigger.situation.eventType.causeCode,
                                                       v_denmEventsParmsPerZone[0].eventHistory,
                                                       v_denmEventsParmsPerZone[0].traces,
                                                       v_utDenmTrigger.validityDuration,
                                                       v_utDenmTrigger.relevanceDistance,
                                                       v_utDenmTrigger.relevanceTrafficDirection
                                                       );
          v_denmParmContainers.managementContainer.detectionTime := v_utDenmTrigger.detectionTime;
          vc_rsuMessagesValueList[vc_rsu_id].denms[lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms)] := valueof(
                                                                                                                  m_denmPdu_rsu(
                                                                                                                                PICS_RSU_PARAMS[vc_rsu_id].stationID,
                                                                                                                                m_denm(
                                                                                                                                       v_denmParmContainers.managementContainer,
                                                                                                                                       v_denmParmContainers.situationContainer,
                                                                                                                                       v_denmParmContainers.locationContainer
                                                                                                                                       )));
YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: utDenmTrigger: denm=[" & int2char(lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms) - 1) & "]=", vc_rsuMessagesValueList[vc_rsu_id].denms[lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms) - 1]);
YannGarcia's avatar
YannGarcia committed
          //denm={ { header := { protocolVersion := 2, messageID := 1, stationID := 1111101 }, denm := { management := { actionID := { originatingStationID := 1111101, sequenceNumber := 1 }, detectionTime := 510819417810, referenceTime := 510819420809, termination := omit, eventPosition := { latitude := 367467556, longitude := -45552381, positionConfidenceEllipse := { semiMajorConfidence := 100, semiMinorConfidence := 100, semiMajorOrientation := 0 }, altitude := { altitudeValue := 0, altitudeConfidence := alt_000_01 (0) } }, relevanceDistance := lessThan50m (0), relevanceTrafficDirection := upstreamTraffic (1), validityDuration := 2, transmissionInterval := omit, stationType := 15 }, situation := { informationQuality := 0, eventType := { causeCode := 91, subCauseCode := 0 }, linkedCause := omit, eventHistory := { { eventPosition := { deltaLatitude := 135, deltaLongitude := -147, deltaAltitude := 0 }, eventDeltaTime := omit, informationQuality := 0 }, { eventPosition := { deltaLatitude := -68, deltaLongitude := 74, deltaAltitude := 0 }, eventDeltaTime := omit, informationQuality := 0 } } }, location := { eventSpeed := omit, eventPositionHeading := omit, traces := { { { pathPosition := { deltaLatitude := -1086, deltaLongitude := 2551, deltaAltitude := 0 }, pathDeltaTime := omit }, { pathPosition := { deltaLatitude := -450, deltaLongitude := 1010, deltaAltitude := 0 }, pathDeltaTime := omit }, { pathPosition := { deltaLatitude := -460, deltaLongitude := 1000, deltaAltitude := 0 }, pathDeltaTime := omit }, { pathPosition := { deltaLatitude := -440, deltaLongitude := 1000, deltaAltitude := 0 }, pathDeltaTime := omit }, { pathPosition := { deltaLatitude := -440, deltaLongitude := 990, deltaAltitude := 0 }, pathDeltaTime := omit } } }, roadType := omit }, alacarte := omit } } }
          if (lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms) == 1) {
            tc_denm.start;
          }
          cfPort.send(UtDenmResults: { utDenmTriggerResult := { result := true, actionId := vc_rsuMessagesValueList[vc_rsu_id].denms[lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms) - 1].denm.management.actionID } } );
          repeat;
        }
        [vc_denm == true] cfPort.receive(UtDenmUpdate:?) -> value v_utDenmUpdate {
          var integer v_i := 0;
          var boolean v_found := false;

YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utDenmUpdate = ", v_utDenmUpdate);
YannGarcia's avatar
YannGarcia committed
          for (v_i := 0; v_i < lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms); v_i := v_i + 1) {
            if (v_utDenmUpdate.actionId.sequenceNumber == valueof(vc_rsuMessagesValueList[vc_rsu_id].denms[v_i].denm.management.actionID.sequenceNumber)) {
              v_found := true;
              break;
            }
          } // End of 'for' statement
          if (v_found == true) {
            vc_rsuMessagesValueList[vc_rsu_id].denms[v_i].denm.management.detectionTime := v_utDenmUpdate.detectionTime;
            if (ispresent(v_utDenmUpdate.validityDuration)) {
              vc_rsuMessagesValueList[vc_rsu_id].denms[v_i].denm.management.validityDuration := v_utDenmUpdate.validityDuration;
            }
            if (ispresent(v_utDenmUpdate.situation)) {
              vc_rsuMessagesValueList[vc_rsu_id].denms[v_i].denm.situation := v_utDenmUpdate.situation;
            }
            if (ispresent(v_utDenmUpdate.relevanceDistance)) {
              vc_rsuMessagesValueList[vc_rsu_id].denms[v_i].denm.management.relevanceDistance := v_utDenmUpdate.relevanceDistance;
            }
            if (ispresent(v_utDenmUpdate.relevanceTrafficDirection)) {
              vc_rsuMessagesValueList[vc_rsu_id].denms[v_i].denm.management.relevanceTrafficDirection := v_utDenmUpdate.relevanceTrafficDirection;
            }
            if (ispresent(v_utDenmUpdate.transmissionInterval)) {
              vc_rsuMessagesValueList[vc_rsu_id].denms[v_i].denm.management.transmissionInterval := v_utDenmUpdate.transmissionInterval;
            }
            if (ispresent(v_utDenmUpdate.transmissionInterval)) {
              vc_rsuMessagesValueList[vc_rsu_id].denms[v_i].denm.management.transmissionInterval := v_utDenmUpdate.transmissionInterval;
            }
            if (ispresent(v_utDenmUpdate.alacarte)) {
              vc_rsuMessagesValueList[vc_rsu_id].denms[v_i].denm.alacarte := v_utDenmUpdate.alacarte;
            }
          }
          cfPort.send(UtDenmResults: { utDenmUpdateResult := { result := true, actionId := vc_rsuMessagesValueList[vc_rsu_id].denms[v_i].denm.management.actionID } } );
          repeat;
        }
        [vc_denm == true] cfPort.receive(UtDenmTermination:?) -> value v_utDenmTermination {
          var integer v_i := 0;
          var boolean v_found := false;

YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utDenmTermination: ", v_utDenmTermination);
YannGarcia's avatar
YannGarcia committed
          for (v_i := 0; v_i < lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms); v_i := v_i + 1) {
            if (v_utDenmTermination.actionId.sequenceNumber == valueof(vc_rsuMessagesValueList[vc_rsu_id].denms[v_i].denm.management.actionID.sequenceNumber)) {
              v_found := true;
              break;
            }
          } // End of 'for' statement
          if (v_found == true) {
YannGarcia's avatar
YannGarcia committed
            log("a_process_cf_ut_command: v_utDenmTermination: v_i=", v_i);
            log("a_process_cf_ut_command: v_utDenmTermination: l=", lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms));
YannGarcia's avatar
YannGarcia committed
            if (lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms) > 1) { //Shift elements
              for (var integer v_j := v_i + 1; v_i < lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms); v_i := v_i + 1) {
                vc_rsuMessagesValueList[vc_rsu_id].denms[v_i] := vc_rsuMessagesValueList[vc_rsu_id].denms[v_j];
              v_j := v_j + 1;
              } // End of 'for' statement
              vc_rsuMessagesValueList[vc_rsu_id].denms[lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms) - 1] := {}
            } else {
              vc_rsuMessagesValueList[vc_rsu_id].denms := {};
              vc_denmEventCounter := 0;
            }
            log("v_utDenmTermination: New l=", lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms));
            if (lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms) == 0) {
              tc_denm.stop;
              f_sleep(1.0);
              vc_denm := false;
            }
            cfPort.send(UtDenmResults: { utDenmTerminationResult := true } );
          }
          repeat;
        }
        [vc_pki == true] cfPort.receive(UtPkiInitialize:?) -> value v_utPkiInitialize {
YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utPkiInitialize = ", v_utPkiInitialize);
          if (oct2int(v_utPkiInitialize.hashedId8) != 0) {
            var charstring v_certificate_id;
            var EtsiTs103097Certificate v_certificate;
            log("a_process_cf_ut_command: Looking for certificate ", v_utPkiInitialize.hashedId8);
            f_getCertificateFromDigest(v_utPkiInitialize.hashedId8, v_certificate, v_certificate_id);
            log("a_process_cf_ut_command (pki): Change certificate to ", v_certificate_id);
            f_acTriggerSecEvent(m_acEnableSecurity(v_certificate_id));
          }
          cfPort.send(UtPkiResults: { utPkiInitializeResult := true } );
          repeat;
        }
        [vc_pki == true] cfPort.receive(UtPkiTrigger: { triggerEnrolmentRequest := ? }) -> value v_utPkiTrigger {
          var ItsPkiHttp v_pki;
YannGarcia's avatar
YannGarcia committed
          log("a_process_cf_ut_command: v_utPkiTrigger=", v_utPkiTrigger);
          cfPort.send(UtPkiResults: { utPkiTriggerResult := true } );
          v_pki := ItsPkiHttp.create("TriggeredEc") alive;
          v_pki.start(f_trigger_enrolment_request_await_response(
                                                                 vc_reenrolment,
                                                                 vc_ec_counter,
                                                                 vc_ec_certificates
                                                                 ));
        [vc_pki == true] cfPort.receive(UtPkiTrigger: { triggerAuthorizationRequest := ? }) -> value v_utPkiTrigger {
          var ItsPkiHttp v_pki;
          
          cfPort.send(UtPkiResults: { utPkiTriggerResult := true } );
          v_pki := ItsPkiHttp.create("TriggeredAt") alive;
          v_pki.start(f_trigger_authorization_request_await_response(
                                                                     vc_ec_counter,
                                                                     vc_ec_certificates,
                                                                     vc_at_counter,
                                                                     vc_at_certificates
                                                                     ));
          repeat;
        }
        [] cfPort.receive {
          // Ignore it
          log("*** " & testcasename() & ": INFO: Unexpected CF message received ***");
          repeat;
        }
    } // End of 'altstep' statement
    
    function f_trigger_enrolment_request_await_response(
                                                        inout boolean p_reenrolment,
                                                        inout integer p_ec_counter,
                                                        inout SequenceOfEcData p_ec_certificates
                                                        ) runs on ItsPkiHttp {
      // Local variables
      var Oct32 v_private_key;
      var Oct32 v_compressed_public_key;
      var integer v_compressed_mode;
      var Oct32 v_request_hash;
      var Oct16 v_encrypted_sym_key;
      var Oct16 v_aes_sym_key;
      var Oct16 v_authentication_vector;
      var Oct12 v_nonce;
      var octetstring v_salt;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
      var HeaderLines v_headers;
      var HttpMessage v_response;
      var EtsiTs102941Data v_etsi_ts_102941_data;
      timer v_t := 5.0;
YannGarcia's avatar
YannGarcia committed

      log(">>> f_trigger_enrolment_request_await_response");

      f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID);
YannGarcia's avatar
YannGarcia committed

      f_http_build_inner_ec_request(v_private_key, v_compressed_public_key, v_compressed_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, v_salt, v_ieee1609dot2_signed_and_encrypted_data, v_request_hash);
      f_init_default_headers_list(-, "inner_ec_request", v_headers);
      httpPort.send(
                    m_http_request(
                                   m_http_request_post(
                                                       PICS_HTTP_POST_URI,
                                                       v_headers,
                                                       m_http_message_body_binary(
                                                                                  m_binary_body_ieee1609dot2_data(
                                                                                                                  v_ieee1609dot2_signed_and_encrypted_data
                                                                                                                  )))));
      // Wait for the resposne
      v_t.start;
      alt {
        [] httpPort.receive(
                            mw_http_response(
                                             mw_http_response_ok(
                                                                 mw_http_message_body_binary(
                                                                                             mw_binary_body_ieee1609dot2_data(
                                                                                                                              mw_enrolmentResponseMessage(
                                                                                                                                                          mw_encryptedData(
                                                                                                                                                                           -,
                                                                                                                                                                           mw_SymmetricCiphertext_aes128ccm
                                                                                                                                                                           ))))))) -> value v_response {
          v_t.stop;
          
          log("f_trigger_enrolment_request_await_response: receive ", v_response);
YannGarcia's avatar
YannGarcia committed
          if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, false, -, v_etsi_ts_102941_data) == false) {
            log("f_trigger_enrolment_request_await_response: Failed to verify PKI message ***");
          } else {
            log("f_trigger_enrolment_request_await_response: Receive ", v_etsi_ts_102941_data, " ***");
            // Verify the received EC certificate
            log("f_trigger_enrolment_request_await_response: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -)))), " ***"); // TODO In TITAN, this is the only way to get the unmatching in log
            if (match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -))))) {
              var InnerEcResponse v_inner_ec_response := v_etsi_ts_102941_data.content.enrolmentResponse;
              if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, v_compressed_public_key, v_compressed_mode)) {
                log("f_trigger_enrolment_request_await_response: Well-secured EA certificate received ***");
                log("p_inner_ec_response= ", v_inner_ec_response);
                // Store the new certificate
                p_ec_certificates[p_ec_counter].private_key := v_private_key;
                p_ec_certificates[p_ec_counter].aes_sym_key := v_aes_sym_key;
                p_ec_certificates[p_ec_counter].certificate := v_inner_ec_response.certificate;
                p_ec_counter := p_ec_counter + 1;
              } else {
                log("f_trigger_enrolment_request_await_response: Cannot verify EC certificate signature ***");
              }
            } else {
              log("f_trigger_enrolment_request_await_response: Unexpected message received ***");
            }
          }
        }
        [] v_t.timeout {
          log("*** " & testcasename() & ": INCONC: Expected message not received ***");
        }
      } // End of 'alt' statement

      f_cfHttpDown();
      log("<<< f_trigger_enrolment_request_await_response");
    }
    
    function f_trigger_authorization_request_await_response(
                                                            inout integer p_ec_counter,
                                                            inout SequenceOfEcData p_ec_certificates,
                                                            inout integer p_at_counter,
                                                            inout SequenceOfAtData p_at_certificates
                                                            ) runs on ItsPkiHttp {
      // Local variables
      var Oct32 v_private_key;
      var Oct32 v_compressed_public_key;
      var integer v_compressed_mode;
      var Oct32 v_request_hash;
      var Oct16 v_encrypted_sym_key;
      var Oct16 v_aes_sym_key;
      var Oct16 v_authentication_vector;
      var Oct12 v_nonce;
      var octetstring v_salt;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
      var HeaderLines v_headers;
      var HttpMessage v_response;
      var EtsiTs102941Data v_etsi_ts_102941_data;
      timer v_t := 5.0;
      
      log(">>> f_trigger_authorization_request_await_response");

      f_cfHttpUp(PICS_TS_EA_CERTIFICATE_ID, PICS_TS_AA_CERTIFICATE_ID);
      
      /*f_http_build_authorization_request(v_private_key, v_compressed_public_key, v_compressed_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, v_salt, v_ieee1609dot2_signed_and_encrypted_data, v_request_hash);
      f_init_default_headers_list(-, "inner_at_request", v_headers);
      httpPort.send(
                    m_http_request(
                                   m_http_request_post(
                                                       PICS_HTTP_POST_URI,
                                                       v_headers,
                                                       m_http_message_body_binary(
                                                                                  m_binary_body_ieee1609dot2_data(
                                                                                                                  v_ieee1609dot2_signed_and_encrypted_data
                                                                                                                  )))));
      // Wait for the resposne
      v_t.start;
      alt {
        [] httpPort.receive(
                            mw_http_response(
                                             mw_http_response_ok(
                                                                 mw_http_message_body_binary(
                                                                                             mw_binary_body_ieee1609dot2_data(
                                                                                                                              mw_enrolmentResponseMessage(
                                                                                                                                                          mw_encryptedData(
                                                                                                                                                                           -,
                                                                                                                                                                           mw_SymmetricCiphertext_aes128ccm
                                                                                                                                                                           ))))))) -> value v_response {
          v_t.stop;
          
          log("f_trigger_enrolment_request_await_response: receive ", v_response);
          if (f_verify_pki_response_message(v_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, false, v_etsi_ts_102941_data) == false) {
            log("f_trigger_enrolment_request_await_response: Failed to verify PKI message ***");
          } else {
            log("f_trigger_enrolment_request_await_response: Receive ", v_etsi_ts_102941_data, " ***");
            // Verify the received EC certificate
            log("f_trigger_enrolment_request_await_response: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -)))), " ***"); // TODO In TITAN, this is the only way to get the unmatching in log
            if (match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -))))) {
              var InnerEcResponse v_inner_at_response := v_etsi_ts_102941_data.content.enrolmentResponse;
              if (f_verify_at_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, v_compressed_public_key, v_compressed_mode)) {
                log("f_trigger_enrolment_request_await_response: Well-secured EA certificate received ***");
                log("p_inner_at_response= ", v_inner_at_response);
                p_reenrolment := true;
                // Store the new certificate
                p_at_certificates[p_at_certificates_counter] := v_inner_at_response.certificate;
                p_at_certificates_counter := p_at_xscertificates_counter + 1;
              } else {
                log("f_trigger_enrolment_request_await_response: Cannot verify EC certificate signature ***");
              }
            } else {
              log("f_trigger_enrolment_request_await_response: Unexpected message received ***");
            }
          }
        }
        [] v_t.timeout {
          log("*** " & testcasename() & ": INCONC: Expected message not received ***");
        }
      } // End of 'alt' statement

      f_cfHttpDown();
      log("<<< f_trigger_authorization_request_await_response");*/
} // End of module ItsRSUsSimulator_Functions