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 EtsiTs103097Module language "ASN.1:1997" all;
// LibItsCommon
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;
// 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
/**
* @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
f_initialiseSecuredMode();
} // End of function f_cf01Up
function f_cf01Down() runs on ItsRSUsSimulator {
vc_rsuMessagesValueList := {};
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) octetstring 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;
vc_longPosVectorRsu := PICS_RSU_PARAMS[p_rsu_id].longPosVector;
// 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) and (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[p_rsu_id][PX_ETSI_ZONE_ID - 1]); v_counter := v_counter + 1) {
var DenmEventsParmsPerZone v_denmEventsParmsPerZone := PICS_DENM_EVENTS_RSU[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[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[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
// 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 == 9) {
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 := 'AAAAAAAA'O; // TODO Use a PICS
}
// Build the messages value list for this RSU
vc_rsuMessagesValueList[p_rsu_id] :=
m_rsuProfile(
v_cam,
v_denms,
v_mapem,
v_spatems,
v_ivim,
//log("vc_rsuMessagesValueList[p_rsu_id] = ", vc_rsuMessagesValueList[p_rsu_id]);
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;
}
} // 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
function f_prepare_beacon(
out template (value) GnRawPayload p_payload
) runs on ItsRSUsSimulator {
p_payload := valueof(
f_adaptPayload(
vc_rsuMessagesValueList[vc_rsu_id].beacon,
0,
-,
e_any
)
log("f_prepare_beacon: ", p_payload);
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 {
v_geoNetworkingPdu := valueof(m_geoNwPdu( // FIXME Use PIXIT parameter to get a fully configurable template
m_geoNwBroadcastPacket_payload( // TODO modifes 'template (value) GnNonSecuredPacket m_geoNwBroadcastPacket' to set the field
vc_longPosVectorRsu,
f_incLocalSeqNumber(),
f_geoArea2GeoBroadcastArea(vc_geoArea),
-,
-,
valueof(p_payload)
),
Lifetime:{
multiplier := c_defaultLifetime,
ltBase := e_100s
},
v_geoNetworkingPdu.gnPacket.packet.commonHeader.nextHeader := e_any;
f_sendGeoNetMessage(valueof(m_geoNwReq_linkLayerBroadcast(v_geoNetworkingPdu, p_its_aid)));
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 {
function f_payload_template(
in integer p_dest_port,
in integer p_src_port
) return template (present) octetstring {
var template (present) Oct2 v_t1 := int2oct(PICS_SREM_BTP_DESTINATION_PORT, 2);
var template (present) Oct2 v_t2 := int2oct(PICS_SREM_BTP_SOURCE_PORT, 2);
var template (present) octetstring v_t3 := ? length (5 .. 65535);
var template (present) octetstring v_out := v_t1 & v_t2 & v_t3;
altstep a_process_cf_ut_command() runs on ItsRSUsSimulator {
[] cfPort.receive(UtGnInitialize:?) -> value v_utGnInitialize {
log("v_utGnInitialize = ", v_utGnInitialize);
cfPort.send(UtGnResults: { utGnInitializeResult := true } );
repeat;
}
[] cfPort.receive(UtGnTrigger:?) -> value v_utGnTrigger {
log("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),
c_defaultHopLimit
)
);
// FIXME Check what to do with GN_Address v_geoNwPdu.gnPacket.packet.extendedHeader.geoUnicastHeader. := v_utGnTrigger.geoUnicast.gnAddress;
geoNetworkingPort.send(m_geoNwReq_linkLayerBroadcast(v_geoNwPdu));
}
cfPort.send(UtGnResults: { utGnTriggerResult := true } );
repeat;
}
[vc_cam == true] cfPort.receive(UtCamInitialize:?) {
cfPort.send(UtCamResults: { utCamInitializeResult := true } );
repeat;
[vc_cam == true] cfPort.receive(UtCamTrigger: { changeSpeed := ? }) {
cfPort.send(UtCamResults: { utCamTriggerResult := true } );
vc_cam_timer_value := vc_cam_timer_value / 4.0;
repeat;
}
[vc_denm == true] cfPort.receive(UtDenmInitialize:?) {
cfPort.send(UtDenmResults: { utDenmInitializeResult := true } );
repeat;
[vc_denm == true] cfPort.receive(UtDenmInitialize:?) {
cfPort.send(UtDenmResults: { utDenmInitializeResult := true });
[] cfPort.receive {
// Ignore it
log("*** " & testcasename() & ": INFO: Unexpected CF message received ***");
repeat;
}
} // End of 'altstep' statement
} // End of module ItsRSUsSimulator_Functions