LibItsDenm_Functions.ttcn 19.6 KB
Newer Older
 *    @author     ETSI / STF449
 *  @version     $URL$
 *                $Id$
 *    @desc        Module containing functions for DENM
module LibItsDenm_Functions {
    // LibCommon
    import from LibCommon_Sync all;
    import from LibCommon_VerdictControl all;
    import from LibCommon_Time { modulepar PX_TNOAC ; function f_sleep };
    
    // LibItsCommon
    import from LibItsCommon_Templates all;
    import from LibItsCommon_TypesAndValues all;
    import from LibItsCommon_Functions all;
    import from LibItsCommon_Pixits all;
reinaortega's avatar
reinaortega committed
    import from LibItsDenm_TestSystem all;
tepelmann's avatar
tepelmann committed
    import from LibItsDenm_TypesAndValues all; 
    import from LibItsDenm_Templates all; 
    import from ITS_Container language "ASN.1:1997" all;
tepelmann's avatar
tepelmann committed
    import from DENM_PDU_Descriptions language "ASN.1:1997" all;
reinaortega's avatar
reinaortega committed
    group utFuntions { 
            
        /**
         * @desc    Requests to bring the IUT in an initial state
         * @param   p_init The initialisation to trigger.
         */
        function f_utInitializeIut(template (value) UtInitialize p_init) runs on ItsDenm {
            
            utPort.send(p_init);
            tc_wait.start;
            alt {
tepelmann's avatar
tepelmann committed
                [] utPort.receive(UtInitializeResult:true) {
reinaortega's avatar
reinaortega committed
                    tc_wait.stop;
                    log("*** " & testcasename() & ": INFO: IUT initialized ***");
reinaortega's avatar
reinaortega committed
                }
                [] a_utDefault() {
                  //empty on purpose
                }
berge's avatar
berge committed
                [] tc_wait.timeout {
                    log("*** " & testcasename() & ": INFO: Could not receive expected UT message from IUT in time ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
                }
                [else] { // Shortcut defaults
//                    //f_sleep(0.050); // 50 ms
                    repeat; 
                }
berge's avatar
berge committed
            }            
reinaortega's avatar
reinaortega committed
        }
        
        /**
         * @desc    Requests to change the IUT with a new pseudonym
         * @param   p_change The change to trigger.
         */
        function f_utChangePseudonym ( template (value) UtChangePseudonym p_change ) runs on ItsDenm {
            
            utPort.send(p_change);
            tc_wait.start;
            alt {
                [] utPort.receive(UtChangePseudonymResult:true) {
                    tc_wait.stop;
                    log("*** " & testcasename() & ": INFO: IUT pseudonym changed ***");
                }
                [] utPort.receive(UtChangePseudonymResult:false) {
                    tc_wait.stop;
                    log("*** " & testcasename() & ": INFO: IUT pseudonym changed ***");
                    f_selfOrClientSyncAndVerdict("error", e_error);
                }
                [] a_utDefault() {
                  //empty on purpose
                }
                [] tc_wait.timeout {
                    log("*** " & testcasename() & ": INFO: Could not receive expected UT message from IUT in time ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
                }
                [else] { // Shortcut defaults
//                    //f_sleep(0.050); // 50 ms
                    repeat; 
                }
            }
            
reinaortega's avatar
reinaortega committed
        /**
tepelmann's avatar
tepelmann committed
         * @desc    Triggers an event from the application layer
reinaortega's avatar
reinaortega committed
         * @param   p_event The event to trigger.
         */
        function f_utTriggerEvent(template (value) UtDenmTrigger p_event) runs on ItsDenm return ActionID {
tepelmann's avatar
tepelmann committed
            var ActionID v_actionId;
tepelmann's avatar
tepelmann committed
            var UtDenmTriggerResult v_result;
reinaortega's avatar
reinaortega committed
            
tepelmann's avatar
tepelmann committed
            utPort.send(p_event);
berge's avatar
berge committed
            tc_wait.start;
reinaortega's avatar
reinaortega committed
            alt {
tepelmann's avatar
tepelmann committed
                [] utPort.receive(UtDenmTriggerResult:?) -> value v_result {
reinaortega's avatar
reinaortega committed
                    tc_wait.stop;
tepelmann's avatar
tepelmann committed
                    v_actionId := v_result.actionId;
                    if ( not v_result.result ) {
                        f_selfOrClientSyncAndVerdict("DENM Trigger failed", e_error);
garciay's avatar
garciay committed
                    }
                }
                [] a_utDefault() {
                  //empty on purpose
                }
                [] tc_wait.timeout {
                    log("*** " & testcasename() & ": INFO: Could not receive expected UT message from IUT in time ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
berge's avatar
berge committed
                }
                [else] { // Shortcut defaults
//                    //f_sleep(0.050); // 50 ms
                    repeat; 
reinaortega's avatar
reinaortega committed
                }
            }
tepelmann's avatar
tepelmann committed
            
            return v_actionId;
tepelmann's avatar
tepelmann committed
         * @desc    Updates an event at the application layer
         * @param   p_event The event to update.
reinaortega's avatar
reinaortega committed
         */
        function f_utUpdateEvent(template (value) UtDenmUpdate p_event) runs on ItsDenm return ActionID {
tepelmann's avatar
tepelmann committed
            var ActionID v_actionId;
            var UtDenmUpdateResult v_result;
reinaortega's avatar
reinaortega committed
            
tepelmann's avatar
tepelmann committed
            utPort.send(p_event);
berge's avatar
berge committed
            tc_wait.start;
reinaortega's avatar
reinaortega committed
            alt {
tepelmann's avatar
tepelmann committed
                [] utPort.receive(UtDenmUpdateResult:?) -> value v_result {
reinaortega's avatar
reinaortega committed
                    tc_wait.stop;
tepelmann's avatar
tepelmann committed
                    v_actionId := v_result.actionId;
reinaortega's avatar
reinaortega committed
                }
                [] a_utDefault() {
                  //empty on purpose
                }
berge's avatar
berge committed
                [] tc_wait.timeout {
                    log("*** " & testcasename() & ": INFO: Could not receive expected UT message from IUT in time ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
                }
                [else] { // Shortcut defaults
//                    //f_sleep(0.050); // 50 ms
                    repeat; 
                }
tepelmann's avatar
tepelmann committed
            }
            
            return v_actionId;
        }
        
        /**
         * @desc    Terminates an event at the application layer
         * @param   p_event The event to terminate.
         */
        function f_utTerminateEvent(template (value) UtDenmTermination p_event) runs on ItsDenm {
tepelmann's avatar
tepelmann committed
            
            utPort.send(p_event);
berge's avatar
berge committed
            tc_wait.start;
tepelmann's avatar
tepelmann committed
            alt {
                [] utPort.receive(UtDenmTerminationResult:?) {
reinaortega's avatar
reinaortega committed
                    tc_wait.stop;
                }
berge's avatar
berge committed
                [] tc_wait.timeout {
                    log("*** " & testcasename() & ": INFO: Could not receive expected UT message from IUT in time ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
                }
                [] a_utDefault() {
                  //empty on purpose
                }
                [else] { // Shortcut defaults
//                    //f_sleep(0.050); // 50 ms
                    repeat; 
                }
reinaortega's avatar
reinaortega committed
            }
        }
berge's avatar
berge committed
        /**
         * @desc    Changes the position of the IUT
         * @param   p_latitude
         * @param   p_longitude
         * @param   p_elevation 
         */
        function f_utChangePosition(template (value) UtChangePosition p_position) runs on ItsDenm {
            
            utPort.send(p_position);
berge's avatar
berge committed
            alt {
                [] utPort.receive(UtChangePositionResult:?) {
                    tc_wait.stop;
                }
berge's avatar
berge committed
                [] tc_wait.timeout {
                    log("*** " & testcasename() & ": INFO: Could not receive expected UT message from IUT in time ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
                }
                [] a_utDefault() {
                  //empty on purpose
                }
                [else] { // Shortcut defaults
//                    //f_sleep(0.050); // 50 ms
                    repeat; 
                }
reinaortega's avatar
reinaortega committed
    } // End of group utFunctions
tepelmann's avatar
tepelmann committed

    group adapterControl {
        
        /**
         * @desc    Triggers event in the test system adaptation.
         * @param   p_event The event to trigger
         * @return  FncRetCode
         */
        function f_acTriggerSecEvent(template (value) AcSecPrimitive p_event) runs on ItsDenm return FncRetCode {
            var FncRetCode v_ret := e_success;
            
            acPort.send(p_event);
            tc_ac.start;
            alt {
                [] acPort.receive(m_acSecResponseSuccess) {
                    tc_ac.stop;
                }
                [] acPort.receive {
                    tc_ac.stop;
                    log("*** " & __SCOPE__ & ": ERROR: Received unexpected message ***");
                    f_selfOrClientSyncAndVerdict("error", e_error);
                }
                [] tc_ac.timeout {
                    log("*** " & __SCOPE__ & ": ERROR: Timeout while waiting for adapter control event result ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
                }
            }
            
            return v_ret;
        }
        
        /**
         * @desc    Triggers event in the test system adaptation.
         * @param   p_event The event to trigger
         * @return  FncRetCode
         */
        function f_acTriggerGnssEvent(template (value) AcGnssPrimitive p_event) runs on ItsDenm return FncRetCode {
            var FncRetCode v_ret := e_success;
            
            acPort.send(p_event);
            tc_ac.start;
            alt {
                [] acPort.receive(m_acGnssResponseSuccess) {
                    tc_ac.stop;
                }
                [] acPort.receive {
                    tc_ac.stop;
                    log("*** " & __SCOPE__ & ": ERROR: Received unexpected message ***");
                    f_selfOrClientSyncAndVerdict("error", e_error);
                }
                [] tc_ac.timeout {
                    log("*** " & __SCOPE__ & ": ERROR: Timeout while waiting for adapter control event result ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
                }
            }
            
            return v_ret;
        }
        
        /**
         * @desc    Loads the given scenario
         * 
         * @param   p_scenario   The scenario to load.
         */
        function f_acLoadScenario(Scenario p_scenario) runs on ItsDenm {
            
            if (PICS_GNSS_SCENARIO_SUPPORT==true) {
                f_acTriggerGnssEvent(m_loadScenario(p_scenario));
            }
        } // end f_acLoadScenario
        
        /**
         * @desc    Starts a loaded scenario
         */
        function f_acStartScenario() runs on ItsDenm {
            
            if (PICS_GNSS_SCENARIO_SUPPORT==true) {
                f_acTriggerGnssEvent(m_startScenario);
                vc_scenarioStarted := true;
            }
        } // end f_acStartScenario
        
        /**
         * @desc    Stops a loaded scenario
         */
        function f_acStopScenario() runs on ItsDenm {
            
            if (PICS_GNSS_SCENARIO_SUPPORT==true and vc_scenarioStarted==true) {
                f_acTriggerGnssEvent(m_stopScenario);
                vc_scenarioStarted := false;
            }
        } // end f_acStopScenario
        
        function f_acAwaitDistanceCovered(float p_distanceToCover) runs on ItsDenm return FncRetCode {
            var FncRetCode v_ret := e_success;
            
            if (PICS_GNSS_SCENARIO_SUPPORT==true and vc_scenarioStarted==true) {
                f_acTriggerGnssEvent(m_distanceToCover(p_distanceToCover));
                
                tc_ac.start;
                alt {
                    [] acPort.receive(m_acGnssDistanceCovered) {
                        tc_ac.stop;
                    }
                    [] acPort.receive {
                        tc_ac.stop;
                        log("*** " & __SCOPE__ & ": ERROR: Received unexpected message ***");
                        f_selfOrClientSyncAndVerdict("error", e_error);
                    }
                    [] tc_ac.timeout {
                        log("*** " & __SCOPE__ & ": ERROR: Timeout while waiting for covered distance indication ***");
                        f_selfOrClientSyncAndVerdict("error", e_timeout);
                    }
                }
                
            }
            return v_ret;
        } // end f_acAwaitDistanceCovered
        
    } // End of group adapterControl

tepelmann's avatar
tepelmann committed
    group denmConfigurationFunctions {
berge's avatar
berge committed
        
        /**
         * @desc    Setups default configuration   
         */
        function f_cfUp() runs on ItsDenm system ItsDenmSystem {
            map(self:acPort, system:acPort);
            map(self:utPort, system:utPort);
            map(self:denmPort, system:denmPort);
            f_connect4SelfOrClientSync();
            
        } // end f_cfUp
berge's avatar
berge committed
        
        /**
         * @desc    Deletes default configuration 
         */
        function f_cfDown() runs on ItsDenm system ItsDenmSystem {
            unmap(self:acPort, system:acPort);
            unmap(self:utPort, system:utPort);
garciay's avatar
garciay committed
            unmap(self:denmPort, system:denmPort);
            f_disconnect4SelfOrClientSync();
            
        } // end f_cfDown
berge's avatar
berge committed
        
tepelmann's avatar
tepelmann committed
    } //end denmConfigurationFunctions
tepelmann's avatar
tepelmann committed
    group altsteps {
        
        /**
         * @desc The base default.
         */
reinaortega's avatar
reinaortega committed
        altstep a_default() runs on ItsDenm {
tepelmann's avatar
tepelmann committed
            [] denmPort.receive(mw_denmInd(mw_denmPdu(mw_anyDenm))) { 
                log("*** " & testcasename() & ": INFO: DENM message received in default ***");
berge's avatar
berge committed
                vc_denmReceived := true;
                repeat;
            }
tepelmann's avatar
tepelmann committed
            [] denmPort.receive {
                log("*** " & testcasename() & ": ERROR: Received an unexpected message ***");
berge's avatar
berge committed
                f_selfOrClientSyncAndVerdict("error", e_error);
tepelmann's avatar
tepelmann committed
            }
            [] tc_wait.timeout {
                log("*** " & testcasename() & ": INCONC: Timeout while awaiting reaction of the IUT prior to Upper Tester action ***");
berge's avatar
berge committed
                f_selfOrClientSyncAndVerdict("error", e_timeout);
tepelmann's avatar
tepelmann committed
            }
            [] tc_ac.timeout {
                log("*** " & testcasename() & ": INCONC: Timeout while awaiting the reception of a message ***");
berge's avatar
berge committed
                f_selfOrClientSyncAndVerdict("error", e_timeout);
tepelmann's avatar
tepelmann committed
            }
tepelmann's avatar
tepelmann committed
            [] a_shutdown() {
                f_poDefault();
                f_cfDown();
                log("*** " & testcasename() & ": INFO: TEST COMPONENT NOW STOPPING ITSELF! ***");
tepelmann's avatar
tepelmann committed
         * @desc The default for handling upper tester messages.
tepelmann's avatar
tepelmann committed
         */
        altstep a_utDefault() runs on ItsDenm {
            var UtDenmEventInd v_event;
            [] utPort.receive(UtDenmEventInd:?) -> value v_event {
tepelmann's avatar
tepelmann committed
                //store every upper tester indication received
                vc_utEvents[lengthof(vc_utEvents)] := v_event;
tepelmann's avatar
tepelmann committed
                repeat;
            }
            [] utPort.receive {
                log("*** " & testcasename() & ": INFO: Received unhandled/unknown UT message from IUT ***");
                repeat;
tepelmann's avatar
tepelmann committed
    } // end group altsteps
    
    group preambles {
        
        /**
         * @desc The default preamble.
         */
reinaortega's avatar
reinaortega committed
        function f_prDefault() runs on ItsDenm {
tepelmann's avatar
tepelmann committed
            vc_default := activate(a_default());
berge's avatar
berge committed
            activate(a_utDefault());
tepelmann's avatar
tepelmann committed
        }
        
        /**
         * @desc Brings the IUT into an initial state.
         * @return FncRetCode 
tepelmann's avatar
tepelmann committed
         */
        function f_prInitialState(
                                  in Scenario p_scenario := e_staticPosition,
                                  in template (value) UtInitialize p_denmInitialize := m_denmInitialize
        ) runs on ItsDenm return FncRetCode {
tepelmann's avatar
tepelmann committed
            var FncRetCode v_ret := e_success;
            
            f_utInitializeIut(p_denmInitialize);
            f_acLoadScenario(valueof(p_scenario));
            f_acStartScenario();
            
tepelmann's avatar
tepelmann committed
            f_prDefault();
tepelmann's avatar
tepelmann committed
            
            return v_ret;
        }
        
    } // end group preambles
    
    group postambles {
        
        /**
         * @desc The default postamble.
         */
reinaortega's avatar
reinaortega committed
        function f_poDefault() runs on ItsDenm {
tepelmann's avatar
tepelmann committed
            var FncRetCode v_ret := e_success;
            f_acStopScenario();
tepelmann's avatar
tepelmann committed
        }
        
        /**
         * @desc Postamble including cancellation of an event.
         * @param p_trigger Indicates if the cancellation have to be raised by the test system(e_ets) 
         *                  or at the application layer of the IUT(e_iut).
         * @param p_actionId The action ID of the event to be cancelled
tepelmann's avatar
tepelmann committed
         */
tepelmann's avatar
tepelmann committed
        function f_poCancelEvent(template (value) Trigger p_trigger, template (value) ActionID p_actionId) 
reinaortega's avatar
reinaortega committed
        runs on ItsDenm {
tepelmann's avatar
tepelmann committed
            var FncRetCode v_ret := e_success;
            
berge's avatar
berge committed
            if (valueof(p_trigger) == e_ets) {
                f_sendDenMessage( m_denmCancellation ( p_actionId , f_getTsStationType( ) ) );
garciay's avatar
garciay committed
                f_sleep(PX_TNOAC);
tepelmann's avatar
tepelmann committed
            }
            else {
tepelmann's avatar
tepelmann committed
                f_utTerminateEvent(m_utEventCancellation(p_actionId));
tepelmann's avatar
tepelmann committed
            }
            
            f_poDefault();
        }
        
    } // end group postambles
    
    group sendFunctions {
        
        /**
         * @desc Sends a DEN message
         * @param p_sendMsg The DEN message to send.
         * @param p_overrideSeqNo Overrides the sequence number with the stored one. 
tepelmann's avatar
tepelmann committed
         */
        function f_sendDenMessage(template (value) DecentralizedEnvironmentalNotificationMessage p_denm, boolean p_overrideSeqNo := true) runs on ItsDenm return ActionID {
berge's avatar
berge committed

            if (p_overrideSeqNo) {
                p_denm.management.actionID.sequenceNumber := vc_sequenceNo;
            }
berge's avatar
berge committed

            denmPort.send(
                m_denmReq(
                    m_denmPdu(
                        p_denm
                    )
                )
            );
berge's avatar
berge committed
                        
garciay's avatar
garciay committed
            return valueof(p_denm.management).actionID;
tepelmann's avatar
tepelmann committed
        }
        
    } // end sendFunctions
    
    group receiveFunctions {
        
        /**
         * @desc Awaits a DEN message and returns it
tepelmann's avatar
tepelmann committed
         * @param p_rcvMsg The expected message to be received.
         * @param p_rcvdMsg The received message - OUT.
         */
reinaortega's avatar
reinaortega committed
        function f_awaitDenMessage(in template (present) DenmInd p_rcvMsg, out DenmInd p_rcvdMsg) runs on ItsDenm {
tepelmann's avatar
tepelmann committed
            
berge's avatar
berge committed
            tc_ac.start;
tepelmann's avatar
tepelmann committed
            alt {
                [] denmPort.receive(p_rcvMsg) -> value p_rcvdMsg {
berge's avatar
berge committed
                    tc_ac.stop;
tepelmann's avatar
tepelmann committed
                }
berge's avatar
berge committed
                [] tc_ac.timeout {
                    log("*** " & testcasename() & ": INFO: Timeout while awaiting the reception of a message ***");
berge's avatar
berge committed
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
tepelmann's avatar
tepelmann committed
        }
        
    } // end receiveFunctions
    
tepelmann's avatar
tepelmann committed
    group miscellaneousFunctions {
        
tepelmann's avatar
tepelmann committed
        /**
         * @desc Increases the sequence number and handles the special case where the 
garciay's avatar
garciay committed
         *       sequence number reaches the limit of 65535 and will be reset to 0.
         * @param p_sequenceNumber The sequence number to increase.
         * @return The increased sequence number.
tepelmann's avatar
tepelmann committed
        function f_increaseSequenceNumber(in SequenceNumber p_sequenceNumber) return SequenceNumber {
            // if maximum number of 65535 reached, reset it to 0
            return ((p_sequenceNumber + 1) mod 65536);
        }
        
    } // end group miscellaneousFunctions
    
} // end LibItsDenm_Functions