Newer
Older
module ItsRSUsSimulator_Functions {
// LibCommon
import from LibCommon_BasicTypesAndValues all;
import from LibCommon_DataStrings all;
import from LibCommon_VerdictControl all;
import from LibCommon_Sync all;
import from LibCommon_Time all;
// LibIts
import from ITS_Container language "ASN.1:1997" all;
import from CAM_PDU_Descriptions language "ASN.1:1997" all;
import from DENM_PDU_Descriptions language "ASN.1:1997" all;
import from MAPEM_PDU_Descriptions language "ASN.1:1997" all;
import from SPATEM_PDU_Descriptions language "ASN.1:1997" all;
import from IVIM_PDU_Descriptions language "ASN.1:1997" all;
//import from EVCSN_PDU_Descriptions language "ASN.1:1997" all;
import from SREM_PDU_Descriptions language "ASN.1:1997" all;
import from SSEM_PDU_Descriptions language "ASN.1:1997" all;
import from IEEE1609dot2BaseTypes language "ASN.1:1997" all;
import from IEEE1609dot2 language "ASN.1:1997" all;
import from EtsiTs102941BaseTypes language "ASN.1:1997" all;
import from EtsiTs102941TypesEnrolment language "ASN.1:1997" all;
import from EtsiTs102941TypesAuthorization language "ASN.1:1997" all;
import from EtsiTs102941TypesAuthorizationValidation language "ASN.1:1997" all;
import from EtsiTs102941MessagesCa language "ASN.1:1997" all;
import from EtsiTs103097Module language "ASN.1:1997" all;
import from LibItsCommon_Functions all;
// LibItsBtp
import from LibItsBtp_TypesAndValues all;
import from LibItsBtp_Templates all;
import from LibItsCam_TypesAndValues all;
import from LibItsDenm_TypesAndValues all;
// LibItsMapemSpatemm
import from LibItsMapemSpatem_Templates all;
// LibItsMapemSpatemm
import from LibItsIvim_Templates all;
// LibItsMapemSpatemm
import from LibItsSremSsem_Templates all;
// LibItsGeoNetworking
import from LibItsGeoNetworking_TestSystem all;
import from LibItsGeoNetworking_Functions all;
import from LibItsGeoNetworking_Templates all;
import from LibItsGeoNetworking_TypesAndValues all;
import from LibItsGeoNetworking_Pixits all;
// LibItsSecurity
import from LibItsSecurity_TypesAndValues all;
import from LibItsSecurity_Functions all;
import from LibItsSecurity_Templates all;
// LibItsHttp
import from LibItsHttp_TypesAndValues all;
import from LibItsHttp_Templates all;
import from LibItsHttp_BinaryTemplates all;
import from LibItsHttp_Functions all;
import from LibItsHttp_TestSystem all;
// LibItsPki
import from LibItsPki_TypesAndValues all;
import from LibItsPki_Functions all;
import from LibItsPki_TestSystem all;
import from LibItsPki_Pics all;
import from LibItsPki_Pixits all;
// AtsRSUsSimulator
import from ItsRSUsSimulator_TypesAndValues all;
import from ItsRSUsSimulator_TestSystem all;
import from ItsRSUsSimulator_Templates all;
import from ItsRSUsSimulator_PicsInitConsts all;
import from ItsRSUsSimulator_Pics all;
import from ItsRSUsSimulator_Pixits all;
/**
* @desc External function to compute a position using a reference position, a distance and an orientation
* @param p_refLongPosVector Vehicle reference position
* @param p_cenLongPosVector Collision point position
* @param p_rotation Rotation angle in 1/10 of degrees (from North)
* @param p_latitude Computed position's latitude
* @param p_longitude Computed position's longitude
* @remark See http://www.movable-type.co.uk/scripts/latlong.html
*/
external function fx_computePositionFromRotation(
in Int32 p_refLatitude,
in Int32 p_refLongitude,
in Int32 p_cenLatitude,
in Int32 p_cenLongitude,
out Int32 p_latitude,
out Int32 p_longitude
);
} // End of group externalFunctions
group rsuConfigurationFunctions {
/**
* @desc This configuration features:
* - one ITS node (IUT)
* - two ITS nodes (nodeA, nodeB)
* - Area1 which only includes NodeB and IUT
* - Area2 which only includes NodeB
* NodeB being close to the area center
*/
function f_cf01Up() runs on ItsRSUsSimulator {
// Local variables
// Map
map(self:acPort, system:acPort);
map(self:cfPort, system:cfPort);
map(self:geoNetworkingPort, system:geoNetworkingPort);
// Connect
f_connect4SelfOrClientSync();
activate(a_cf01Down());
// Initialise secured mode
LibItsGeoNetworking_Functions.f_initialiseSecuredMode();
if (vc_pki == true) {
// TODO LibItsPki_Function.f_cf01();
}
} // End of function f_cf01Up
function f_cf01Down() runs on ItsRSUsSimulator {
vc_rsuMessagesValueList := {};
LibItsGeoNetworking_Functions.f_uninitialiseSecuredMode();
// Unmap
unmap(self:acPort, system:acPort);
unmap(self:cfPort, system:cfPort);
unmap(self:geoNetworkingPort, system:geoNetworkingPort);
// Disconnect
f_disconnect4SelfOrClientSync();
[] a_shutdown() {
f_poDefault();
f_cf01Down();
log("*** a_cf01Down: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***");
stop;
}
} // End of altstep a_cf01Down
} // End of group rsuConfigurationFunctions
group usecase6 {
function f_initialiseVehicleSimulatorComponent(
in ItsRSUsSimulator p_component,
out template (omit) CAM p_cam
) runs on ItsRSUsSimulator {
p_cam :=
m_camMsg_vehicle(
f_getCurrentTime() mod 65536, // Shall be updated in function f_prepare_vehicle_cam
m_rsuPosition(
0, // Shall be computed
0 // Shall be computed
)
);
map(p_component:geoNetworkingPort, system:geoNetworkingPort);
} // End of function f_initialiseVehicleSimulatorComponent
function f_uninitialiseVehicleSimulatorComponent(
in ItsRSUsSimulator p_component
) runs on ItsRSUsSimulator {
p_component.done;
unmap(p_component:geoNetworkingPort, system:geoNetworkingPort);
} // End of function f_uninitialiseVehicleSimulatorComponent
} // End of group usecase6
function f_setup_rsu(
in integer p_rsu_id
) runs on ItsRSUsSimulator {
// Local variables
var template (value) DenmParmContainers v_denmParmContainers;
var template (omit) GeoNetworkingPdu v_beacon := omit;
var template (omit) DENMs v_denms := omit;
var template (omit) CAM v_cam := omit;
var template (omit) MAPEM v_mapem := omit;
var template (omit) SPATEMs v_spatems := omit;
var template (omit) IVIM v_ivim := omit;
//var template (omit) EvcsnPdu v_evcsn := omit;
var template (omit) SSEM v_ssem := omit;
var integer v_counter;
log(">>> f_setup_rsu: ", vc_cam);
log(">>> f_setup_rsu: ", vc_denm);
log(">>> f_setup_rsu: ", p_rsu_id);
log(">>> f_setup_rsu: ", PX_ETSI_USE_CASE_ID);
vc_longPosVectorRsu := PICS_RSU_PARAMS[p_rsu_id].longPosVector;
log("f_setup_rsu: vc_longPosVectorRsu=", vc_longPosVectorRsu);
// MAPEM, only if PX_ETSI_USE_CASE_ID is set to 3
if ((vc_mapem == true) and (PX_ETSI_USE_CASE_ID == 3) and ispresent(PICS_MAPEM_PARMS_RSUs[p_rsu_id].intersections)) {
// Build the list of the MAPEM events
v_mapem :=
m_mapemParm(
PICS_RSU_PARAMS[vc_rsu_id].stationID,
m_mapem(
f_getMsgIssueRevision(),
PICS_MAPEM_PARMS_RSUs[p_rsu_id].intersections,
PICS_MAPEM_PARMS_RSUs[p_rsu_id].roadSegments
));
// Update revision fields
v_mapem.map_.intersections[0].revision := f_incMsgIssueRevision();
// TODO Add more?
// SPATEM, only if PX_ETSI_USE_CASE_ID is set to 3
if ((vc_spatem == true) and (PX_ETSI_USE_CASE_ID == 3) and (lengthof(PICS_SPATEM_PARMS_RSUs[p_rsu_id]) != 0)) {
// Reset counter
vc_currentPhaseStartTime := 36001;
vc_endPhaseStartTime := 0;
vc_spatemStatesId := 0;
for (v_counter := 0; v_counter < lengthof(PICS_SPATEM_PARMS_RSUs[p_rsu_id]); v_counter := v_counter + 1) {
v_spatems[v_counter] :=
m_spatemParm(
PICS_RSU_PARAMS[p_rsu_id].stationID,
m_spatem(
PICS_SPATEM_PARMS_RSUs[p_rsu_id][v_counter].intersections,
"SignalGroupID #" & int2str(PICS_SPATEM_PARMS_RSUs[p_rsu_id][v_counter].signalGroupID)
));
for (var integer v_intersection := 0; v_intersection < lengthof(v_spatems[v_counter].spat.intersections); v_intersection := v_intersection + 1) {
vc_states[v_counter][v_intersection] := v_spatems[v_counter].spat.intersections[v_intersection].states;
} // End of 'for' statement
// TODO Build SPATEM with dynamic values
} // End of 'for' statement
// TODO Build SPATEM with dynamic values
// IVIM, only if PX_ETSI_USE_CASE_ID is set to 5
if ((vc_ivim == true) and (PX_ETSI_USE_CASE_ID == 5) and ispresent(PICS_IVIM_PARMS_RSUs[p_rsu_id].provider)) {
v_ivim :=
m_ivimParm(
PICS_RSU_PARAMS[p_rsu_id].stationID,
m_ivimStructure(
m_iviManagementContainer(
PICS_IVIM_PARMS_RSUs[p_rsu_id].provider,
PICS_IVIM_PARMS_RSUs[p_rsu_id].iviIdentificationNumber,
0//IviStatus_new_
),
));
// Update ivi status
v_ivim.ivi.mandatory.validFrom := f_getCurrentTime();
v_ivim.ivi.mandatory.validTo := valueof(v_ivim.ivi.mandatory.validFrom) + 43200000; // 12hours
/* // EVCSN, only if PX_ETSI_USE_CASE_ID is set to 8 */
/* if ((vc_evcsn == true) and (PX_ETSI_USE_CASE_ID == 8)) { */
/* // Build the list of the EVCSN events */
/* v_evcsn := */
/* m_evcsnParm( */
/* PICS_RSU_PARAMS[p_rsu_id].stationID, */
/* m_evcsn( */
/* m_itsPOIHeader( */
/* -, */
/* 0, // To be updated at run time */
/* - */
/* ), */
/* m_itsEVCSNData( */
/* -, */
/* { c_PICS_ITS_CHARGING } */
/* ) */
/* )); */
/* // Update poi status */
/* } else { */
/* vc_evcsn := false; */
/* } */
// DENM, only if PX_ETSI_USE_CASE_ID is set to 1
if (vc_denm == true) {
if (PX_ETSI_USE_CASE_ID == 1) {
// Build the list of the DENM events for the specified RSU (PX_RSU_ID) and the given zone (PX_ETSI_ZONE_ID)
for (v_counter := 0; v_counter < lengthof(PICS_DENM_EVENTS_RSU_UC1[p_rsu_id][PX_ETSI_ZONE_ID - 1]); v_counter := v_counter + 1) {
var DenmEventsParmsPerZone v_denmEventsParmsPerZone := PICS_DENM_EVENTS_RSU_UC1[p_rsu_id][PX_ETSI_ZONE_ID - 1];
v_denmParmContainers := m_denmParmContainers(
PICS_RSU_PARAMS[p_rsu_id].stationID,
f_incDenmSequenceNumber(),
PICS_DENM_REPETITION_INTERVAL,
v_denmEventsParmsPerZone[v_counter].eventPosition,
v_denmEventsParmsPerZone[v_counter].causeCodeType,
v_denmEventsParmsPerZone[v_counter].eventHistory,
v_denmEventsParmsPerZone[v_counter].traces,
PICS_DENM_RELEVANCE_DISTANCE,
PICS_DENM_RELEVANCE_TRAFFIC_DIRECTION
);
v_denms[v_counter] := valueof(
m_denmPdu_rsu(
PICS_RSU_PARAMS[p_rsu_id].stationID,
m_denm(
v_denmParmContainers.managementContainer,
v_denmParmContainers.situationContainer,
v_denmParmContainers.locationContainer
)));
if (ispresent(v_denmEventsParmsPerZone[v_counter].roadWorksContainerExtended)) {
v_denms[v_counter].denm.alacarte := m_alacarte(v_denmEventsParmsPerZone[v_counter].roadWorksContainerExtended);
}
} // End of 'for' statement
// Update referenceDenms field, all except the current one
for (v_counter := 0; v_counter < lengthof(PICS_DENM_EVENTS_RSU_UC1[p_rsu_id][PX_ETSI_ZONE_ID - 1]); v_counter := v_counter + 1) {
if (ispresent(v_denms[v_counter].denm.alacarte.roadWorks)) {
var integer v_referenceDenms := 0;
for (var integer v_counter1 := 0; v_counter1 < lengthof(PICS_DENM_EVENTS_RSU_UC1[p_rsu_id][PX_ETSI_ZONE_ID - 1]); v_counter1 := v_counter1 + 1) {
if (v_counter1 == v_counter) {
continue;
}
v_denms[v_counter].denm.alacarte.roadWorks.referenceDenms[v_referenceDenms] := v_denms[v_counter1].denm.management.actionID;
v_referenceDenms := v_referenceDenms + 1;
} // End of 'for' statement
}
} // End of 'for' statement
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
} else if (PX_ETSI_USE_CASE_ID == 2) { // Use case for Accident
// Build the list of the DENM events for the specified RSU (PX_RSU_ID) and the given zone (PX_ETSI_ZONE_ID)
for (v_counter := 0; v_counter < lengthof(PICS_DENM_PARAMS_UC2); v_counter := v_counter + 1) {
v_denmParmContainers := m_denmParmContainers(
PICS_RSU_PARAMS[p_rsu_id].stationID,
f_incDenmSequenceNumber(),
PICS_DENM_REPETITION_INTERVAL,
PICS_DENM_PARAMS_UC2[v_counter].eventPosition,
PICS_DENM_PARAMS_UC2[v_counter].causeCodeType,
omit,
omit,
PICS_DENM_VALIDITY_DURATION,
PICS_DENM_RELEVANCE_DISTANCE,
PICS_DENM_RELEVANCE_TRAFFIC_DIRECTION
);
log("f_setup_rsu: v_denmParmContainers=", v_denmParmContainers);
v_denms[v_counter] := valueof(
m_denmPdu_rsu(
PICS_RSU_PARAMS[p_rsu_id].stationID,
m_denm(
v_denmParmContainers.managementContainer,
v_denmParmContainers.situationContainer,
omit
)));
} // End of 'for' statement
} else {
}
log("f_setup_rsu: v_denms=", v_denms);
// Build the list of the CAM events
if (PX_ETSI_USE_CASE_ID == 7) {
vc_longPosVectorRsu := PICS_UC7_LPV.longPosVector;
v_cam :=
m_camParm(
PICS_UC7_LPV.stationID,
m_rsuPosition(
PICS_UC7_LPV.longPosVector.latitude,
PICS_UC7_LPV.longPosVector.longitude
),
PICS_UC7_LPV.pathHistory,
{
rsuContainerHighFrequency := {
protectedCommunicationZonesRSU := omit
}
}
);
} else if (PX_ETSI_USE_CASE_ID == 6) { // FIXME To be removed only for test
v_cam :=
m_camMsg_vehicle(
PICS_RSU_PARAMS[p_rsu_id].stationID,
f_getCurrentTime() mod 65536, // Shall be updated in function f_prepare_vehicle_cam
m_rsuPosition(
vc_longPosVectorRsu.latitude,
vc_longPosVectorRsu.longitude
)
);
v_cam :=
m_camParm(
PICS_RSU_PARAMS[p_rsu_id].stationID,
m_rsuPosition(
vc_longPosVectorRsu.latitude,
vc_longPosVectorRsu.longitude
),
PICS_RSU_PARAMS[p_rsu_id].pathHistory,
m_highFrequencyContainer_rsuContainerHighFrequency(
m_rSUContainerHighFrequency(
)));
} else {
v_cam :=
m_camParm(
PICS_RSU_PARAMS[p_rsu_id].stationID,
m_rsuPosition(
vc_longPosVectorRsu.latitude,
vc_longPosVectorRsu.longitude
),
PICS_RSU_PARAMS[p_rsu_id].pathHistory,
{
rsuContainerHighFrequency := {
protectedCommunicationZonesRSU := omit
}
}
// Build the list of the Beacon events
v_beacon := valueof(m_geoNwPdu(
m_geoNwBeaconPacket(
vc_longPosVectorRsu
),
m_defaultLifetime,
1
)
);
v_beacon.gnPacket.packet.commonHeader.flags := f_isMobile();
f_acTriggerEvent(m_startPassBeaconing(m_beaconHeader(m_longPosVector(PX_TS_NODE_B_LOCAL_GN_ADDR, 0)).beaconHeader));
}
// Build the messages value list for this RSU
vc_rsuMessagesValueList[p_rsu_id] :=
m_rsuProfile(
v_denms,
v_mapem,
v_spatems,
v_ivim,
v_ssem
);
if (PICS_RSU_PARAMS[p_rsu_id].geoShape == e_geoCircle) {
vc_geoArea := {
shape := e_geoCircle,
area := {
geoAreaPosLatitude := vc_longPosVectorRsu.latitude,
geoAreaPosLongitude := vc_longPosVectorRsu.longitude,
distanceA := PICS_RSU_PARAMS[p_rsu_id].geoParms.radius,
distanceB := PICS_RSU_PARAMS[p_rsu_id].geoParms.radius,
angle := 0
}
}
} else {
log("*** " & testcasename() & ": INCONC: Wrong PICS_RSU_GEOAREA_FORM event initialisation ***");
setverdict(inconc);
stop;
}
log("<<< f_setup_rsu: ", vc_rsuMessagesValueList[p_rsu_id]);
} // End of function f_setup_rsu
in CfEvent p_cfEvent
) runs on ItsRSUsSimulator return boolean {
var template (value) CfResult v_result := true;
// Terminate simulation
if (p_cfEvent == "stop") {
if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].beacon)) {
tc_beacon.stop;
}
if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].cam)) {
if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].denms)) {
if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].mapem)) {
if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].spatems)) {
if (ispresent(vc_rsuMessagesValueList[vc_rsu_id].ivim)) {
tc_ivim.stop;
}
} else {
v_result := false;
}
cfPort.send(v_result);
return true;
} // End of function f_process_cf_event
out template (value) GnRawPayload p_payload
vc_rsuMessagesValueList[vc_rsu_id].cam.cam.generationDeltaTime := f_getCurrentTime() mod 65536; // See ETSI EN 302 637-2 V1.3.0 - Clause B.3 generationDelatTime
p_payload := valueof(
f_adaptPayload(
bit2oct(
encvalue(
valueof(
vc_rsuMessagesValueList[vc_rsu_id].cam
))),
PICS_CAM_BTP_DESTINATION_PORT,
PICS_CAM_BTP_SOURCE_PORT
)
);
} // End of function f_prepare_cam
out template (value) GnRawPayload p_payload,
vc_rsuMessagesValueList[vc_rsu_id].denms[vc_denmEventCounter].denm.management.referenceTime := f_getCurrentTime();
if (p_cancellation == true) {
vc_rsuMessagesValueList[vc_rsu_id].denms[vc_denmEventCounter].denm.management.termination := isCancellation;
}
p_payload := valueof(
f_adaptPayload(
bit2oct(
encvalue(
valueof(vc_rsuMessagesValueList[vc_rsu_id].denms[vc_denmEventCounter]
))),
PICS_DENM_BTP_DESTINATION_PORT,
PICS_DENM_BTP_SOURCE_PORT
)
);
vc_denmEventCounter := (vc_denmEventCounter + 1) mod lengthof(vc_rsuMessagesValueList[vc_rsu_id].denms);
} // End of function f_prepare_denm
out template (value) GnRawPayload p_payload
p_payload := valueof(
f_adaptPayload(
bit2oct(
encvalue(
valueof(
vc_rsuMessagesValueList[vc_rsu_id].mapem
))),
PICS_MAPEM_BTP_DESTINATION_PORT,
PICS_MAPEM_BTP_SOURCE_PORT
)
);
} // End of function f_prepare_mapem
function f_computeEndPhaseStartTime(
in TimeMark p_timeMark,
in UInt32 p_inc
) return TimeMark {
var UInt32 v_endPhaseStartTime := p_timeMark + p_inc;
return v_endPhaseStartTime mod 36000;
}
out template (value) GnRawPayload p_payload
var template (omit) SPATEM v_spatem := p_spatem; // Make a copy
var TimeMark v_currentTimeMark := f_getCurrentTimeMark();
if (vc_currentPhaseStartTime == 36001) { // First call
select (vc_spatemStatesId) {
case (0) {
vc_endPhaseStartTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, PICS_SPATEM_REPITITION_DURATION_STATE_30);
}
case (1) {
vc_endPhaseStartTime := f_computeEndPhaseStartTime(v_currentTimeMark, PICS_SPATEM_REPITITION_DURATION_STATE_30);
}
case (2) {
vc_endPhaseStartTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, PICS_SPATEM_REPITITION_DURATION_STATE_30);
}
} // End of 'select' statement
if (v_currentTimeMark >= vc_endPhaseStartTime) {
var float t := (int2float(v_currentTimeMark - vc_endPhaseStartTime) / int2float(v_currentTimeMark));
log("t = ", t);
if (t < 1.0) { // Change state
vc_spatemStatesId := (vc_spatemStatesId + 1) mod vc_spatemStatesNum;
vc_currentPhaseStartTime := v_currentTimeMark;
vc_endPhaseStartTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, PICS_SPATEM_REPITITION_DURATION_STATE_30);
}
}
log("vc_currentPhaseStartTime = ", vc_currentPhaseStartTime);
log("v_currentTimeMark = ", v_currentTimeMark);
log("vc_endPhaseStartTime = ", vc_endPhaseStartTime);
log("vc_spatemStatesId = ", vc_spatemStatesId);
// Rebuild SPATEM message
for (var integer v_intersection := 0; v_intersection < lengthof(v_spatem.spat.intersections); v_intersection := v_intersection + 1) {
var template (omit) MovementList v_states := vc_states[vc_signalGroupParmId][v_intersection];
v_spatem.spat.intersections[v_intersection].states := { v_states[vc_spatemStatesId] };
v_spatem.spat.intersections[v_intersection].moy := f_getMinuteOfTheYear();
v_spatem.spat.intersections[v_intersection].timeStamp := f_getDSecond();
v_spatem.spat.intersections[v_intersection].revision := (valueof(v_spatem.spat.intersections[v_intersection].revision) + 1) mod 128;
case (0) { // permissive_Movement_Allowed
v_spatem.spat.intersections[v_intersection].states[1] := v_states[1]; // permissive-clearance
//v_spatem.spat.intersections[v_intersection].states[2] := v_states[2];
// Update startTime & minEndTime
v_spatem.spat.intersections[v_intersection].states[0].state_time_speed[0].timing.minEndTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, PICS_SPATEM_REPITITION_DURATION_STATE_30);
v_spatem.spat.intersections[v_intersection].states[1].state_time_speed[0].timing.startTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, PICS_SPATEM_REPITITION_DURATION_STATE_30);
v_spatem.spat.intersections[v_intersection].states[1].state_time_speed[0].timing.minEndTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, PICS_SPATEM_REPITITION_DURATION_STATE_40);
case (1) { // permissive-clearance
v_spatem.spat.intersections[v_intersection].states[1] := v_states[2]; // stop-And-Remain
//v_spatem.spat.intersections[v_intersection].states[2] := v_states[0];
// Update startTime & minEndTime
v_spatem.spat.intersections[v_intersection].states[0].state_time_speed[0].timing.minEndTime := f_computeEndPhaseStartTime(v_currentTimeMark, PICS_SPATEM_REPITITION_DURATION_STATE_10);
v_spatem.spat.intersections[v_intersection].states[1].state_time_speed[0].timing.startTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, PICS_SPATEM_REPITITION_DURATION_STATE_10);
v_spatem.spat.intersections[v_intersection].states[1].state_time_speed[0].timing.minEndTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, PICS_SPATEM_REPITITION_DURATION_STATE_30);
case (2) { // stop-And-Remain
v_spatem.spat.intersections[v_intersection].states[1] := v_states[0]; // permissive_Movement_Allowed
//v_spatem.spat.intersections[v_intersection].states[2] := v_states[1];
// Update startTime & minEndTime
v_spatem.spat.intersections[v_intersection].states[0].state_time_speed[0].timing.minEndTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, PICS_SPATEM_REPITITION_DURATION_STATE_20);
v_spatem.spat.intersections[v_intersection].states[1].state_time_speed[0].timing.startTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, PICS_SPATEM_REPITITION_DURATION_STATE_20);
v_spatem.spat.intersections[v_intersection].states[1].state_time_speed[0].timing.minEndTime := f_computeEndPhaseStartTime(vc_currentPhaseStartTime, PICS_SPATEM_REPITITION_DURATION_STATE_50);
}
case else {
}
} // End of 'select' statement
} // End of 'for' statement
log("v_spatem.spat.intersections = ", v_spatem.spat.intersections);
p_payload := valueof(
f_adaptPayload(
bit2oct(
encvalue(
valueof(
v_spatem
))),
PICS_SPATEM_BTP_DESTINATION_PORT,
PICS_SPATEM_BTP_SOURCE_PORT
} // End of function f_prepare_spatem
out template (value) GnRawPayload p_payload
p_payload := valueof(
f_adaptPayload(
bit2oct(
encvalue(
valueof(
vc_rsuMessagesValueList[vc_rsu_id].ivim
))),
PICS_IVIM_BTP_DESTINATION_PORT,
PICS_IVIM_BTP_SOURCE_PORT
)
);
} // End of function f_prepare_ivim
/* function f_prepare_evcsn( */
/* out template (value) GnRawPayload p_payload */
/* ) runs on ItsRSUsSimulator { */
/* vc_rsuMessagesValueList[vc_rsu_id].evcsn.evcsn.poiHeader.timeStamp := f_getCurrentTime(); // Check if it is ITS or UTC time */
/* log("vc_rsuMessagesValueList[vc_rsu_id].evcsn", valueof(vc_rsuMessagesValueList[vc_rsu_id].evcsn)); */
/* p_payload := valueof( */
/* f_adaptPayload( */
/* bit2oct( */
/* encvalue( */
/* valueof( */
/* vc_rsuMessagesValueList[vc_rsu_id].evcsn */
/* ))), */
/* PICS_EVCSN_BTP_DESTINATION_PORT, */
/* PICS_EVCSN_BTP_SOURCE_PORT */
/* ) */
/* ); */
/* } // End of function f_prepare_evcsn */
function f_adaptPayload(
in template (value) octetstring p_finalPayload,
in template (value) BtpPortId p_destPort,
in template (value) BtpPortId p_srcPort := 0,
in NextHeader p_nextHeader := PX_GN_UPPER_LAYER
) return template (value) GnRawPayload {
var template (value) GnRawPayload v_payload := ''O;
if(p_nextHeader == e_any) {
if(p_nextHeader == e_ipv6) {
log("*** " & testcasename() & ": INCONC: Layer IPv6 not supported ***");
setverdict(inconc);
stop;
}
if(p_nextHeader == e_btpA) {
v_payload := int2oct(valueof(p_destPort), 2) & int2oct(valueof(p_srcPort), 2) & valueof(p_finalPayload);
if(p_nextHeader == e_btpB) {
v_payload := int2oct(valueof(p_destPort), 2) & int2oct(valueof(p_srcPort), 2) & valueof(p_finalPayload);
return v_payload;
}
return v_payload;
} // End of function f_adaptPayload
function f_isInApproach(
in ThreeDLocation p_detectionPoint,
in ThreeDLocation p_location,
in float p_dist := 150.0
) return boolean {
var float v_dist := fx_computeDistance(p_detectionPoint.latitude, p_detectionPoint.longitude, p_location.latitude, p_location.longitude);
log("v_dist = ", v_dist);
return v_dist <= p_dist;
}
function f_mirror_and_send_vehicle_cam(
in template (value) CAM p_camSimu,
in CAM p_camVehicle,
in ThreeDLocation p_location
var ReferencePosition v_newPosition := p_camVehicle.cam.camParameters.basicContainer.referencePosition;
var template (value) GnRawPayload v_payload;
fx_computePositionFromRotation(
p_location.latitude,
p_location.longitude,
PICS_UC6_COLLISION_POINT_Z2.latitude, // Z1
PICS_UC6_COLLISION_POINT_Z2.longitude, // Z1
900,
v_newPosition.latitude,
v_newPosition.longitude
);
log("Rotation: (", p_location.latitude, ", ", p_location.longitude, ") --> (", v_newPosition.latitude, ", ", v_newPosition.longitude, ")");
} else {
fx_computePositionFromRotation(
p_camVehicle.cam.camParameters.basicContainer.referencePosition.latitude,
p_camVehicle.cam.camParameters.basicContainer.referencePosition.longitude,
PICS_UC6_COLLISION_POINT_Z2.latitude, // Z1
PICS_UC6_COLLISION_POINT_Z2.longitude, // Z1
2450,
v_newPosition.latitude,
v_newPosition.longitude
);
log("Rotation: (", p_camVehicle.cam.camParameters.basicContainer.referencePosition.latitude, ", ", p_camVehicle.cam.camParameters.basicContainer.referencePosition.longitude, ") --> (", v_newPosition.latitude, ", ", v_newPosition.longitude, ")");
}
/*v_newPosition.latitude := ;
v_newPosition.longitude := ;*/
// Update CAM
p_camSimu.cam.generationDeltaTime := f_getCurrentTime() mod 65536; // See ETSI EN 302 637-2 V1.3.0 - Clause B.3 generationDelatTime
p_camSimu.cam.camParameters.basicContainer.referencePosition := v_newPosition;
p_camSimu.cam.camParameters.highFrequencyContainer := p_camVehicle.cam.camParameters.highFrequencyContainer;
v_payload := valueof(
f_adaptPayload(
bit2oct(
encvalue(
valueof(
p_camSimu
))),
PICS_CAM_BTP_DESTINATION_PORT,
PICS_CAM_BTP_SOURCE_PORT
)
// Update GN
vc_longPosVectorRsu := PICS_UC6_VEHICLE_TEMPLATE_POSITION;
vc_longPosVectorRsu.latitude := valueof(p_camSimu.cam.camParameters.basicContainer.referencePosition.latitude);
vc_longPosVectorRsu.longitude := valueof(p_camSimu.cam.camParameters.basicContainer.referencePosition.longitude);
vc_geoArea := PICS_UC6_VEHICLE_TEMPLATE_GEOAREA;
vc_geoArea.area.geoAreaPosLatitude := valueof(p_camSimu.cam.camParameters.basicContainer.referencePosition.latitude);
vc_geoArea.area.geoAreaPosLongitude := valueof(p_camSimu.cam.camParameters.basicContainer.referencePosition.longitude);
// And send it
f_send(v_payload, PICS_CAM_ITS_AID);
in template (value) GnRawPayload p_payload,
) runs on ItsRSUsSimulator {
var GeoNetworkingPdu v_geoNetworkingPdu;
if (p_its_aid == 36) { // CAM
v_geoNetworkingPdu := valueof(m_geoNwPdu( // FIXME Use PIXIT parameter to get a fully configurable template
vc_longPosVectorRsu,
valueof(p_payload)
),
Lifetime:{
multiplier := c_defaultLifetime,
ltBase := e_100s
},
} else if (p_its_aid == 37) { // DENM
v_geoNetworkingPdu := valueof(m_geoNwPdu( // FIXME Use PIXIT parameter to get a fully configurable template
m_geoNwTsbPacket_payload(
f_incLocalSeqNumber(),
vc_longPosVectorRsu,
-,
-,
valueof(p_payload)
),
Lifetime:{
multiplier := c_defaultLifetime,
ltBase := e_100s
},
c_hopLimit1
} else if ((p_its_aid == 137) or (p_its_aid == 138)) { // MAPEM/SPATEM
v_geoNetworkingPdu := valueof(m_geoNwPdu( // FIXME Use PIXIT parameter to get a fully configurable template
m_geoNwTsbPacket_payload(
f_incLocalSeqNumber(),
vc_longPosVectorRsu,
-,
-,
valueof(p_payload)
),
Lifetime:{
multiplier := c_defaultLifetime,
ltBase := e_100s
},
c_hopLimit1
));
} else { // Beacon
v_geoNetworkingPdu := valueof(vc_rsuMessagesValueList[vc_rsu_id].beacon);
f_sendGeoNetMessage(valueof(m_geoNwReq_linkLayerBroadcast(v_geoNetworkingPdu, p_its_aid)));
function f_processBeacon(
in GeoNetworkingPdu p_geoNetworkingPdu
) runs on ItsRSUsSimulator {
var bitstring v_enc_msg;
log("f_processBeacon: Beacon=", p_geoNetworkingPdu);
if (PICS_SEND_BEACON_INDICATION) {
var UtGnEventInd v_utGnEventInd;
var integer v_result;
// Extract BEACON message
var octetstring v_payload := p_geoNetworkingPdu.gnPacket.packet.payload;
// Send UtGnEventInd
log("f_processBeacon: v_payload=", v_payload);
v_utGnEventInd.rawPayload := v_payload;
cfPort.send(v_utGnEventInd);
}
}
) runs on ItsRSUsSimulator {
var bitstring v_enc_msg;
log("f_processCam: CAM=", p_geoNetworkingPdu.gnPacket.packet.payload);
if (PICS_SEND_CAM_INDICATION) {
var UtCamEventInd v_utCamEventInd;
var integer v_result;
// Extract CAM message
var octetstring v_payload := p_geoNetworkingPdu.gnPacket.packet.payload;
// Remove BTP layer
v_payload := substr(v_payload, 4, lengthof(v_payload) - 4);
// Send UtCamEventInd
log("f_processCam: v_payload=", v_payload);
v_enc_msg := oct2bit(v_payload);
if (decvalue(v_enc_msg, v_utCamEventInd.camMsg) == 0) {
cfPort.send(v_utCamEventInd);
}
}
}
function f_processDenm(
in GeoNetworkingPdu p_geoNetworkingPdu
) runs on ItsRSUsSimulator {
var bitstring v_enc_msg;
log("f_processDenm: DENM=", p_geoNetworkingPdu.gnPacket.packet.payload);
if (PICS_SEND_DENM_INDICATION) {
var UtDenmEventInd v_utDenmEventInd;
var integer v_result;
// Extract DENM message
var octetstring v_payload := p_geoNetworkingPdu.gnPacket.packet.payload;
// Remove BTP layer
v_payload := substr(v_payload, 4, lengthof(v_payload) - 4);
// Send UtDenmEventInd
log("f_processDenm: v_payload=", v_payload);
v_enc_msg := oct2bit(v_payload);
if (decvalue(v_enc_msg, v_utDenmEventInd.denMsg) == 0) {
cfPort.send(v_utDenmEventInd);
}
}
}
function f_processSrem(
in GeoNetworkingPdu p_geoNetworkingPdu
) runs on ItsRSUsSimulator {
if (ispresent(p_geoNetworkingPdu.gnPacket.packet.payload)) {
/* TODO Decode and process GnPayload or use different ports
if (ispresent(p_geoNetworkingPdu.gnPacket.packet.payload.decodedPayload.btpPacket.payload.decodedPayload)) {
if (ischosen(p_geoNetworkingPdu.gnPacket.packet.payload.decodedPayload.btpPacket.payload.decodedPayload.sremPacket)) {
var SignalRequestMessage v_signalRequestMessage := p_geoNetworkingPdu.gnPacket.packet.payload.decodedPayload.btpPacket.payload.decodedPayload.sremPacket.srm;
var template (value) GnRawPayload v_payload;
log(v_signalRequestMessage);
// Build response
// TODO v_ssem.ssm.status
v_payload := valueof(
f_adaptPayload(
bit2oct(
encvalue(
valueof(
m_ssem(
v_signalRequestMessage
)))),
PICS_SSEM_BTP_DESTINATION_PORT,
PICS_SSEM_BTP_SOURCE_PORT
)
);
// Send SSEM
f_send(v_payload, PICS_SSEM_ITS_AID);
} // else, ignore message
} // else, ignore message
} // End of function f_processSrem
function f_incLocalSeqNumber() runs on ItsRSUsSimulator return UInt16 {
vc_localSeqNumber := (vc_localSeqNumber + 1) mod 65536;
return vc_localSeqNumber;
}
function f_incMsgIssueRevision() runs on ItsRSUsSimulator return MsgCount {
vc_msgIssueRevision := (vc_msgIssueRevision + 1) mod 128; // See MsgCount declaration
return vc_msgIssueRevision;
}
function f_getMsgIssueRevision() runs on ItsRSUsSimulator return MsgCount {
return vc_msgIssueRevision;
}
function f_incDenmSequenceNumber() runs on ItsRSUsSimulator return SequenceNumber {
vc_sequenceNumber := (vc_sequenceNumber + 1) mod 65536; // See SequenceNumber declaration
return vc_sequenceNumber;
}
function f_getDenmSequenceNumber() runs on ItsRSUsSimulator return SequenceNumber {
in integer p_src_port
) return template (present) octetstring {
//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
altstep a_process_cf_ut_command() runs on ItsRSUsSimulator {
var UtCamInitialize v_utCamInitialize;
var UtDenmInitialize v_utDenmInitialize;
var UtPkiInitialize v_utPkiInitialize;
var UtDenmTrigger v_utDenmTrigger;
var UtDenmUpdate v_utDenmUpdate;
var UtDenmTermination v_utDenmTermination;
var UtPkiTrigger v_utPkiTrigger;
[] cfPort.receive(UtGnInitialize:?) -> value v_utGnInitialize {
log("a_process_cf_ut_command: v_utGnInitialize = ", v_utGnInitialize);
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;
cfPort.send(UtGnResults: { utGnInitializeResult := true } );
repeat;
}
log("a_process_cf_ut_command: v_utGnTrigger = ", v_utGnTrigger);
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
var GeoNetworkingPdu v_geoNwPdu := valueof(
m_geoNwPdu(
v_geoNwUnicastPacket,
m_lifetimeBase1s(v_utGnTrigger.geoUnicast.lifetime / 1000),
v_geoNwPdu.gnPacket.packet.commonHeader.nextHeader := e_any;
v_geoNwPdu.gnPacket.packet.commonHeader.flags := f_isMobile();
v_geoNwPdu.gnPacket.packet.extendedHeader.geoUnicastHeader.dstPosVector.gnAddr := v_utGnTrigger.geoUnicast.gnAddress;
vc_rsuMessagesValueList[vc_rsu_id].beacon := v_geoNwPdu;
cfPort.send(UtGnResults: { utGnTriggerResult := true } );
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
} 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
));
v_geoNwBroadcastPacket.commonHeader.flags := f_isMobile();
v_geoNwPdu := valueof(
m_geoNwPdu(
v_geoNwBroadcastPacket,
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
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),
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
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 } );
[vc_cam == true] cfPort.receive(UtCamInitialize:?) -> value v_utCamInitialize {
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));
}
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;
[vc_cam == true] cfPort.receive(UtCamTrigger: { changeSpeed := ? }) -> value v_utCamTrigger {
log("a_process_cf_ut_command: v_utCamTrigger = ", v_utCamTrigger);
cfPort.send(UtCamResults: { utCamTriggerResult := true } );
vc_cam_timer_value := vc_cam_timer_value / 2.0;
repeat;
}
[vc_cam == true] cfPort.receive(UtCamTrigger: { changeCurvature := ? }) -> value v_utCamTrigger {
log("a_process_cf_ut_command: v_utCamTrigger = ", v_utCamTrigger);
if (ischosen(vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.highFrequencyContainer.basicVehicleContainerHighFrequency)) {
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 } );
}
[vc_cam == true] cfPort.receive(UtCamTrigger: { changeHeading := ? }) -> value v_utCamTrigger {
log("a_process_cf_ut_command: v_utCamTrigger = ", v_utCamTrigger);
if (ischosen(vc_rsuMessagesValueList[vc_rsu_id].cam.cam.camParameters.highFrequencyContainer.basicVehicleContainerHighFrequency)) {
cfPort.send(UtCamResults: { utCamTriggerResult := true } );
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;
} else {
cfPort.send(UtCamResults: { utCamTriggerResult := false } );
}
repeat;
}
[vc_cam == true] cfPort.receive(UtCamTrigger: { setVehicleRole := ? }) -> value v_utCamTrigger {
log("a_process_cf_ut_command: v_utCamTrigger = ", v_utCamTrigger);
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 } };
cfPort.send(UtCamResults: { utCamTriggerResult := true } );
repeat;
}
[] cfPort.receive(UtDenmInitialize:?) -> value v_utDenmInitialize {
log("a_process_cf_ut_command: v_utDenmInitialize = ", v_utDenmInitialize);
vc_rsuMessagesValueList[vc_rsu_id].denms := {};
vc_denmEventCounter := 0;
vc_denm := true;
cfPort.send(UtDenmResults: { utDenmInitializeResult := true } );
repeat;
[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();
log("a_process_cf_ut_command: v_utDenmTrigger: ", v_utDenmTrigger);
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
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
)));
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]);
//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;
log("a_process_cf_ut_command: v_utDenmUpdate = ", v_utDenmUpdate);
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
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;
log("a_process_cf_ut_command: v_utDenmTermination: ", v_utDenmTermination);
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) {
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));
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 {
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 {
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,
repeat;
}
[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
// 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_enrolment_request_await_response");
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
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);
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) {
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
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_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 ***");
}
}
}
log("*** " & testcasename() & ": INCONC: Expected message not received ***");
}
} // End of 'alt' statement
log("<<< f_trigger_authorization_request_await_response");*/
} // End of module ItsRSUsSimulator_Functions