/**
 *    @author   ETSI STF517
 *    @version  $URL$
 *              $Id$
 *    @desc     SPATEM TP functions
 *
 */

module ItsSpatem_TpFunctions {
    
    // LibCommon
    import from LibCommon_BasicTypesAndValues all;
    import from LibCommon_Sync all;
    import from LibCommon_VerdictControl all;
    import from LibCommon_Time all;
    
    // LibItsCommon
    import from LibItsCommon_Functions all;
    import from LibItsCommon_TypesAndValues all;
    
    // LibIts
    import from ITS_Container 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 DSRC language "ASN.1:1997" all;
    
    // LibItsMapemSpatem
    import from LibItsMapemSpatem_TestSystem all;
    import from LibItsMapemSpatem_Functions all;
    import from LibItsMapemSpatem_Templates all;
    import from LibItsMapemSpatem_TypesAndValues all;
    import from LibItsMapemSpatem_Pics all;
    
    group spateMessageDissemination { 
        
        group spateMessageFormat { 
            
            /**
             * @desc    TP Function for TC_IS_RLT_MSGF_BV_01
             */
            function f_IS_TLM_MSGF_BV_01 () runs on ItsMapemSpatem {
                
                // Local variables
                
                // Test control
                if (not PICS_RSU_ROLE or not PICS_SPATEM_GENERATION) {
                    log("*** " & testcasename() & ": PICS_RSU_ROLE and PICS_SPATEM_GENERATION required for executing the TC ***");
                    setverdict(inconc);
                    stop;
                }
                
                // Test component configuration
                f_cfUp();
                    
                // Preamble
                f_prInitialState();
                f_utTriggerEvent(m_utTriggerEvent(startTLMService));
                // Wait for SPATEM sent
                tc_ac.start(2.0);
                f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                    
                // Test Body
                tc_ac.start;
                alt {
                    [] mapemSpatemPort.receive(
                        mw_spatemInd(
                            mw_spatemPdu
                    )) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": PASS: Successfully received SAPTEM PDU header. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                    }
                    [] tc_ac.timeout {
                        log("*** " & testcasename() & ": INCONC: Timeout while awaiting the reception of a message. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
                    }
                }
                
                // Postamble
                f_utTriggerEvent(m_utTriggerEvent(stopTLMService));
                f_poDefault();
                f_cfDown();
                
            } // End of function f_IS_TLM_MSGF_BV_01
            
        } // End of group spateMessageFormat
        
        group spateEventGeneration { 
            
            /**
             * @desc    TP Function for f_IS_TLM_EVGN_BV_01
             */
            function f_IS_TLM_EVGN_BV_01() runs on ItsMapemSpatem {
                
                // Local variables
                
                // Test control
                if (not PICS_RSU_ROLE or not PICS_SPATEM_GENERATION) {
                    log("*** " & testcasename() & ": PICS_RSU_ROLE and PICS_SPATEM_GENERATION required for executing the TC ***");
                    setverdict(inconc);
                    stop;
                }
                
                // Test component configuration
                f_cfUp();
                
                // Preamble
                f_prInitialState();
                f_utTriggerEvent(m_utTriggerEvent(startTLMService));
                f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                    
                // Test Body
                tc_ac.start;
                alt {
                    [] mapemSpatemPort.receive(
                        mw_spatemInd(
                            mw_spatemPdu(
                                mw_spatemWellFormatted
                    ))) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": PASS: Successfully received well-formed SPATEM. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                    }
                    [] mapemSpatemPort.receive(
                        mw_spatemInd(
                            mw_spatemPdu(
                                mw_defaultSpatem
                    ))) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": FAIL: Received a SPATEM with incorrect information. ***");
                        f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success);
                    }
                    [] tc_ac.timeout {
                        log("*** " & testcasename() & ": INCONC: Timeout while awaiting the reception of a message. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
                    }
                }
                
                // Postamble
                f_utTriggerEvent(m_utTriggerEvent(stopTLMService));
                f_poDefault();
                f_cfDown();
                
            } // End of function f_IS_TLM_EVGN_BV_01
            
            /**
             * @desc    TP Function for f_IS_TLM_EVGN_BV_02
             */
            function f_IS_TLM_EVGN_BV_02() runs on ItsMapemSpatem {
                
                // Local variables
                var SpatemInd v_spatem;
                
                // Test control
                if (not PICS_RSU_ROLE or not PICS_SPATEM_GENERATION) {
                    log("*** " & testcasename() & ": PICS_RSU_ROLE and PICS_SPATEM_GENERATION required for executing the TC ***");
                    setverdict(inconc);
                    stop;
                }
                
                // Test component configuration
                f_cfUp();
                    
                // Preamble
                f_prInitialState();
                f_utTriggerEvent(m_utTriggerEvent(startTLMService));
                f_awaitSpateMessage(
                    mw_spatemInd(
                        mw_spatemPdu(
                            mw_spatemWellFormatted
                        )
                    ), 
                    v_spatem
                );
                
                // Test Body
                f_utTriggerEvent(m_utTriggerEvent(spatemNewContent));
                tc_ac.start;
                alt {
                    [] mapemSpatemPort.receive(v_spatem) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": FAIL: The same SPATEM was received. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                    }
                    [] mapemSpatemPort.receive(
                        mw_spatemInd(
                            mw_spatemPdu(
                                mw_spatemWellFormatted
                    ))) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": PASS: Successfully received a new well-formed SPATE message. ***");
                        f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success);
                    }
                    [] mapemSpatemPort.receive(
                        mw_spatemInd(
                            mw_spatemPdu(
                                mw_defaultSpatem
                    ))) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": FAIL: Received a SPATEM with incorrect information. ***");
                        f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success);
                    }
                    [] tc_ac.timeout {
                        log("*** " & testcasename() & ": INCONC: Timeout while awaiting the reception of a message. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
                    }
                }
                
                // Postamble
                f_utTriggerEvent(m_utTriggerEvent(stopTLMService));
                f_poDefault();
                f_cfDown();
                
            } // End of function f_IS_TLM_EVGN_BV_02
            
            /**
             * @desc    TP Function for f_IS_TLM_EVGN_BV_03
             */
            function f_IS_TLM_EVGN_BV_03() runs on ItsMapemSpatem { // TODO Move ito spateEventTermination goup
                
                // Local variables
                
                // Test control
                if (not PICS_RSU_ROLE or not PICS_SPATEM_GENERATION) {
                    log("*** " & testcasename() & ": PICS_RSU_ROLE and PICS_SPATEM_GENERATION required for executing the TC ***");
                    setverdict(inconc);
                    stop;
                }
                
                // Test component configuration
                f_cfUp();
                
                // Preamble
                f_prInitialState();
                f_utTriggerEvent(m_utTriggerEvent(startTLMService));
                f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                    
                // Test Body
                f_utTriggerEvent(m_utTriggerEvent(stopTLMService));
                mapemSpatemPort.clear;
                tc_noac.start;
                alt {
                    [] mapemSpatemPort.receive(
                        mw_spatemInd(
                            mw_spatemPdu(
                                mw_defaultSpatem
                    ))) { 
                        tc_noac.stop;
                        log("*** " & testcasename() & ": FAIL: No more SPATEM messages were expected. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                    }
                    [] tc_noac.timeout {
                        log("*** " & testcasename() & ": PASS: TLM Service terminated. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                    }
                }
                    
                // Postamble
                f_poDefault();
                f_cfDown();
                
            } // End of function f_IS_TLM_EVGN_BV_03
            
            /**
             * @desc    TP Function for f_IS_TLM_EVGN_BV_04
             */
            function f_IS_TLM_EVGN_BV_04() runs on ItsMapemSpatem {
                
                // Local variables
                var SpatemInd v_spatem;
                
                // Test control
                if (not PICS_RSU_ROLE or not PICS_SPATEM_GENERATION) {
                    log("*** " & testcasename() & ": PICS_RSU_ROLE and PICS_SPATEM_GENERATION required for executing the TC ***");
                    setverdict(inconc);
                    stop;
                }
                
                // Test component configuration
                f_cfUp();
                    
                // Preamble
                f_prInitialState();
                f_utTriggerEvent(m_utTriggerEvent(startTLMService));
                f_awaitSpateMessage(
                    mw_spatemInd(
                        mw_spatemPdu(
                            mw_defaultSpatem
                        )
                    ), 
                    v_spatem
                );
                
                // Test Body
                f_utTriggerEvent(m_utTriggerEvent(spatemNewContent));
                tc_ac.start;
                alt {
                    [] mapemSpatemPort.receive(v_spatem) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": FAIL: A different SPATE message was expected. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                    }
                    [] mapemSpatemPort.receive(
                        mw_spatemInd(
                            mw_spatemPdu(
                                mw_spatemWellFormatted
                    ))) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": PASS: Successfully received a new well-formed SPATE message. ***");
                        f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success);
                    }
                    [] mapemSpatemPort.receive(
                        mw_spatemInd(
                            mw_spatemPdu(
                                mw_defaultSpatem
                    ))) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": FAIL: Received a SPATEM with incorrect information. ***");
                        f_selfOrClientSyncAndVerdictPreamble(c_tbDone, e_success);
                    }
                    [] tc_ac.timeout {
                        log("*** " & testcasename() & ": INCONC: Timeout while awaiting the reception of a message. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
                    }
                }
                
                // Postamble
                f_utTriggerEvent(m_utTriggerEvent(stopTLMService));
                f_poDefault();
                f_cfDown();
                
            } // End of function f_IS_TLM_EVGN_BV_04
            
        } // End of group spateEventGeneration
        
        group spateCommunication {
            
            /**
             * @desc    TP Function for f_IS_TLM_COMM_BV_01
             */
            function f_IS_TLM_COMM_BV_01 () runs on ItsMapemSpatem {
                
                // Local variables
                
                // Test control
                if (not PICS_RSU_ROLE or not PICS_SPATEM_GENERATION) {
                    log("*** " & testcasename() & ": PICS_RSU_ROLE and PICS_SPATEM_GENERATION required for executing the TC ***");
                    setverdict(inconc);
                    stop;
                }
                
                // Test component configuration
                f_cfUp();
                
                // Preamble
                f_prInitialState();
                f_utTriggerEvent(m_utTriggerEvent(startTLMService));
                f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                
                // Test Body
                tc_ac.start;
                alt {
                    [] mapemSpatemPort.receive(
                        mw_spatemInd(
                           mw_spatemPdu(
                               mw_spatem_with_region_id
                    ))) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": PASS: Successfully received MAPEM using GBC. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                    }
                    [] tc_ac.timeout {
                        log("*** " & testcasename() & ": INCONC: Timeout while awaiting the reception of a message. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
                    }
                }
                
                // Postamble
                f_utTriggerEvent(m_utTriggerEvent(stopTLMService));
                f_poDefault();
                f_cfDown();
                
            } // End of function f_IS_TLM_COMM_BV_01
            
            /**
             * @desc    TP Function for f_IS_TLM_COMM_BV_02_01
             */
            function f_IS_TLM_COMM_BV_02_01 () runs on ItsMapemSpatem {
                
                // Local variables
                const UInt8 c_gnNhBtpB := 2;
                
                // Test control
                if (not PICS_RSU_ROLE or not PICS_SPATEM_GENERATION) {
                    log("*** " & testcasename() & ": PICS_RSU_ROLE and PICS_SPATEM_GENERATION required for executing the TC ***");
                    setverdict(inconc);
                    stop;
                }
                
                // Test component configuration
                f_cfUp();
                
                // Preamble
                f_prInitialState();
                f_utTriggerEvent(m_utTriggerEvent(startTLMService));
                f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                
                // Test Body
                tc_ac.start;
                alt {
                    [] mapemSpatemPort.receive(
                        mw_spatemIndWithGnParameters(
                           mw_spatemPdu, 
                           c_gnNhBtpB
                    )) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": PASS: Expected SPATEM encapsultated in BTP-B packet received. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                    }
                    [] mapemSpatemPort.receive(mw_spatemIndWithGnParameters(mw_spatemPdu(mw_defaultSpatem), omit)) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": FAIL: no GN NH information in SpatemInd ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);  
                    }                    
                    [] mapemSpatemPort.receive(mw_spatemInd(mw_spatemPdu(mw_defaultSpatem))) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": FAIL: Expected SPATEM received, but not encapsulated in BTP-B packet ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_error);  
                    }                    
                    [] tc_ac.timeout {
                        log("*** " & testcasename() & ": INCONC: Timeout while awaiting the reception of a message. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
                    }
                }
                
                // Postamble
                f_utTriggerEvent(m_utTriggerEvent(stopTLMService));
                f_poDefault();
                f_cfDown();
                
            } // End of function f_IS_TLM_COMM_BV_02_01
            
            /**
             * @desc    TP Function for f_IS_TLM_COMM_BV_02_02
             */
            function f_IS_TLM_COMM_BV_02_02 () runs on ItsMapemSpatem {
                
                // Local variables
                const UInt16 c_gnNhBtpBPort := 2004;
                
                // Test control
                if (not PICS_RSU_ROLE or not PICS_SPATEM_GENERATION) {
                    log("*** " & testcasename() & ": PICS_RSU_ROLE and PICS_SPATEM_GENERATION required for executing the TC ***");
                    setverdict(inconc);
                    stop;
                }
                
                // Test component configuration
                f_cfUp();
                
                // Preamble
                f_prInitialState();
                f_utTriggerEvent(m_utTriggerEvent(startTLMService));
                f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                
                // Test Body
                tc_ac.start;
                alt {
                    [] mapemSpatemPort.receive(
                        mw_spatemIndWithBtpParameters(
                           mw_spatemPdu, 
                           c_gnNhBtpBPort,
                           0
                    )) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": PASS: Expected SPATEM encapsultated in BTP packet with port value 2004 received. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                    }
                    [] mapemSpatemPort.receive(mw_spatemInd(mw_spatemPdu(mw_defaultSpatem))) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": FAIL: Expected SPATEM received, but not addressed to the correct destination port. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_error);  
                    }                    
                    [] tc_ac.timeout {
                        log("*** " & testcasename() & ": INCONC: Timeout while awaiting the reception of a message. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
                    }
                }
                
                // Postamble
                f_utTriggerEvent(m_utTriggerEvent(stopTLMService));
                f_poDefault();
                f_cfDown();
                
            } // End of function f_IS_TLM_COMM_BV_02_02
            
            /**
             * @desc    TP Function for f_IS_TLM_COMM_BV_03
             */
            function f_IS_TLM_COMM_BV_03 () runs on ItsMapemSpatem {
                
                // Local variables
                const UInt8 c_gnHtGbc := 4;
                
                // Test control
                if (not PICS_RSU_ROLE or not PICS_SPATEM_GENERATION) {
                    log("*** " & testcasename() & ": PICS_RSU_ROLE and PICS_SPATEM_GENERATION required for executing the TC ***");
                    setverdict(inconc);
                    stop;
                }
                
                // Test component configuration
                f_cfUp();
                
                // Preamble
                f_prInitialState();
                f_utTriggerEvent(m_utTriggerEvent(startTLMService));
                f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                
                // Test Body
                tc_ac.start;
                alt {
                    [] mapemSpatemPort.receive(
                        mw_spatemIndWithGnParameters(
                           mw_spatemPdu(
                               mw_spatemWellFormatted
                           ),
                           -,
                           c_gnHtGbc
                    )) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": PASS: Expected SPATEM encapsulated in GBC packet received. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                    }
                    [] mapemSpatemPort.receive(
                        mw_spatemIndWithGnParameters(
                           mw_spatemPdu(
                               mw_spatemWellFormatted
                           ),
                           -,
                           omit
                    )) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": FAIL: Eno GN HT information in SpatemInd. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                    }
                    [] mapemSpatemPort.receive(
                        mw_spatemInd(
                           mw_spatemPdu(
                               mw_spatemWellFormatted
                    ))) { 
                        tc_ac.stop;
                        log("*** " & testcasename() & ": FAIL: Expected SPATEM received, but not encapsulated in GBC packet. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                    }
                    [] tc_ac.timeout {
                        log("*** " & testcasename() & ": INCONC: Timeout while awaiting the reception of a message. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
                    }
                }
                
                // Postamble
                f_utTriggerEvent(m_utTriggerEvent(stopTLMService));
                f_poDefault();
                f_cfDown();
                
            } // End of function f_IS_TLM_COMM_BV_03
            
        } // End of group spateCommunication 
        
    } // End of group spateMessageDissemination
    
    group spateMessageProcessing {
            
            /**
             * @desc    TP Function for f_IS_TLM_MSGF_BV_02
             */
            function f_IS_TLM_MSGF_BV_02 () runs on ItsMapemSpatem {
                    
                // Local variables
                var SpatemReq   v_spatemReq;
                var integer     i;
                
                if (PICS_RSU_ROLE and not PICS_SPATEM_RECEPTION) {
                    log("*** " & testcasename() & ": not PICS_RSU_ROLE and PICS_SPATEM_RECEPTION required for executing the TC ***");
                    setverdict(inconc);
                    stop;
                }
                
                // Test component configuration
                f_cfUp();
                
                // Preamble
                f_prInitialState();
                f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                
                // Test Body
                v_spatemReq := valueof(m_spatemReq(m_spatemPdu(m_defaultSpatem)));
                mapemSpatemPort.send(v_spatemReq) ;
                
                f_sleep(PX_TAC);
                for (i := 0; i < lengthof(vc_utSpatemEvents) and not match (v_spatemReq.msgOut , vc_utSpatemEvents[i].spateMsg); i := i + 1) {
                    // empty on purpose 
                }
                if (i < lengthof(vc_utSpatemEvents) ) {
                    log("*** " & testcasename() & ": PASS: SPATEM was transmitted to upper layer ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                } else {
                    log("*** " & testcasename() & ": FAIL: SPATEM was not transmitted to upper layer ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                }
                
                // Postamble
                f_poDefault();
                f_cfDown();
                
            } // End of function f_IS_TLM_MSGF_BV_02
            
    } // End of group spateMessageProcessing
    
} // End of module ItsSpatem_TpFunctions 