Skip to content
ItsRSUsSimulator_Functions.ttcn 18.9 KiB
Newer Older
garciay's avatar
garciay committed
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 SREM_PDU_Descriptions language "ASN.1:1997" all;
    import from SSEM_PDU_Descriptions language "ASN.1:1997" all;
garciay's avatar
garciay committed
    import from DSRC language "ASN.1:1997" all;
garciay's avatar
garciay committed
    
    // LibItsCommon
    import from LibItsCommon_Functions all;
    
    // LibItsBtp
    import from LibItsBtp_TypesAndValues all;
    import from LibItsBtp_Templates all;
    
    // LibItsDenm
    import from LibItsDenm_Templates all;
    
garciay's avatar
garciay committed
    // LibItsMapemSpatemm
    import from LibItsMapemSpatem_Templates all;
    
    // LibItsMapemSpatemm
    import from LibItsIvim_Templates all;
    
    // LibItsMapemSpatemm
    import from LibItsSremSsem_Templates all;
    
garciay's avatar
garciay committed
    // 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;
    
    // AtsRSUsSimulator
    import from ItsRSUsSimulator_TypesAndValues all;
    import from ItsRSUsSimulator_TestSystem all;
    import from ItsRSUsSimulator_Templates all;
    import from ItsRSUsSimulator_Pics all;
    import from ItsRSUsSimulator_Pixits all;
    
    group geoConfigurationFunctions {
        
        /**
         * @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
            var template (value) DenmParmContainers v_denmParmContainers;
            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) SSEM v_ssem := omit;
garciay's avatar
garciay committed
            var integer v_counter;
            
            // Map
            map(self:acPort, system:acPort);
            map(self:utPort, system:utPort);
            map(self:geoNetworkingPort, system:geoNetworkingPort);
            
            // Connect
            f_connect4SelfOrClientSync();
            activate(a_cf01Down());
            
            // Initialise secured mode
            f_initialiseSecuredMode();
            
            //Initialze the IUT
//            f_initialState();
garciay's avatar
garciay committed
            
            // Initialisations
            vc_longPosVectorRsu := PICS_RSU_PARAMS[PX_RSU_ID - 1].longPosVector;
garciay's avatar
garciay committed
            // MAPEM
            if (PICS_GENERATE_MAPEM) {
                // Build the list of the MAPEM events
                v_mapem := 
                    m_mapemParm(
                        PICS_RSU_PARAMS[PX_RSU_ID - 1].stationID,
                        m_mapem(
                            f_getMsgIssueRevision(),
                            PICS_MAPEM_PARMS_RSUs[PX_RSU_ID - 1].intersections,
                            PICS_MAPEM_PARMS_RSUs[PX_RSU_ID - 1].roadSegments
                ));
                // Update revision fields
                v_mapem.map_.intersections[0].revision := f_incMsgIssueRevision();
                // TODO Add more?
            }
            // SPATEM
            if (PICS_GENERATE_SPATEM) {
                // Build the list of the DENM events
                for (v_counter := 0; v_counter < lengthof(PICS_SPATEM_PARMS_RSUs[PX_RSU_ID - 1]); v_counter := v_counter + 1) {
                    v_spatems[v_counter] := 
                        m_spatemParm(
                            PICS_RSU_PARAMS[PX_RSU_ID - 1].stationID,
                            m_spatem(
                                PICS_SPATEM_PARMS_RSUs[PX_RSU_ID - 1][v_counter].intersections,
                                "SignalGroupID #" & int2str(PICS_SPATEM_PARMS_RSUs[PX_RSU_ID - 1][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
garciay's avatar
garciay committed
            }
            // IVIM
            if (PICS_GENERATE_IVIM) {
                // Build the list of the MAPEM events
                v_ivim := 
                    m_ivimParm(
                        PICS_RSU_PARAMS[PX_RSU_ID - 1].stationID,
                        m_ivimStructure(
                            m_iviManagementContainer(
                                PICS_IVIM_PARMS_RSUs[PX_RSU_ID - 1].provider,
                                PICS_IVIM_PARMS_RSUs[PX_RSU_ID - 1].iviIdentificationNumber,
                                0//IviStatus_new_
                )));
                // Update ivi status
                v_ivim.ivi.mandatory.validFrom := f_getCurrentTime();
                // TODO Add more?
garciay's avatar
garciay committed
            }
            // DENM
            if (PICS_GENERATE_DENM) {
                // Build the list of the DENM events
                for (v_counter := 0; v_counter < lengthof(PICS_DENM_EVENTS_RSU[PX_RSU_ID - 1][PX_ETSI_ZONE_ID]); v_counter := v_counter + 1) {
                    var DenmEventsParmsPerZone v_denmEventsParmsPerZone := PICS_DENM_EVENTS_RSU[PX_RSU_ID - 1][PX_ETSI_ZONE_ID];
                    
                    v_denmParmContainers := m_denmParmContainers(
                        PICS_RSU_PARAMS[PX_RSU_ID - 1].stationID,
garciay's avatar
garciay committed
                        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
                    );
                    v_denms[v_counter] := valueof(
garciay's avatar
garciay committed
                        m_denmPdu(
                            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
garciay's avatar
garciay committed
            // CAM
            if (PICS_GENERATE_CAM) {
                // Build the list of the CAM events
                v_cam := 
                    m_camParm(
                        PICS_RSU_PARAMS[PX_RSU_ID - 1].stationID,
                        m_rsuPosition(
                            vc_longPosVectorRsu.latitude,
                            vc_longPosVectorRsu.longitude
                        ), 
                        PICS_RSU_PARAMS[PX_RSU_ID - 1].pathHistory
garciay's avatar
garciay committed
                );
garciay's avatar
garciay committed
            // Build the messages value list for this RSU
            vc_rsuMessagesValueList[PX_RSU_ID - 1] := 
garciay's avatar
garciay committed
                m_rsuProfile(
                    v_cam, 
                    v_mapem,
garciay's avatar
garciay committed
            if (PICS_RSU_PARAMS[PX_RSU_ID - 1].geoShape == e_geoCircle) {
                vc_geoArea := f_computeCircularArea(vc_longPosVectorRsu, PICS_RSU_PARAMS[PX_RSU_ID - 1].geoParms.radius);
            } else {
                log("*** " & testcasename() & ": INCONC: Wrong PICS_RSU_GEOAREA_FORM event initialisation ***");
                setverdict(inconc);
                stop;
            }
            
        } // End of function f_cf01Up
        
        function f_cf01Down() runs on ItsRSUsSimulator {
            
            vc_longPosVectorRsu := {};
            vc_geoArea := {};
            vc_rsuMessagesValueList := {};
            
garciay's avatar
garciay committed
            f_uninitialiseSecuredMode();
            
            // Unmap
            unmap(self:acPort, system:acPort);
            unmap(self:utPort, system:utPort);
            unmap(self:geoNetworkingPort, system:geoNetworkingPort);
            
            // Disconnect
            f_disconnect4SelfOrClientSync();
            
        } // End of function f_cf01Down
        
    } // End of group geoConfigurationFunctions
    
    function f_prepare_cam(
                           out template (value) Payload p_payload
    ) runs on ItsRSUsSimulator {
        
        vc_rsuMessagesValueList[PX_RSU_ID - 1].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[PX_RSU_ID - 1].cam
                ))),
                PICS_CAM_BTP_DESTINATION_PORT,
                PICS_CAM_BTP_SOURCE_PORT
            )
        );
    }
    
    function f_prepare_denm(
                            out template (value) Payload p_payload
    ) runs on ItsRSUsSimulator {
        
        // Update dynamic parms
garciay's avatar
garciay committed
        vc_rsuMessagesValueList[PX_RSU_ID - 1].denms[vc_denmEventCounter].denm.management.referenceTime  := f_getCurrentTime();
        p_payload := valueof(
            f_adaptPayload(
                bit2oct(
                    encvalue(
                        valueof(vc_rsuMessagesValueList[PX_RSU_ID - 1].denms[vc_denmEventCounter]
                ))),
                PICS_DENM_BTP_DESTINATION_PORT,
                PICS_DENM_BTP_SOURCE_PORT
            )
        ); 
        vc_denmEventCounter := (vc_denmEventCounter + 1) mod lengthof(vc_rsuMessagesValueList[PX_RSU_ID - 1].denms);
    }
    
    function f_prepare_mapem(
                             out template (value) Payload p_payload
    ) runs on ItsRSUsSimulator {
        
garciay's avatar
garciay committed
        p_payload := valueof(
            f_adaptPayload(
                bit2oct(
                    encvalue(
                        valueof(
                            vc_rsuMessagesValueList[PX_RSU_ID - 1].mapem
                ))),
                PICS_MAPEM_BTP_DESTINATION_PORT,
                PICS_MAPEM_BTP_SOURCE_PORT
            )
        );
garciay's avatar
garciay committed
    }
    
    function f_prepare_spatem(
                              in template (value) SPATEM p_spatem,
garciay's avatar
garciay committed
                              out template (value) Payload p_payload
    ) runs on ItsRSUsSimulator {
        var template (value) SPATEM v_spatem := p_spatem; // Make a copy
        // Rebuild SPATEM message
        for (var integer v_intersection := 0; v_intersection < lengthof(v_spatem.spat.intersections); v_intersection := v_intersection + 1) {
            var template (value) MovementList v_states := vc_states[PX_RSU_ID - 1][v_intersection];
            select (vc_spatemStatesId) {
                case (0) {
                    v_spatem.spat.intersections[v_intersection].states[0] := v_states[0];
                    v_spatem.spat.intersections[v_intersection].states[1] := v_states[1];
                    v_spatem.spat.intersections[v_intersection].states[2] := v_states[2];
                }
                case (1) {
                    v_spatem.spat.intersections[v_intersection].states[0] := v_states[1];
                    v_spatem.spat.intersections[v_intersection].states[1] := v_states[2];
                    v_spatem.spat.intersections[v_intersection].states[2] := v_states[0];
                }
                case (2) {
                    v_spatem.spat.intersections[v_intersection].states[0] := v_states[2];
                    v_spatem.spat.intersections[v_intersection].states[1] := v_states[0];
                    v_spatem.spat.intersections[v_intersection].states[2] := v_states[1];
                }
                case else {
                }
            } // End of 'select' statement
        } // End of 'for' statement
        vc_spatemStatesId := (vc_spatemStatesId + 1) mod 4; // TODO To be refined
        
        p_payload := valueof(
            f_adaptPayload(
                bit2oct(
                    encvalue(
                        valueof(
                            v_spatem
                ))),
                PICS_SPATEM_BTP_DESTINATION_PORT,
                PICS_SPATEM_BTP_SOURCE_PORT
garciay's avatar
garciay committed
        
    }
    
    function f_prepare_ivim(
                            out template (value) Payload p_payload
garciay's avatar
garciay committed
    ) runs on ItsRSUsSimulator {
        
        p_payload := valueof(
            f_adaptPayload(
                bit2oct(
                    encvalue(
                        valueof(
                            vc_rsuMessagesValueList[PX_RSU_ID - 1].ivim
                ))),
                PICS_IVIM_BTP_DESTINATION_PORT,
                PICS_IVIM_BTP_SOURCE_PORT
            )
        );
garciay's avatar
garciay committed
    }
    
    function f_adaptPayload(
                            in template (value) octetstring p_finalPayload,
                            in template (value) BtpPortId  p_destPort,
                            in template (value) BtpPortId  p_srcPort := 0
    ) return template (value) Payload {
        var template (value) Payload v_payload;
        
        if(PX_GN_UPPER_LAYER == e_any) {
            v_payload := { decodedPayload := omit, rawPayload := p_finalPayload};
            return v_payload;
        }
        
        if(PX_GN_UPPER_LAYER == e_ipv6) {
            log("*** " & testcasename() & ": INCONC: Layer IPv6 not supported ***");
            setverdict(inconc);
            stop;
        }
        
        if(PX_GN_UPPER_LAYER == e_btpA) {
            v_payload := { 
                decodedPayload := { 
                    btpPacket := m_btpAWithPorts(
                        p_destPort,
                        p_srcPort,
                        { 
                            decodedPayload := omit, 
                            rawPayload := p_finalPayload 
                        }
                    )
                },
                rawPayload := ''O
            };
            return v_payload;
        }
        
        if(PX_GN_UPPER_LAYER == e_btpB) {
            v_payload := { 
                decodedPayload := { 
                    btpPacket := m_btpBWithPorts(
                        p_destPort,
                        p_srcPort,
                        { 
                            decodedPayload := omit, 
                            rawPayload := p_finalPayload 
                        }
                    )
                }, 
                rawPayload := ''O
            };
            return v_payload;
        }
        
        return v_payload;
    }
    
    function f_send(
                    in template (value) Payload p_payload
    ) runs on ItsRSUsSimulator {
        var GeoNetworkingPdu v_geoNetworkingPdu;
        
        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)
            ),
            m_defaultLifetime,
            c_defaultHopLimit
        ));
        f_sendGeoNetMessage(valueof(m_geoNwReq_linkLayerBroadcast(v_geoNetworkingPdu)));
    }
    
    function f_processSrem(
                           in GeoNetworkingPdu p_geoNetworkingPdu
    ) runs on ItsRSUsSimulator {
        log("SREM=", p_geoNetworkingPdu);
        if (ispresent(p_geoNetworkingPdu.gnPacket.packet.payload.decodedPayload)) {
            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) Payload 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
                        )
                    );
                    
                } // else, ignore message
            } // else, ignore message
        } // else, ignore message
garciay's avatar
garciay committed
        // TODO Process message, and send SSEM 
    }
    
    function f_incLocalSeqNumber() runs on ItsRSUsSimulator return UInt16 {
        vc_localSeqNumber := (vc_localSeqNumber + 1) mod 65536;
        return vc_localSeqNumber;
    }
    
garciay's avatar
garciay committed
    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;
    }
    
garciay's avatar
garciay committed
    function f_getDenmSequenceNumber() runs on ItsRSUsSimulator return SequenceNumber {
garciay's avatar
garciay committed
        return vc_sequenceNumber;
garciay's avatar
garciay committed
    }
    
} // End of module ItsRSUsSimulator_Functions