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 RTCMEM_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_ASN1_ISDSRC_NamedNumbers all;
// LibItsBtp
import from LibItsBtp_TypesAndValues all;
import from LibItsBtp_Templates all;
import from LibItsCam_TypesAndValues all;
import from LibItsDenm_TypesAndValues all;
import from LibItsIvim_TypesAndValues all;
import from LibItsIvim_Templates all;
// LibItsMapemSpatemm
import from LibItsMapemSpatem_TypesAndValues all;
import from LibItsMapemSpatem_Templates all;
// LibItsSremSsem
import from LibItsSremSsem_TypesAndValues all;
import from LibItsSremSsem_Templates all;
// LibItsRtcmem
import from LibItsRtcmem_TypesAndValues all;
import from LibItsRtcmem_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
// 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;
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_
),
PICS_IVIM_PARMS_RSUs[p_rsu_id].iviContainers
));
// Update ivi status
v_ivim.ivi.mandatory.validFrom := f_getCurrentTime();
v_ivim.ivi.mandatory.validTo := valueof(v_ivim.ivi.mandatory.validFrom) + 43200000; // 12hours
// RTCMEM
if (vc_rtcmem == true) {
// Build the list of the RTCMEM events
v_rtcmem :=
m_rtcmemParm(
PICS_RSU_PARAMS[p_rsu_id].stationID,
m_defaultRtcmem(
123,
-,
/* // 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
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
} 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,
);
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_rtcmem(
out template (value) GnRawPayload p_payload
) runs on ItsRSUsSimulator {
p_payload := valueof(
f_adaptPayload(
bit2oct(
encvalue(
valueof(
vc_rsuMessagesValueList[vc_rsu_id].rtcmem
))),
PICS_RTCMEM_BTP_DESTINATION_PORT,
PICS_RTCMEM_BTP_SOURCE_PORT
)
);
} // End of function f_prepare_rtcmem
function f_prepare_srem(
out template (value) GnRawPayload p_payload
) runs on ItsRSUsSimulator {
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
log("f_prepare_srem: vc_sremEventCounter = ", vc_sremEventCounter);
p_payload := valueof(
f_adaptPayload(
bit2oct(
encvalue(
valueof(
vc_rsuMessagesValueList[vc_rsu_id].srems[vc_sremEventCounter]
))),
PICS_SREM_BTP_DESTINATION_PORT,
PICS_SREM_BTP_SOURCE_PORT
)
);
if (valueof(vc_rsuMessagesValueList[vc_rsu_id].srems[vc_sremEventCounter].srm.requests[0].request.requestType) == priorityCancellation) {
log("f_prepare_srem: Remove item: ", vc_rsuMessagesValueList[vc_rsu_id].srems);
if (lengthof(vc_rsuMessagesValueList[vc_rsu_id].srems) == 1) {
log("f_prepare_srem: Remove last item");
vc_rsuMessagesValueList[vc_rsu_id].srems := {};
vc_sremEventCounter := 0;
vc_srem := false;
} else {
if (vc_sremEventCounter == 0) {
vc_rsuMessagesValueList[vc_rsu_id].srems := substr(vc_rsuMessagesValueList[vc_rsu_id].srems, 1, lengthof(vc_rsuMessagesValueList[vc_rsu_id].srems) - 1);
} else {
var SREMs v_l;
v_l := substr(vc_rsuMessagesValueList[vc_rsu_id].srems, 0, vc_sremEventCounter) & substr(vc_rsuMessagesValueList[vc_rsu_id].srems, vc_sremEventCounter + 1, lengthof(vc_rsuMessagesValueList[vc_rsu_id].srems) - vc_sremEventCounter - 1);
vc_rsuMessagesValueList[vc_rsu_id].srems := v_l;
}
log("f_prepare_srem: After removing: ", vc_rsuMessagesValueList[vc_rsu_id].srems);
vc_sremEventCounter := (vc_sremEventCounter + 1) mod lengthof(vc_rsuMessagesValueList[vc_rsu_id].srems);
}
} else {
vc_sremEventCounter := (vc_sremEventCounter + 1) mod lengthof(vc_rsuMessagesValueList[vc_rsu_id].srems);
}
function f_prepare_ssem(
out template (value) GnRawPayload p_payload
) runs on ItsRSUsSimulator {
log("f_prepare_ssem: vc_ssemEventCounter = ", vc_ssemEventCounter);
p_payload := valueof(
f_adaptPayload(
bit2oct(
encvalue(
valueof(
vc_rsuMessagesValueList[vc_rsu_id].ssems[vc_ssemEventCounter]
))),
PICS_SSEM_BTP_DESTINATION_PORT,
PICS_SSEM_BTP_SOURCE_PORT
)
);
vc_ssemEventCounter := (vc_ssemEventCounter + 1) mod lengthof(vc_rsuMessagesValueList[vc_rsu_id].ssems);
} // End of function f_prepare_ssem
/* 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
f_incLocalSeqNumber(),
f_geoArea2GeoBroadcastArea(vc_geoArea),
-, -,
valueof(p_payload)
),
Lifetime:{
multiplier := c_defaultLifetime,
ltBase := e_100s
},
c_hopLimit1
));
} else if (p_its_aid == 139) { // IVIM
v_geoNetworkingPdu := valueof(m_geoNwPdu( // FIXME Use PIXIT parameter to get a fully configurable template
f_geoArea2GeoBroadcastArea(vc_geoArea),
valueof(p_payload)
),
Lifetime:{
multiplier := c_defaultLifetime,
ltBase := e_100s
},
c_hopLimit1
));
} else if (p_its_aid == 140) { // SxEM
v_geoNetworkingPdu := valueof(m_geoNwPdu( // FIXME Use PIXIT parameter to get a fully configurable template
f_incLocalSeqNumber(),
f_geoArea2GeoBroadcastArea(vc_geoArea),
-, -,