LibItsFntp_Functions.ttcn3 63.2 KB
Newer Older
/**
 *  @author     ETSI / STF422_EETS
filatov's avatar
filatov committed
 *  @version    $URL$
 *              $Id$
 *  @desc       FAST networking & transport layer protocol (ISO 29281-2) functions
 */
module LibItsFntp_Functions {
    
    // Libcommon
garciay's avatar
garciay committed
    import from LibCommon_Sync {
        function 
            f_connect4SelfOrClientSync, f_disconnect4SelfOrClientSync, 
        f_selfOrClientSyncAndVerdict, f_selfOrClientSyncAndVerdictTestBody; 
        altstep a_shutdown 
    };
    import from LibCommon_VerdictControl {
      type FncRetCode
    };
    import from LibCommon_Time {
      function f_sleep, f_sleepIgnoreDef
    };
    import from LibCommon_BasicTypesAndValues { 
        type UInt16 
    };
    
garciay's avatar
garciay committed
    // LibIts 
    
    // LibItsCalm 
    import from CALMmanagement language "ASN.1:1997" { 
        type StationID, ITS_scuId; 
    }; 
    import from CALMllsap language "ASN.1:1997" { 
        type 
            EUI64, IN_SAPaddress, LLserviceAddr, Link_ID, AccessParameters 
    }; 
garciay's avatar
garciay committed
    import from CALMmsap language "ASN.1:1997" { 
        type 
            FWTsetNot 
    }; 
    import from CITSapplReq language "ASN.1:1997" { 
        type ServiceRef 
garciay's avatar
garciay committed
    import from CALMfntp language "ASN.1:1997" all; 
    import from LibItsFntp_TypesAndValues {
        const c_portDyn, c_portNon;
garciay's avatar
garciay committed
        type 
            UtFntpEvent, UtFntpEventInd, 
            CfFntpEventInd 
    };
    import from LibItsFntp_Pics { 
        modulepar PICS_ITS_MGT_NOT
    };
    import from LibItsFntp_Templates all;
    import from LibItsFntp_Pixits all;
    import from LibItsFntp_Pics {
        modulepar PICS_ITS_S_INW, PICS_ROLE_RH;
garciay's avatar
garciay committed
    import from LibItsMgt_TypesAndValues { 
        group constants 
    };
    import from LibItsMgt_Templates { 
        template 
            mdw_fwtSetNotRequestReq, mdw_fwtDeleteFntp, 
            mw_mnRequestRequest_setNotFNTP 
    };
    import from LibItsCalm_Interface { 
        type 
            UtInitialize, CfInitialize, CfEventInd, 
            UtResult, CfResult, 
            ItsCalm 
    }; 
garciay's avatar
garciay committed
    /**
     * @desc Upper tester functions
     */
    group utFunctions {
        
        /**
         * @desc    Requests to bring the IUT in an initial state
         * @param   p_utInitialize The initialisation to trigger.
         * @verdict Unchanged on success, fail on error and inconc otherwise
         */
        function f_utFntpInitializeIut(template (value) UtInitialize p_utInitialize) runs on ItsCalm {
        
            utPort.send(p_utInitialize);
            tc_wait.start;
            alt {
                [] utPort.receive(UtResult:true) {
                    tc_wait.stop;
                    log("*** f_utFntpInitializeIut: INFO: IUT initialized ***");
                }
                [] utPort.receive {
                    tc_wait.stop;
                    log("*** f_utFntpInitializeIut: INFO: IUT could not be initialized ***");
                    f_selfOrClientSyncAndVerdict("error", e_error);
                }
                [] tc_wait.timeout {
                    log("*** f_utFntpInitializeIut: INFO: IUT could not be initialized in time ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
                }
                [else] { // Shortcut defaults
                    //f_sleep(0.050); // 50 ms
garciay's avatar
garciay committed
                    repeat; 
                }
            } // End of 'alt' statement 
        
        } // End of function f_utFntpInitializeIut 
        
        /**
         * @desc    Send a NFsapPrimitivesDown primitive and wait for the NFsapPrimitivesUp confirm response
         * @param   p_utFntpEvent    The NFsapPrimitivesDown request
         * @param   p_utFntpEventInd The NFsapPrimitivesDown response
         * @param   p_discard        Set to true if responses shall be discard, otherwise the function failed 
         * @param   p_result         The response value
         * @verdict Unchanged on success, fail on error and inconc otherwise
         */
        function f_utFntpEventResponse( 
            in template (value) UtFntpEvent p_utFntpEvent, 
            in template (present) UtFntpEventInd p_utFntpEventInd, 
            in boolean p_discard, 
            out UtFntpEventInd p_result) 
        runs on ItsCalm {
            
//            log("*** f_utFntpEventResponse: INFO: Send message: ", p_commandReq, " ***");
            utPort.send(p_utFntpEvent);
//            log("*** f_utFntpEventResponse: INFO: Expected UtCommandConfirm: ", p_commandConf, " ***");
            tc_wait.start;
            alt {
                [] utPort.receive(p_utFntpEventInd) -> value p_result {
//                    log("*** f_utFntpEventResponse: INFO: Receive expected confirm: message ***");
                    tc_wait.stop;
                }
                [] utPort.receive(UtFntpEventInd:? ) -> value p_result {
                    if (p_discard == false) { 
                        tc_wait.stop; 
                        log("*** f_utFntpEventResponse: ERROR: Event not correctly indicated at application layer ***", p_result);
                        f_selfOrClientSyncAndVerdict("fail", e_error);
                    }
                    else {
                        log("*** f_utFntpEventResponse: INFO: Another event indicated at application layer, repeating check ***");
                        repeat;
                    }
                }
                [] tc_wait.timeout {
                    if (p_discard == false) {
                        log("*** f_utFntpEventResponse: ERROR: Timeout while waiting for event check result ***");
                        f_selfOrClientSyncAndVerdict("error", e_timeout);
                    }
                    else {
                        log("*** f_utFntpEventResponse: INFO: Event not indicated at application layer ***");
                        f_selfOrClientSyncAndVerdict("error", e_timeout);
                    }
                }
            } // End of 'alt' statement
            
        } // End of function f_utFntpEventResponse
        
        /**
         * @desc    Send a NFsapPrimitivesDown primitive and do not wait for the NFsapPrimitivesDown confirm response
         * @param   p_utFntpEvent    The NFsapPrimitivesDown primitive
         * @verdict Unchanged on success, fail otherwise
         */
        function f_utFntpEvent( 
            in template (value) UtFntpEvent p_utFntpEvent 
        ) runs on ItsCalm { 
            var UtFntpEventInd v_utFntpEventInd;
            
            utPort.send(p_utFntpEvent);
            tc_noac.start;
            alt {
                [] utPort.receive(mdw_fntpCommConfirm_anyError(?)) { // Failure expected 
                    tc_noac.stop;
                    log("*** f_utFntpEvent: ERROR: Message is confirmed on error only (see ISO/IEC WD 29281-1 Clause 7.6.2 Basic procedure) ***");
                    f_selfOrClientSyncAndVerdict("error", e_error);
                }
                [] utPort.receive(mw_fntpCommConfirm_success) { // FIXME Use altstep for UtPort
                    tc_noac.stop;
                    log("*** f_utFntpEvent: INFO: Message was confirmed successfully ***");
                }
                [] utPort.receive(UtFntpEventInd:?) -> value v_utFntpEventInd { // FIXME Use altstep for UtPort
                    tc_noac.stop;
                    log("*** f_utFntpEvent: INFO: Unexpected message was received ***", v_utFntpEventInd);
                    // FIXME Check the content of the notification, not sure which fields should be set - repeat;
                }
                [] tc_noac.timeout {
                    log("*** f_utFntpEvent: INFO: CommandRequest succeed ***");
                }
            } // End of 'alt' statement 

        } // End of function f_utFntpEvent
        
    } // End of group utFunctions

    /**
     * @desc Config tester functions
     */
    group cfFunctions { 
        
        /**
         * @desc    Requests to initialize the configuration tester 
         * @param   p_cfInitialize The initialisation to trigger.
         * @verdict Unchanged on success, fail otherwise
         */
        function f_cfFntpInitialize(template (value) CfInitialize p_cfInitialize) runs on ItsCalm {
        
            cfPort.send(p_cfInitialize);
            tc_wait.start;
            alt {
                [] cfPort.receive(CfResult:true) {
                    tc_wait.stop;
                    log("*** f_cfFntpInitialize: INFO: Configuration tester initialized ***");
                }
                [] cfPort.receive {
                    tc_wait.stop;
                    log("*** f_cfFntpInitialize: INFO: Configuration tester could not be initialized ***");
                    f_selfOrClientSyncAndVerdict("error", e_error);
                }
                [] tc_wait.timeout {
                    log("*** f_cfFntpInitialize: INFO: Configuration tester could not be initialized in time ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
                }
                [else] { // Shortcut defaults
                    //f_sleep(0.050); // 50 ms
garciay's avatar
garciay committed
                    repeat; 
                }
            } // End of 'alt' statement 

        } // End of function f_cfFntpInitialize 
        
        /**
         * @desc    Await for notification on MN-SAP 
         * @param   p_cfFntpEventInd    The MN_Request_request notification message.
         * @param   p_discard           Set to true if responses shall be discard, otherwise the function failed 
         * @verdict Unchanged on success, fail otherwise
         */
        function f_cfFntpAwaitNotificationToManagement( 
            in template CfFntpEventInd p_cfFntpEventInd, 
            in boolean p_discard 
        ) runs on ItsCalm {
            var CfFntpEventInd p_result;
            
            log("*** f_cfFntpAwaitNotificationToManagement: INFO: Expected event: ", p_cfFntpEventInd, " ***");
            tc_wait.start;
            alt {
                [] cfPort.receive(p_cfFntpEventInd) {
                    tc_wait.stop;
                    log("*** f_cfFntpAwaitNotificationToManagement: INFO: Notification event received ***");
                }
                [] cfPort.receive(CfFntpEventInd: ?) -> value p_result { 
                    if (p_discard == false) { 
                        tc_wait.stop;
                        log("*** f_cfFntpAwaitNotificationToManagement: ERROR: Another event indicated at application layer ***", p_result);
                        f_selfOrClientSyncAndVerdict("error", e_timeout);
                    } else { 
                        log("*** f_cfFntpAwaitNotificationToManagement: INFO: Another event indicated at application layer, repeating check ***");
                        repeat;
                    } 
                }
                [] tc_wait.timeout {
                    if (p_discard == false) { 
                        log("*** f_cfFntpAwaitNotificationToManagement: ERROR: Timeout while waiting for event check result ***");
                        f_selfOrClientSyncAndVerdict("error", e_timeout);
                    } else { 
                        log("*** f_cfFntpAwaitNotificationToManagement: INFO: Event not indicated at application layer ***");
                    }
                }
            } // End of 'alt' statement
        
        } // End of function f_cfFntpAwaitNotificationToManagement
    
    } // End of group cfFunctions
    
    /**
     * @desc Test adapter setting functions
     */
    group fntpConfigurationFunctions {
        
        /**
         * @desc This configuration features:
         * <li>Host and Router are combined (see ISO/WD 29281-2 - Figure 1 - Implementation architecture I)</li>
         * <li>MGT1 IISC Port (IISC/LAN) is not used</li>
         */
reinaortega's avatar
reinaortega committed
        function f_cf01Up() runs on ItsCalm {
            if (PICS_ITS_S_INW or not(PICS_ROLE_RH)) {
                log("*** f_cf01Up: ERROR: 'PICS_ITS_S_INW or not(PICS_ROLE_RH)' required for stting up CF01 ***");
                stop;
            }
            
            // Map
            map(self:utPort, system:utPort);
garciay's avatar
garciay committed
            map(self:cfPort, system:cfPort); // FIXME Add check PICS_ITS_MGT_NOT
            map(self:fntpPort, system:fntpPort);
            
garciay's avatar
garciay committed
            vc_commandRef := 0;
            vc_pduCounter := 0;
            
            // Connect
            f_connect4SelfOrClientSync();
            
            // Set processing on shutdown
            activate(a_cf01Down());
            
            // Initialize the component
            f_initialiseComponent("cf01Up");
garciay's avatar
garciay committed
            
            // Initialze the IUT
            f_initialState();
            
        } // End of function f_cf01Up
        
        /**
         * @desc This configuration features:
         * <li>Host and Router are separated (see ISO/WD 29281-2 - Figure 3 - Implementation architecture II & III)</li>
         * <li>MGT1 IISC Port (IISC/LAN) is not used</li>
         */
reinaortega's avatar
reinaortega committed
        function f_cf02Up() runs on ItsCalm {
            
            // Sanity check
            if (not(PICS_ITS_S_INW)) {
                log("*** f_cf02Up: ERROR: PICS_ITS_S_INW required for setting uo CF02 ***");
                stop;
            }
            
            vc_commandRef := 0;
            vc_pduCounter := 0;
            
            // Map
            map(self:utPort, system:utPort);
garciay's avatar
garciay committed
            map(self:cfPort, system:cfPort); // FIXME Add check PICS_ITS_MGT_NOT
            map(self:fntpPort, system:fntpPort);
            
            // Connect
            f_connect4SelfOrClientSync();
            
            // Set processing on shutdown
            activate(a_cf02Down());
            
            // Initialize the component
            f_initialiseComponent("cf02Up");

            // Initialze the IUT
            f_initialState();
            
        } // End of function f_cf02Up
        
        /**
         * @desc Deletes configuration cf01
         */
reinaortega's avatar
reinaortega committed
        function f_cf01Down() runs on ItsCalm {
            
            deactivate;
            
            // Unmap
            unmap(self:utPort, system:utPort);
garciay's avatar
garciay committed
            unmap(self:cfPort, system:cfPort); // FIXME Add check PICS_ITS_MGT_NOT
            unmap(self:fntpPort, system:fntpPort);
            
            // Disconnect
            f_disconnect4SelfOrClientSync();
            
        } // end f_cf01Down
garciay's avatar
garciay committed
         * @desc Deletes configuration cf02
reinaortega's avatar
reinaortega committed
        function f_cf02Down() runs on ItsCalm {
            
            deactivate;
            
            // Unmap
            unmap(self:utPort, system:utPort);
garciay's avatar
garciay committed
            unmap(self:cfPort, system:cfPort); // FIXME Add check PICS_ITS_MGT_NOT
            unmap(self:fntpPort, system:fntpPort);
            
            // Disconnect
            f_disconnect4SelfOrClientSync();
            
        } // End of f_cf02Down
        
        /**
         * @desc    Behavior function for initializing component's variables and tables
         * @param   p_componentName Name of the component
         */
reinaortega's avatar
reinaortega committed
        function f_initialiseComponent(in charstring p_componentName) runs on ItsCalm {
            
            // Initialize variables
            vc_componentName := p_componentName;
            vc_portNumber := { portLong := c_portNon };
            
            // Set defaults
            activate(a_fntpDefault()); // Default for Fntp module
        } // End of f_initialiseComponent
        
    } // End of group fntpConfigurationFunctions
    
garciay's avatar
garciay committed
    /**
     * @desc Preambule functions
     */
    group preambles {
        
        /**
         * @desc Brings the IUT into an initial state.
         */
reinaortega's avatar
reinaortega committed
        function f_initialState() runs on ItsCalm {
garciay's avatar
garciay committed
            if (PICS_ITS_MGT_NOT == true) {
                f_utFntpInitializeIut(m_utFntpInitialize_with_management);
            } else { 
                f_utFntpInitializeIut(m_utFntpInitialize_without_management);
            } 
            f_cfFntpInitialize(m_cfFntpInitialize);
            f_sleepIgnoreDef(PX_WAIT_FOR_IUT_READY); // Wait until the IUT is in a stable situation (beaconing...)
garciay's avatar
garciay committed
            cfPort.clear; // Because TestConfigIICP should trigger management port deletion message 
        } // End of function f_initialState
        
        /**
         * @desc Implement the following Initial conditions:
         * <li>the IUT having set up properly the FNTP forwarding table, and the local port number of the ITS-S application</li>
         * <li>the IUT having an entry in the FNTP forwarding table for unicast communication with remote Link Port and Service Port</li>
         * <li>the IUT having an entry in the FNTP forwarding table for Service Port = port1, but not for Service Port = port2</li>
         * <li>the IUT having an entry in the FNTP forwarding table for a Service Port, but no entry for the peer station</li>
         * @param p_port Indicates the port number
         * @verdict Unchanged on success, set to fail on error (e_timeout)
garciay's avatar
garciay committed
         * @see ISO 29281-2 Clause 8.2
garciay's avatar
garciay committed
        // TODO Consider case of c_portDyn, and use f_utEventResponse
reinaortega's avatar
reinaortega committed
        function f_initializeFntpForwardingTable(in PortNumber p_port) runs on ItsCalm {
garciay's avatar
garciay committed
            
            f_utFntpEventResponse( 
                m_generateNfFntpPortCreationRequest(
                    f_getIutServiceRef(), 
garciay's avatar
garciay committed
                    p_port 
                ),
                mw_utFntpEventInd( 
                    mw_fntpPortConfirm( 
                        f_getIutServiceRef(), 
                        p_port 
                    ) 
                ), 
                false, 
                vc_utEventInd.utFntpEventInd 
            // Store the allocated port number
            vc_portNumber := p_port;
            if (ischosen(vc_portNumber.portShort)) {
                log("*** f_initializeFntpForwardingTable: INFO: portNumber value is: " & int2str(vc_portNumber.portShort) & " ***");
            } else {
                log("*** f_initializeFntpForwardingTable: INFO: portNumber value is: " & int2str(vc_portNumber.portLong) & " ***");
            }
garciay's avatar
garciay committed
            if (PICS_ITS_MGT_NOT) {
                // And wait for a MN-SAP.MN-REQUEST/FWTupdate message sent to ITS management entity to update the forwarding table
                f_fntpAwaitFwtUpdate_reference(
                    vc_portNumber, 
                    vc_reference 
                );
            }
        } // End of function f_initializeFntpForwardingTable
        
        /**
garciay's avatar
garciay committed
         * @desc    Wait for MN_Request_request/FWTupdate message sent by IST management entity to update the forwarding table 
         * @param   p_portNumber Contains either the value PORT_NON in order to indicate dynamic assignment of a port number by the port number manager, or a valid value of a well-known static port PORT_REG
         * @param   p_reference  The reference value associated to the provided port number
garciay's avatar
garciay committed
        function f_fntpAwaitFwtUpdate_reference( 
            in template (present) PortNumber p_portNumber, 
            out integer p_reference 
        ) runs on ItsCalm {
            
            f_cfAwaitCreationPortNotificationToManagement( 
                mw_cfFntpEventInd(
                    mdw_fwtSetNotRequestReq(
                        p_portNumber, 
                        PX_USER_PRIORITY, 
                        c_linkId_unknown,  
                        c_unknown_portLong, 
                        c_unknown_portLong 
                    )
                ),
                false,
                p_reference 
            ); 
        } // End of function f_fntpAwaitFwtUpdate_reference
		
        /**
         * @desc Wait for notification from IUT to Management layer
         * @param p_cfFntpEventInd	Receive template of the expected event
         * @param p_discard			Set to true if command confirm responses shall be discard, otherwise the function failed 
         * @param p_reference		The reference value associated to the provided port number
         * @verdict Unchanged on success, set to fail on error (e_timeout)
         */
        function f_cfAwaitCreationPortNotificationToManagement( 
            in template CfFntpEventInd p_cfFntpEventInd, 
            in boolean p_discard, 
            out integer p_reference  
        ) runs on ItsCalm {
            var CfFntpEventInd p_result;
            
            p_reference := 65535; // See noFNTPfwtEntries FIXME Create a constant
            
            log("*** f_cfAwaitCreationPortNotificationToManagement: INFO: Expected event: ", p_cfFntpEventInd, " ***");
            tc_wait.start;
            alt {
                [] cfPort.receive(p_cfFntpEventInd) -> value p_result {
                    tc_wait.stop;
                    p_reference := p_result.mnRequestRequest.request_param.FWTsetNot.fwt.SetNotFNTP.reference;
                    log("*** f_cfAwaitCreationPortNotificationToManagement: INFO: Notification event received, reference entry=", p_reference, " ***");
                }
                [] cfPort.receive(CfFntpEventInd: ?) -> value p_result { 
                    if (p_discard == false) { 
                        tc_wait.stop;
                        log("*** f_cfAwaitCreationPortNotificationToManagement: ERROR: Another event indicated at application layer ***", p_result);
                        f_selfOrClientSyncAndVerdict("error", e_timeout);
                    } else { 
                        log("*** f_cfAwaitCreationPortNotificationToManagement: INFO: Another event indicated at application layer, repeating check ***");
                        repeat;
                    } 
                }
                [] tc_wait.timeout {
                    if (p_discard == false) { 
                        log("*** f_cfAwaitCreationPortNotificationToManagement: ERROR: Timeout while waiting for event check result ***");
                        f_selfOrClientSyncAndVerdict("error", e_timeout);
                    } else { 
                        log("*** f_cfAwaitCreationPortNotificationToManagement: INFO: Event not indicated at application layer ***");
                    }
                }
            } // End of 'alt' statement
        
        } // End of function f_cfAwaitCreationPortNotificationToManagement
    
        /**
         * @desc Wait for MN_Request_request/FWT Update notification from IUT to Management layer
         * @param p_portNumber			The provided port number value
         * @param p_linkId				Set VCI link identifier 
         * @param p_remotePortNumber	The remote port number value
         * @param p_linkPortNumber		The linked port number value
         * @verdict Unchanged on success, set to fail on error (e_timeout)
         */
        function f_fntpAwaitFwtUpdate( 
            in template (present) PortNumber p_portNumber, 
            in template (value) Link_ID p_linkId,  
            in template (value) PortNumber p_remotePortNumber, 
            in template (value) PortNumber p_linkPortNumber 
        ) runs on ItsCalm {
            
            f_cfFntpAwaitNotificationToManagement( 
               mw_cfFntpEventInd(
                    mdw_fwtSetNotRequestReq(
                        p_portNumber, 
                        PX_USER_PRIORITY, 
                        p_linkId,  
                        p_remotePortNumber, 
                        p_linkPortNumber
                    )  
                ),
                false 
            ); 
        } // End of function f_fntpAwaitFwtUpdate
        
        /**
         * @desc Wait for MN_Request_request/FWT Delete notification from IUT to Management layer
         * @param p_reference		The reference value associated to the provided port number
         * @verdict Unchanged on success, set to fail on error (e_timeout)
         */
        function f_fntpAwaitFwtDelete( 
            in template (value) integer p_reference  
        ) runs on ItsCalm {
            
            f_cfFntpAwaitNotificationToManagement( 
                mw_cfFntpEventInd(
                    mdw_fwtDeleteFntp(
                        p_reference 
                    )  
                ),
                false 
            ); 
        } // End of function f_fntpAwaitFwtDelete()
        
        /**
         * @desc Generate a NF-SAP request and wait for a confirm message 
         * @param p_generateNfSapRequest  The NF-SAP request message to send 
         * @param p_nfSapRequestConfirm   The command confirm response
         * @param p_discard               Set to true if command confirm responses shall be discard, otherwise the function failed 
         * @param p_result                The command/request confirm response
         * @verdict Unchanged on success, fail otherwise
         */
        function f_fntpGenerateNfSApRequestWithConfirm( 
            in template (value) UtFntpEvent p_generateNfSapRequest, 
            in template (present) UtFntpEventInd p_nfSapRequestConfirm, 
            in boolean p_discard, 
            out UtFntpEventInd p_result 
        ) runs on ItsCalm { 
            
            f_utFntpEventResponse(
                p_generateNfSapRequest, 
                p_nfSapRequestConfirm, 
                p_discard,
                p_result
            );
            
        } // End of function f_fntpGenerateNfSApRequestWithConfirm 
        
        /**
         * @desc Generate a NFsapPrimitivesDown primitive without waiting for a confirm message 
         * @param p_utFntpEvent The NFsapPrimitivesDown primitive to send 
         * @verdict Unchanged
         */
        function f_fntpGenerateNfSApRequestWithoutConfirm( 
            in template (value) UtFntpEvent p_utFntpEvent 
        ) runs on ItsCalm { 
            
            f_utFntpEvent(p_utFntpEvent);
            
        } // End of function f_fntpGenerateNfSApRequestWithoutConfirm 
        
        /**
         * @desc Await for NFsapPrimitivesUp primitive 
         * @param p_portNumber	The port number value 
         * @param p_linkId	    The source link identifier
         * @verdict Unchanged on success, fail on error and inconc otherwise 
         */
        function f_fntpAwaitNfSapCommConfirm( 
            in template (present) PortNumber p_portNumber, 
            in template (present) Link_ID p_linkId
        ) runs on ItsCalm {
            var UtFntpEventInd v_utFntpEventInd;
            
            log("*** f_fntpAwaitNfSapCommConfirm: DEBUG: Expected template: ", 
                 mw_utFntpEventInd( 
                    mdw_checkNfFntpCommIndication(
                        vc_portNumber,                      // Destination port of DL-UNITDATA.request primitive
                        p_portNumber,                        // Source port of DL-UNITDATA.request primitive
                        p_linkId                            // Source address of DL-UNITDATA.request primitive
            )));
            tc_wait.start;
            alt {
                [] utPort.receive( 
                    mw_utFntpEventInd( 
                        mdw_checkNfFntpCommIndication(
                            vc_portNumber,                      // Destination port of DL-UNITDATA.request primitive
                            p_portNumber,                       // Source port of DL-UNITDATA.request primitive
                            p_linkId                            // Source address of DL-UNITDATA.request primitive
                ))) -> value v_utFntpEventInd {
                    tc_wait.stop;
                    log("*** f_fntpAwaitNfSapCommConfirm: INFO: NF-SAP Communication indication received:", v_utFntpEventInd, " ***");
                }
                [] utPort.receive( 
                    mw_utFntpEventInd( 
                        mw_checkNfFntpCommIndication_any
                )) -> value v_utFntpEventInd {
                    tc_wait.stop;
                    log("*** f_fntpAwaitNfSapCommConfirm: INFO: Unexpected NF-SAP Communication indication received:", v_utFntpEventInd, " ***");
                    f_selfOrClientSyncAndVerdict("error", e_error);
                }
                [] utPort.receive(UtFntpEventInd:?) -> value v_utFntpEventInd {
                    tc_wait.stop;
                    log("*** f_fntpAwaitNfSapCommConfirm: INFO: Unknown NF-SAP Communication indication received:", v_utFntpEventInd, " ***");
                    f_selfOrClientSyncAndVerdict("error", e_error);
                }
                [] tc_wait.timeout {
                    log("*** f_fntpAwaitNfSapCommConfirm: ERROR: Timeout while waiting for event check result ***");
                    f_selfOrClientSyncAndVerdict("error", e_timeout);
                }
            } // End of 'alt' statement
        } // End of function f_fntpAwaitNfSapCommConfirm 
        
        /**
         * @desc Call this method to remove entry created by f_initializeFntpForwardingTable() in FNTP Forwarding Table
         * @verdict Unchanged on success, fail on error and inconc otherwise
         */
reinaortega's avatar
reinaortega committed
        function f_unInitializeFntpForwardingTable() runs on ItsCalm {
            // check c_portDyn
            // Send for FTN-SOCKET.request & Wait for FTN-SOCKET.confirm
garciay's avatar
garciay committed
            
            f_utFntpEventResponse( 
                m_generateNfFntpPortDeletionRequest( 
                    f_getIutServiceRef(), 
                    vc_portNumber 
                ), 
                mw_utFntpEventInd( 
                    mw_fntpPortConfirm( 
                        f_getIutServiceRef(), 
                        c_unknown_portLong  
                    )  
                ), 
                false, 
                vc_utEventInd.utFntpEventInd  
            );
            
            if (PICS_ITS_MGT_NOT) {
                // And wait for a MN-SAP.MN-REQUEST/FWTupdate message sent to ITS management entity to update the forwarding table
                f_fntpAwaitFwtDelete(
                    vc_reference 
                );
            }
        } // End of function f_unInitializeFntpForwardingTable
        
        /**
         * @desc Trigger a basic FNTPNPDU to create an entry in forwarding table for a known peer station 
garciay's avatar
garciay committed
         * @verdict Unchanged on success, fail on error and inconc otherwise
reinaortega's avatar
reinaortega committed
        function f_setupKnownPeerStation() runs on ItsCalm { 
garciay's avatar
garciay committed
            f_sendBasicFntpNpdu( 
                f_getIutRemotePortNumberValue(), 
                vc_portNumber,  
                m_llServiceAddr(mw_linkId(f_getIutRemoteDestCiidUc(), f_getIutWlLocalCiid())), 
                m_llServiceAddr(mw_linkId(f_getIutWlLocalCiid(), f_getIutWlLocalCiid())) 
            );
            if (PICS_ITS_MGT_NOT) {
                // And wait for a MN-SAP.MN-REQUEST/FWTupdate message sent to ITS management entity to update the forwarding table
                f_fntpAwaitFwtUpdate( 
                    vc_portNumber, 
                    mw_linkId(f_getIutRemoteDestCiidUc(), f_getIutWlLocalCiid()), 
                    f_getIutRemotePortNumberValue(), 
                    vc_portNumber 
                );
            }
            // And wait for NF-SAP Comm.ind message sent by the FNTP to the ITS facilities entity 
            f_fntpAwaitNfSapCommConfirm(
                f_getIutRemotePortNumberValue(), 
garciay's avatar
garciay committed
                m_linkId(f_getIutRemoteDestCiidUc(), f_getIutWlLocalCiid())  
            );
        } // End of function f_setupKnownPeerStation
        
    } // End of group preambles
    
garciay's avatar
garciay committed
    /**
     * @desc Postambule functions
     */
    group postambles {
        
        /**
         * @desc The default postamble.
         */
reinaortega's avatar
reinaortega committed
        function f_poDefault() runs on ItsCalm {
garciay's avatar
garciay committed
     * @desc Message triggreing functions
garciay's avatar
garciay committed
    group messagesTriggering {
garciay's avatar
garciay committed
         * @desc    Triggers test adapter to send FNTP basic NDPU
         * @param   p_sourcePort        	Source port (c_portRtr or c_portHst)
         * @param   p_destinationPort  		Destination port (c_portRtr or c_portHst)
         * @param   p_inSapSourceAddress    IN-SAP source port
         * @param   p_inSapDestAddress   	IN-SAP destination port
garciay's avatar
garciay committed
        function f_sendBasicFntpNpdu(  
            in template (value) PortNumber p_sourcePort, 
            in template (value) PortNumber p_destinationPort, 
            in template (value) LLserviceAddr p_inSapSourceAddress, 
            in template (value) LLserviceAddr p_inSapDestAddress 
        ) runs on ItsCalm { 
            fntpPort.send(
                m_fntpReq( 
                    m_generateFntpNpdu(
                        p_inSapSourceAddress, 
                        p_inSapDestAddress, 
                        bit2oct( 
                            encvalue( 
                                m_fntpBasicNpdu( 
                                    p_sourcePort, 
                                    p_destinationPort
                                ) 
                            ) 
                        ) 
                    )
                )
            );
        } // End of function f_sendBasicFntpNpdu
garciay's avatar
garciay committed
         * @desc    Triggers test adapter to send FNTP forwarding NDPU
         * @param   p_sourcePort        	Source port (c_portRtr or c_portHst)
         * @param   p_destinationPort   	Destination port (c_portRtr or c_portHst)
         * @param   p_fromPort         	 	Forwarding source port
         * @param   p_toPort            	Forwarding destination port
         * @param   p_inSapSourceAddress	IN-SAP source port
         * @param   p_inSapDestAddress   	IN-SAP destination port
         * @param   p_counter           	Expected value of FNTP packet counter counter field
         * @param   p_hops                  N-hops value
         * @verdict Unchanged
garciay's avatar
garciay committed
        function f_sendForwardingNpdu(
            in template (value) PortNumber p_sourcePort, 
            in template (value) PortNumber p_destinationPort, 
            in template (value) PortNumber p_fromPort, 
            in template (value) PortNumber p_toPort, 
            in template (value) LLserviceAddr p_inSapSourceAddress, 
            in template (value) LLserviceAddr p_inSapDestAddress, 
            in template (value) FNTPpacketCounter p_counter, 
            in template (value) FNTPhopCount p_hops 
        ) runs on ItsCalm { 
            fntpPort.send(
                m_fntpReq( 
                    m_generateFntpNpdu(
                        p_inSapSourceAddress, 
                        p_inSapDestAddress, 
                        bit2oct( 
                            encvalue( 
                                md_fntpForwardingNpdu( 
                                    p_sourcePort, 
                                    p_destinationPort, 
                                    p_hops,
                                    p_fromPort,
                                    p_toPort,
                                    p_counter 
                                ) 
                            ) 
                        ) 
                    ) 
                ) 
            ); 
        } // End of function f_sendForwardingNpdu
        
        /**
         * @desc    Triggers test adapter to send FNTP NDPU
garciay's avatar
garciay committed
         * @param   p_sourcePort        	Source port number
         * @param   p_destinationPort   	Destination port number
         * @param   p_inSapSourceAddress	IN-SAP source port
         * @param   p_inSapDestAddress   	IN-SAP destination port
         * @param   p_hops              	N-hops value
         * @verdict Unchanged
garciay's avatar
garciay committed
        function f_sendExtendedFntpNpdu(
            in template (value) PortNumber p_sourcePort, 
            in template (value) PortNumber p_destinationPort, 
garciay's avatar
garciay committed
            in template (value) LLserviceAddr p_inSapSourceAddress, 
            in template (value) LLserviceAddr p_inSapDestAddress, 
            in FNTPhopCount p_hops 
reinaortega's avatar
reinaortega committed
        ) runs on ItsCalm { 
garciay's avatar
garciay committed
            fntpPort.send(
                m_fntpReq( 
                    m_generateFntpNpdu(
                        p_inSapSourceAddress, 
                        p_inSapDestAddress, 
                        bit2oct( 
                            encvalue( 
                                m_fntpExtendedNpdu( 
                                    p_sourcePort, 
                                    p_destinationPort, 
                                    p_hops
                                ) 
garciay's avatar
garciay committed
        } // End of function f_sendExtendedFntpNpdu
        
        /**
         * @desc    Triggers lower tester to send FNTP station-internal NDPU with several hops and an invalid control field
         * @param   p_sourcePort            Source port 
         * @param   p_destinationPort       Destination port 
garciay's avatar
garciay committed
         * @param   p_inSapSourceAddress    IN-SAP source port 
         * @param   p_inSapDestAddress      IN-SAP destination port 
         * @param   p_hops                  N-hops value 
garciay's avatar
garciay committed
         * @verdict Unchanged
garciay's avatar
garciay committed
        function f_sendFntpNpduInvalidCtrlField( 
            in template (value) PortNumber p_sourcePort, 
            in template (value) PortNumber p_destinationPort, 
garciay's avatar
garciay committed
            in template (value) LLserviceAddr p_inSapSourceAddress, 
            in template (value) LLserviceAddr p_inSapDestAddress, 
            in template (value) FNTPhopCount p_hops 
reinaortega's avatar
reinaortega committed
        ) runs on ItsCalm { 
garciay's avatar
garciay committed
            fntpPort.send(
                m_fntpReq( 
                    m_generateFntpNpdu(
                        p_inSapSourceAddress, 
                        p_inSapDestAddress, 
                        bit2oct( 
                            encvalue( 
                                md_fntpExtendedNpdu_invalidCtrlField( 
                                    p_sourcePort, 
                                    p_destinationPort, 
                                    p_hops 
                                ) 
garciay's avatar
garciay committed
        } // End of function f_sendFntpNpduInvalidCtrlField
        
        /**
         * @desc    Triggers lower tester to send FNTP station-internal NDPU with bit5 set 
         * @param   p_sourcePort            Source port 
         * @param   p_destinationPort       Destination port 
garciay's avatar
garciay committed
         * @param   p_inSapSourceAddress    IN-SAP source port 
         * @param   p_inSapDestAddress      IN-SAP destination port 
         * @verdict Unchanged
garciay's avatar
garciay committed
        function f_sendFntpNpduInvalidBitSet( 
            in template (value) PortNumber p_sourcePort, 
            in template (value) PortNumber p_destinationPort, 
garciay's avatar
garciay committed
            in template (value) LLserviceAddr p_inSapSourceAddress, 
            in template (value) LLserviceAddr p_inSapDestAddress 
reinaortega's avatar
reinaortega committed
        ) runs on ItsCalm { 
garciay's avatar
garciay committed
            fntpPort.send(
                m_fntpReq( 
                    m_generateFntpNpdu(
                        p_inSapSourceAddress, 
                        p_inSapDestAddress, 
                        bit2oct( 
                            encvalue( 
                                md_fntpExtendedNpdu_invalidBitSet( 
                                    p_sourcePort, 
                                    p_destinationPort, 
                                    omit
                                ) 
garciay's avatar
garciay committed
        } // End of function f_sendFntpNpduInvalidBitSet
        
        /**
         * @desc    Triggers test adapter to send FNTP NDPU
garciay's avatar
garciay committed
         * @param   p_sourcePort        	Source port 
         * @param   p_destinationPort   	Destination port 
         * @param   p_inSapSourceAddress	IN-SAP source port 
         * @param   p_inSapDestAddress      IN-SAP destination port 
         * @param   p_hops              	N-hops value 
         * @param   p_rxCIP             	Receive (RX) parameter settings
         * @param   p_txCIP             	Transmit (TX) parameters of a VCI
         * @param   p_accessParams          Access parameters 
         * @verdict Unchanged
garciay's avatar
garciay committed
        function f_sendFntpNpduCip(
            in template (value) PortNumber p_sourcePort, 
            in template (value) PortNumber p_destinationPort, 
garciay's avatar
garciay committed
            in template (value) LLserviceAddr p_inSapSourceAddress, 
            in template (value) LLserviceAddr p_inSapDestAddress, 
            in template (value) FNTPhopCount p_hops, 
reinaortega's avatar
reinaortega committed
            in template (value) RXcip p_rxCip, // TODO Perhaps this parameter is not required, p_accessParams would be enough
            in template (value) TXcip p_txCip, // TODO Perhaps this parameter is not required, p_accessParams would be enough
            in template (value) AccessParameters p_accessParams 
reinaortega's avatar
reinaortega committed
        ) runs on ItsCalm { 
garciay's avatar
garciay committed
            fntpPort.send(
                m_fntpReq( 
                    md_generateFntpNpduCip( 
                        p_inSapSourceAddress, 
                        p_inSapDestAddress, 
                        bit2oct( 
                            encvalue( 
                                md_fntpExtendedNpdu_cip( 
                                    p_sourcePort, 
                                    p_destinationPort, 
                                    p_hops, 
                                    p_rxCip, // TODO Perhaps this parameter is not required, p_accessParams would be enough
                                    p_txCip // TODO Perhaps this parameter is not required, p_accessParams would be enough
                                ) 
garciay's avatar
garciay committed
                        ), 
                        p_accessParams 
                    ) 
garciay's avatar
garciay committed
        } // End of function f_sendFntpNpduCip
        
        /**
         * @desc    Triggers test adapter to send FNTP forwarding NDPU with an unknown ITS-SCU-ID
         * @param   p_sourcePort        Source port (c_portRtr or c_portHst)
         * @param   p_destinationPort   Destination port (c_portRtr or c_portHst)
         * @param   p_fromPort          Forwarding source port
         * @param   p_toPort            Forwarding destination port
         * @param   p_sourcePort        IN-SAP source port
         * @param   p_destinationPort   IN-SAP destination port
         * @param   p_counter           Expected value of FNTP packet counter counter field
         * @param   p_hops              N-hops value
garciay's avatar
garciay committed
         * @verdict Unchanged
garciay's avatar
garciay committed
        function f_sendFntpForwardingNpduWithUnknownItsSciId(
            in template (value) PortNumber p_sourcePort, 
            in template (value) PortNumber p_destinationPort, 
            in template (value) PortNumber p_fromPort, 
            in template (value) PortNumber p_toPort,
garciay's avatar
garciay committed
            in template (value) LLserviceAddr p_inSapSourceAddress, 
            in template (value) LLserviceAddr p_inSapDestAddress, 
            in template (value) FNTPpacketCounter p_counter, 
            in template (value) FNTPhopCount p_hops 
reinaortega's avatar
reinaortega committed
        ) runs on ItsCalm { 
garciay's avatar
garciay committed
            fntpPort.send(
                m_fntpReq( 
                    m_generateFntpNpdu( 
                        p_inSapSourceAddress, 
                        p_inSapDestAddress, 
                        bit2oct( 
                            encvalue( 
                                md_fntpForwardingNpdu_unknownItsScuId(