/**
 *    @author   ETSI STF517 / STF525
 *    @version  $URL$
 *              $Id$
 *    @desc     SREM TP functions
 *    @copyright   ETSI Copyright Notification
 *                 No part may be reproduced except as authorized by written permission.
 *                 The copyright and the foregoing restriction extend to reproduction in all media.
 *                 All rights reserved.
 *
 */

module ItsSrem_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 SREM_PDU_Descriptions language "ASN.1:1997" all;
    import from SSEM_PDU_Descriptions language "ASN.1:1997" all;
    import from DSRC language "ASN.1:1997" all;
    
    // LibItsSremSsem
    import from LibItsSremSsem_TestSystem all;
    import from LibItsSremSsem_Functions all;
    import from LibItsSremSsem_Templates all;
    import from LibItsSremSsem_TypesAndValues all;
    import from LibItsSremSsem_Pics all;
    import from LibItsSremSsem_Pixits all;
    
    group iTS_SRole {
        
        group sreMessageDissemination { 
            
            group sreMessageFormat { 
                
                /**
                 * @desc    TP Function for TC_IS_TLC_MSGF_BV_01
                 */
                function f_IS_TLC_MSGF_BV_01 () runs on ItsSremSsem {
                    
                    // Local variables
                    var SremInd v_sremInd;
                    
                    // Test control
                    if (not PICS_SREM_GENERATION) {
                        log("*** " & testcasename() & ": PICS_SREM_GENERATION required for executing the TC ***");
                        setverdict(inconc);
                        stop;
                    }
                    
                    // Test component configuration
                    f_cfUp();
                    
                    // Preamble
                    f_prInitialState();
                    f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                        
                    // Test Body
                    f_utTriggerEvent(m_utTriggerEvent(PX_BASICVEHICLEROLE, PX_REQUESTIMPORTANCELEVEL));
                    
                    tc_ac.start;
                    alt {
                        [] sremSsemPort.receive(
                            mw_sremInd(
                                mw_sremPdu
                        )) -> value v_sremInd { 
                            tc_ac.stop;
                            // Send SSEM
                            f_sendSseMessage(v_sremInd.msgIn.srm);
                            log("*** " & testcasename() & ": PASS: Successfully received SREM 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_poDefault();
                    f_cfDown();
                    
                } // End of function f_IS_TLC_MSGF_BV_01
                
            } // End of group sreMessageFormat 
            
            group sreEventGeneration { 
                
                /**
                 * @desc    TP Function for TC_IS_TLC_EVGN_BV_01
                 */
                function f_IS_TLC_EVGN_BV_01 () runs on ItsSremSsem {
                    
                    // Local variables
                    var SremInd v_sremInd;
                    
                    // Test control
                    if (not PICS_SREM_GENERATION) {
                        log("*** " & testcasename() & ": PICS_SREM_GENERATION required for executing the TC ***");
                        setverdict(inconc);
                        stop;
                    }
                    
                    // Test component configuration
                    f_cfUp();
                        
                    // Preamble
                    f_prInitialState();
                    f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                    
                    // Test Body
                    f_utTriggerEvent(m_utTriggerEvent(PX_BASICVEHICLEROLE, PX_REQUESTIMPORTANCELEVEL));
                    
                    tc_ac.start;
                    alt {
                        [] sremSsemPort.receive(
                            mw_sremInd(
                                mw_sremPdu(
                                    mw_sremWellFormatted
                        ))) -> value v_sremInd { 
                            tc_ac.stop;
                            // Send SSEM
                            f_sendSseMessage(v_sremInd.msgIn.srm);
                            log("*** " & testcasename() & ": PASS: Successfully received SREM 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_poDefault();
                    f_cfDown();
                    
                } // End of function f_IS_TLC_EVGN_BV_01
                
                /**
                 * @desc    TP Function for TC_IS_TLC_EVGN_BV_02
                 */
                function f_IS_TLC_EVGN_BV_02 () runs on ItsSremSsem {
                    
                    // Local variables
                    var template (value) UtSremTriggerList v_utTriggers := {
                        m_utTriggerEvent(PX_BASICVEHICLEROLE, PX_REQUESTIMPORTANCELEVEL),
                        m_utTriggerEvent(PX_BASICVEHICLEROLE, PX_REQUESTIMPORTANCELEVEL),
                        m_utTriggerEvent(PX_BASICVEHICLEROLE, PX_REQUESTIMPORTANCELEVEL)
                    }
                    var boolean v_success := true;
                    var RequestIDList v_requestIDList;
                    var SremInds v_sremInds := {};
                    var integer i;
                    
                    // Test control
                    if (not PICS_SREM_GENERATION) {
                        log("*** " & testcasename() & ": PICS_SREM_GENERATION required for executing the TC ***");
                        setverdict(inconc);
                        stop;
                    }
                    
                    // Test component configuration
                    f_cfUp();
                        
                    // Preamble
                    f_prInitialState();
                    for (i := 0; i < lengthof(v_utTriggers) - 1; i := i + 1) {
                        f_utTriggerEvent(valueof(v_utTriggers[i]));
                        f_awaitSreMessage(mw_sremInd(mw_sremPdu(mw_sremWellFormatted)), v_sremInds[i]);
                        v_requestIDList[i] := v_sremInds[i].msgIn.srm.requests[0].request.requestID;
                    }
                    f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                    
                    // Test Body
                    f_utTriggerEvent(m_utTriggerEvent(PX_BASICVEHICLEROLE, PX_REQUESTIMPORTANCELEVEL));
                    
                    f_utTriggerEvent(valueof(v_utTriggers[lengthof(v_utTriggers) - 1]));
                    f_awaitSreMessage(mw_sremInd(mw_sremPdu(mw_sremWellFormatted)), v_sremInds[i]);
                    v_requestIDList[lengthof(v_requestIDList) - 1] := v_sremInds[i].msgIn.srm.requests[0].request.requestID;
                    
                    //check the action id
                    for (i := 0; i < lengthof(v_requestIDList) - 1; i := i + 1) {
                        if (v_requestIDList[lengthof(v_requestIDList) - 1] == v_requestIDList[i]) {
                            v_success := false;
                        }
                    }
                    if (v_success==true) {
                        log("*** " & testcasename() & ": PASS: RequestID field indicating unused value. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                    }
                    else {
                        log("*** " & testcasename() & ": FAIL: RequestID field indicating used value. ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                    }
                    
                    // Postamble
                    for (i := 0; i < lengthof(v_sremInds); i := i + 1) {
                        // Send SSEM
                        f_sendSseMessage(v_sremInds[i].msgIn.srm);
                    }
                    f_poDefault();
                    f_cfDown();
                    
                } // End of function f_IS_TLC_EVGN_BV_02
                
            } // End of group sreEventGeneration 
            
            group sreEventUpdate {
                
                /**
                 * @desc    TP Function for TC_IS_TLC_EVUP_BV_01
                 */
                function f_IS_TLC_EVUP_BV_01 () runs on ItsSremSsem {
                    
                    // Local variables
                    var SremInd v_sremInd;
                    var RequestID v_requestID;
                    var MsgCount v_sequenceNumber;
                    
                    // Test control
                    if (not PICS_SREM_GENERATION) {
                        log("*** " & testcasename() & ": PICS_SREM_GENERATION required for executing the TC ***");
                        setverdict(inconc);
                        stop;
                    }
                    
                    // Test component configuration
                    f_cfUp();
                        
                    // Preamble
                    f_prInitialState();
                    f_utTriggerEvent(m_utTriggerEvent(PX_BASICVEHICLEROLE, PX_REQUESTIMPORTANCELEVEL));
                    f_awaitSreMessage(mw_sremInd(mw_sremPdu(mw_sremWellFormatted)), v_sremInd);
                    f_sendSseMessage(v_sremInd.msgIn.srm);
                    v_requestID := v_sremInd.msgIn.srm.requests[0].request.requestID;
                    v_sequenceNumber := v_sremInd.msgIn.srm.sequenceNumber;
                    f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                    
                    // Test Body
                    f_utUpdateEvent(m_utUpdateEvent(v_requestID, PX_BASICVEHICLEROLE, PX_REQUESTIMPORTANCELEVEL));
                    
                    tc_ac.start;
                    alt {
                        [] sremSsemPort.receive(
                            mw_sremInd(
                                mw_sremPdu(
                                    mw_srem_sequenceNumber(
                                        (v_sequenceNumber + 1) mod 128 // See MsgCount declaration
                                    )
                        ))) -> value v_sremInd { 
                            tc_ac.stop;
                            // Send SSEM
                            f_sendSseMessage(v_sremInd.msgIn.srm);
                            if (not match(v_requestID, v_sremInd.msgIn.srm.requests[0].request.requestID)) {
                                log("*** " & testcasename() & ": FAIL: requestID mismatch. ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                            } else {
                                log("*** " & testcasename() & ": PASS: Successfully received SREM 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_poDefault();
                    f_cfDown();
                    
                } // End of function f_IS_TLC_EVUP_BV_01
                
            } // End of group sreEventUpdate 
            
            group sreCommunication {
                
                /**
                 * @desc    TP Function for TC_IS_TLC_COMM_BV_01_01
                 */
                function f_IS_TLC_COMM_BV_01_01 () runs on ItsSremSsem {
                    
                    // Local variables
                    const UInt8 c_gnNhBtpB := 2;
                    var SremInd v_sremInd;
                    
                    // Test control
                    if (not PICS_SREM_GENERATION) {
                        log("*** " & testcasename() & ": PICS_SREM_GENERATION required for executing the TC ***");
                        setverdict(inconc);
                        stop;
                    }
                    
                    // Test component configuration
                    f_cfUp();
                    
                    // Preamble
                    f_prInitialState();
                    f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                    
                    // Test Body
                    f_utTriggerEvent(m_utTriggerEvent(PX_BASICVEHICLEROLE, PX_REQUESTIMPORTANCELEVEL));
                    
                    tc_ac.start;
                    alt {
                        [] sremSsemPort.receive(
                            mw_sremIndWithGnParameters(
                               mw_sremPdu(
                                   mw_sremWellFormatted
                               ), 
                               c_gnNhBtpB
                        )) -> value v_sremInd { 
                            tc_ac.stop;
                            // Send SSEM
                            f_sendSseMessage(v_sremInd.msgIn.srm);
                            log("*** " & testcasename() & ": PASS: Expected SREM encapsultated in BTP-B packet received. ***");
                            f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                        }
                        [] sremSsemPort.receive(mw_sremIndWithGnParameters(mw_sremPdu(mw_sremWellFormatted), omit)) -> value v_sremInd { 
                            tc_ac.stop;
                            // Send SSEM
                            f_sendSseMessage(v_sremInd.msgIn.srm);
                            log("*** " & testcasename() & ": INCONC: no GN NH information in SremInd ***");
                            f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);  
                        }                    
                        [] sremSsemPort.receive(mw_sremInd(mw_sremPdu(mw_defaultSrem))) -> value v_sremInd { 
                            tc_ac.stop;
                            // Send SSEM
                            f_sendSseMessage(v_sremInd.msgIn.srm);
                            log("*** " & testcasename() & ": FAIL: Expected SREM 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_poDefault();
                    f_cfDown();
                    
                } // End of function f_IS_TLC_COMM_BV_01_01
                
                /**
                 * @desc    TP Function for TC_IS_TLC_COMM_BV_01_02
                 */
                function f_IS_TLC_COMM_BV_01_02 () runs on ItsSremSsem {
                    
                    // Local variables
                    const UInt16 c_gnNhBtpBPort := 2007;
                    var SremInd v_sremInd;
                    
                    // Test control
                    if (not PICS_SREM_GENERATION) {
                        log("*** " & testcasename() & ": PICS_SREM_GENERATION required for executing the TC ***");
                        setverdict(inconc);
                        stop;
                    }
                    
                    // Test component configuration
                    f_cfUp();
                    
                    // Preamble
                    f_prInitialState();
                    f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                    
                    // Test Body
                    f_utTriggerEvent(m_utTriggerEvent(PX_BASICVEHICLEROLE, PX_REQUESTIMPORTANCELEVEL));
                    
                    tc_ac.start;
                    alt {
                        [] sremSsemPort.receive(
                            mw_sremIndWithBtpParameters(
                               mw_sremPdu, 
                               c_gnNhBtpBPort,
                               0
                        )) -> value v_sremInd { 
                            tc_ac.stop;
                            // Send SSEM
                            f_sendSseMessage(v_sremInd.msgIn.srm);
                            log("*** " & testcasename() & ": PASS: Expected SREM encapsultated in BTP packet with port value 2003 received. ***");
                            f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                        }
                        [] sremSsemPort.receive(mw_sremInd(mw_sremPdu(mw_defaultSrem))) -> value v_sremInd { 
                            tc_ac.stop;
                            // Send SSEM
                            f_sendSseMessage(v_sremInd.msgIn.srm);
                            log("*** " & testcasename() & ": FAIL: Expected SREM 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_poDefault();
                    f_cfDown();
                    
                } // End of function f_IS_TLC_COMM_BV_01_02
                
                /**
                 * @desc    TP Function for TC_IS_TLC_COMM_BV_03
                 */
                function f_IS_TLC_COMM_BV_03 () runs on ItsSremSsem {
                    
                    // Local variables
                    const UInt8 c_gnHtGbc := 4;
                    var SremInd v_sremInd;
                    
                    // Test control
                    if (not PICS_SREM_GENERATION) {
                        log("*** " & testcasename() & ": PICS_SREM_GENERATION required for executing the TC ***");
                        setverdict(inconc);
                        stop;
                    }
                    
                    // Test component configuration
                    f_cfUp();
                        
                    // Preamble
                    f_prInitialState();
                    f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                        
                    // Test Body
                    f_utTriggerEvent(m_utTriggerEvent(PX_BASICVEHICLEROLE, PX_REQUESTIMPORTANCELEVEL));
                    
                    tc_ac.start;
                    alt {
                        [] sremSsemPort.receive(
                            mw_sremIndWithGnParameters(
                                mw_sremPdu(
                                    mw_sremWellFormatted
                                ),
                                -, 
                                c_gnHtGbc
                        )) -> value v_sremInd { 
                            tc_ac.stop;
                            // Send SSEM
                            f_sendSseMessage(v_sremInd.msgIn.srm);
                            log("*** " & testcasename() & ": PASS: Expected SREM encapsulated in GBC packet received. ***");
                            f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                        }
                        [] sremSsemPort.receive(
                            mw_sremIndWithGnParameters(
                                mw_sremPdu(
                                    mw_sremWellFormatted
                                ),
                                -, 
                                omit
                        )) -> value v_sremInd { 
                            tc_ac.stop;
                            // Send SSEM
                            f_sendSseMessage(v_sremInd.msgIn.srm);
                            log("*** " & testcasename() & ": FAIL: no GN HT information in SremInd. ***");
                            f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                        }
                        [] sremSsemPort.receive(
                            mw_sremInd(
                                mw_sremPdu(
                                    mw_sremWellFormatted
                        ))) -> value v_sremInd { 
                            tc_ac.stop;
                            // Send SSEM
                            f_sendSseMessage(v_sremInd.msgIn.srm);
                            log("*** " & testcasename() & ": FAIL:  Expected SREM 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_poDefault();
                    f_cfDown();
                    
                } // End of function f_IS_TLC_COMM_BV_03
                
            } // End of group sreCommunication 
            
        } // End of group sreMessageDissemination 
        
        group sreMessageProcessing {
            
            /**
             * @desc    TP Function for TC_IS_TLC_MSGF_BV_03
             */
            function f_IS_TLC_MSGF_BV_03 () runs on ItsSremSsem {
                
                // Local variables
                var SsemReq   v_ssemReq;
                var integer     i;
                    
                if (not PICS_SSEM_RECEPTION) {
                    log("*** " & testcasename() & ": PICS_SSEM_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_ssemReq := valueof(m_ssemReq(m_ssemPdu(m_defaultSsem))); 
                sremSsemPort.send(v_ssemReq) ;
                    
                f_sleep(PX_TAC);
                for (i := 0; i < lengthof(vc_utSsemEvents) and not match (v_ssemReq.msgOut , vc_utSsemEvents[i].sseMsg); i := i + 1) {
                    // empty on purpose 
                }
                if (i < lengthof(vc_utSsemEvents) ) {
                    log("*** " & testcasename() & ": PASS: SREM was transmitted to upper layer ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                } else {
                    log("*** " & testcasename() & ": FAIL: SREM was not transmitted to upper layer ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                }
                    
                // Postamble
                f_poDefault();
                f_cfDown();
                    
            } // End of function f_IS_TLC_MSGF_BV_03
            
        } // End of group sreMessageProcessing
        
    } // End of group iTS_SRole
    
    group rsuRole {
        
        group sreMessageDisseminationRsu { 
            
            group sreMessageFormatRsu { 
                
                /**
                 * @desc    TP Function for TC_IS_TLC_MSGF_BV_04
                 */
                function f_IS_TLC_MSGF_BV_04 () runs on ItsSremSsem {
                    
                    // Local variables
                    
                    // Test control
                    if (not PICS_SSEM_GENERATION) {
                        log("*** " & testcasename() & ": PICS_SSEM_GENERATION required for executing the TC ***");
                        setverdict(inconc);
                        stop;
                    }
                    
                    // Test component configuration
                    f_cfUp();
                        
                    // Preamble
                    f_prInitialState();
                    f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
                        
                    // Test Body
                    // Send SREM
                    sremSsemPort.send(
                        m_sremReq(
                            m_sremPdu(
                                m_defaultSrem
                    )));
                    
                    tc_ac.start;
                    alt {
                        [] sremSsemPort.receive(
                            mw_ssemInd(
                                mw_ssemPdu
                        )) { 
                            tc_ac.stop;
                            log("*** " & testcasename() & ": PASS: Successfully received SSEM 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_poDefault();
                    f_cfDown();
                    
                } // End of function f_IS_TLC_MSGF_BV_04
                
            } // End of group sreMessageFormatRsu
            
            group sreCommunicationRsu {
                
            } // End of group sreCommunicationRsu
            
        } // End of group sreMessageDisseminationRsu
        
        group sreMessageProcessingRsu {
            
            /**
             * @desc    TP Function for TC_IS_TLC_MSGF_BV_02
             */
            function f_IS_TLC_MSGF_BV_02 () runs on ItsSremSsem {
                
                // Local variables
                var SremReq   v_sremReq;
                var integer   i;
                    
                if (not PICS_SREM_RECEPTION) {
                    log("*** " & testcasename() & ": PICS_SREM_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_sremReq := valueof(m_sremReq(m_sremPdu(m_defaultSrem)));
                sremSsemPort.send(v_sremReq) ;
                    
                f_sleep(PX_TAC);
                for (i := 0; i < lengthof(vc_utSremEvents) and not match (v_sremReq.msgOut , vc_utSremEvents[i].sreMsg); i := i + 1) {
                    // empty on purpose 
                }
                if (i < lengthof(vc_utSsemEvents) ) {
                    log("*** " & testcasename() & ": PASS: SSEM was transmitted to upper layer ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                } else {
                    log("*** " & testcasename() & ": FAIL: SSEM was not transmitted to upper layer ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                }
                    
                // Postamble
                f_poDefault();
                f_cfDown();
                    
            } // End of function f_IS_TLC_MSGF_BV_02
            
        } // End of group sreMessageProcessingRsu
        
    } // End of group rsuRole
    
} // End of module ItsSrem_TpFunctions 