ItsAutoInterop_TestCases.ttcn 34.2 KB
Newer Older
module ItsAutoInterop_TestCases {
    
    // Libcommon
    import from LibCommon_VerdictControl all;
    import from LibCommon_Sync all;
    import from LibCommon_BasicTypesAndValues all;
    import from LibCommon_DataStrings all;
    import from LibCommon_Time all;
    
    // LibItsCommon
    import from LibItsCommon_Functions all;
    import from LibItsExternal_TypesAndValues all;
    
    // LibItsGeoNetworking
    import from LibItsGeoNetworking_TypesAndValues all;
    import from LibItsGeoNetworking_Functions all;
    import from LibItsGeoNetworking_Templates all;
    import from LibItsGeoNetworking_Pixits all;
    import from LibItsGeoNetworking_TestSystem all;
    
    // AtsInterop
    import from ItsAutoInterop_TypesAndValues all;
    import from ItsAutoInterop_Templates all;
    import from ItsAutoInterop_Functions all;
    import from ItsAutoInterop_Pics all;
    import from ItsAutoInterop_Pixits all;
    import from ItsAutoInterop_TestSystem all;
    
    /**
     * @desc    Verify complete forwarding message scenario (GREEDY, GREEDY, GREEDY) 
     * <pre>
     * Pics Selection: 
     * Config Id: CF-01
     * Initial conditions:
     *  with {
     *      itsGnNonAreaForwardingAlgorithm of EUT1 (source) set to GREEDY
     *      itsGnNonAreaForwardingAlgorithm of EUT2 (forwarder) set to GREEDY
     *      itsGnNonAreaForwardingAlgorithm of EUT3 (neighbour) set to GREEDY
     *      itsGnNonAreaForwardingAlgorithm of EUT4 is SIMPLE
     *  }
     * Expected behaviour:
     *  ensure that {
     *      when {
     *         EUT1 is requested to broadcast DEN message
     *             containing GBC packet
     *                 containing Basic Header
     *                     containing RHL field
     *                 containing DestinationArea
     *                     indicating the GEOA_AREA2
     *      }
     *      then {
     *          EUT1 sends a LL packet
     *              containg a destination MAC address
     *                  indicating the EUT2 address
     *              containing GBC packet
     *                  containing Basic Header
     *                      containing RHL field
     *                  containing DestinationArea
     *                      indicating the GEOA_AREA2
     *                  containing Payload
     *                      containing the DEN message
     *      }
     *  }
     * </pre>
     *
     * @see         Draft ETSI TS yyy xxx-2 V0.0.8 (2017-02) TD_AUTO_IOT_DENM_MFW_BV_01
     * @reference   ETSI EN 302 636-4-1 Clauses D & E2
     */
    testcase TC_AUTO_IOT_DENM_MFW_BV_01() runs on ItsMtc system ItsAutoInteropGeoNetworkingSystem {
        
        // Local variables
        var ItsAutoInteropGeonetworking v_eut1;
        var ItsAutoInteropGeonetworking v_eut2;
        var ItsAutoInteropGeonetworking v_eut3;
        var ItsAutoInteropGeonetworking v_eut4;
        
        // Test control
        /*if (not PICS_GN_LS_FWD) {
            log("*** " & testcasename() & ": PICS_GN_LS_FWD required for executing the TC ***");
            setverdict(inconc);
            stop;
        }*/
        
        // Test component configuration
        f_mtcCf01Up(v_eut1, v_eut2, v_eut3, v_eut4);
        
        // Preamble
        
        // Start components
        v_eut1.start(f_TC_AUTO_IOT_DENM_MFW_BV_01_eut1(v_eut1, 0));
        v_eut2.start(f_TC_AUTO_IOT_DENM_MFW_BV_01_eut2(v_eut2, 1));
        v_eut3.start(f_TC_AUTO_IOT_DENM_MFW_BV_01_eut3(v_eut3, 2));
        v_eut4.start(f_TC_AUTO_IOT_DENM_MFW_BV_01_eut4(v_eut4, 3));
        
        // Synchronization
        f_serverSyncNClientsAndStop(4, {c_prDone, c_tbDone, c_poDone});
        
        // Cleanup
        f_mtcCf01Down(v_eut1, v_eut2, v_eut3, v_eut4);
        
    } // End of TC_AUTO_IOT_DENM_MFW_BV_01
    
    group g_TC_AUTO_IOT_DENM_MFW_BV_01 { 
        
        /**
         * @desc    Behavior function for EUT1 (TC_AUTO_IOT_DENM_MFW_BV_01)
         */
        function f_TC_AUTO_IOT_DENM_MFW_BV_01_eut1(
                                                   in ItsAutoInteropGeonetworking p_eut, 
                                                   in integer p_eut_id
        ) runs on ItsAutoInteropGeonetworking {
            
            // Local variables
            var GeoNetworkingInd v_gnInd;
            var template (value) Payload v_payload;
            
            // Test component configuration
            f_cfPtcUp(p_eut);
            
            // Preamble
            f_prDefault();
            f_selfOrClientSyncAndVerdict(c_prDone, e_success);
            
            // Test Body
            tc_ac.start;
            alt {
                [] geoNetworkingPort.receive( // Filter broadcasted DENM
                    mw_geoNwInd_withLinkLayerDestination(
                        mw_geoNwPdu(
                            mw_geoNwTsbPacketWithNextHeader_denm(
                                ?,
                                ?,
                                e_btpB, 
                                mw_denm_stationId(
                                    PX_EUT_DESC[p_eut_id].stationId
                         ))),
                         PX_EUT_DESC[1].ll_mac_address
                )) -> value v_gnInd { //  Receives the triggered DENM message
                    tc_ac.stop;
                    // Re-send DEN message to EUT2s
                    eutGeoNetworkingPort.send(
                                              m_forward_geoNetworkingInd(
                                                  v_gnInd
                    ));
                    tc_ac.start;
                    repeat;
                }
                [] geoNetworkingPort.receive( 
                    mw_geoNwInd_withLinkLayerDestination(
                        mw_geoNwPdu(
                            mw_geoNwTsbPacketWithNextHeader_denm(
                                ?,
                                ?,
                                e_btpB, 
                                mw_denm_stationId(
                                    complement(PX_EUT_DESC[p_eut_id].stationId)
                         ))),
                         ?
                )) -> value v_gnInd { // Receives a broadcast MAC address
                    tc_ac.stop;
                    log("*** " & testcasename() & ": FAIL: Unexpected DEN message received ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                }
                // TODO Check unexpected messages on eutGeoNetworkingPort port
                [] eutGeoNetworkingPort.receive { // TODO Use a default
                    tc_ac.stop;
                    tc_ac.start;
                    repeat;
                }
                [] geoNetworkingPort.receive { // TODO Use a default
                    tc_ac.stop;
                    tc_ac.start;
                    repeat;
                }
                [] tc_ac.timeout {
                    log("*** " & testcasename() & ": PASS: Forwarding message scenario (GREEDY, GREEDY, GREEDY) succeed ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                }
            }
            
            // Postamble
            f_poDefault();
            f_cfPtcDown(p_eut);
            
        } // End of f_TC_AUTO_IOT_DENM_MFW_BV_01_eut1
        
        /**
         * @desc    Behavior function for EUT2 (TC_AUTO_IOT_DENM_MFW_BV_01)
         */
        function f_TC_AUTO_IOT_DENM_MFW_BV_01_eut2(
                                                   in ItsAutoInteropGeonetworking p_eut, 
                                                   in integer p_eut_id
        ) runs on ItsAutoInteropGeonetworking {
            
            // Local variables
            var EutGeoNetworking v_eutGeoNw;
            
            // Test component configuration
            f_cfPtcUp(p_eut);
            
            // Preamble
            f_prNeighbour();
            f_selfOrClientSyncAndVerdict(c_prDone, e_success);
            
            // Test Body
            tc_ac.start;
             alt {
                [] eutGeoNetworkingPort.receive(
                    mw_eutGeoNwInd(
                        mw_geoNwPdu(
                            mw_geoNwTsbPacketWithNextHeader_denm(
                                ?,
                                ?,
                                e_btpB,
                                mw_denm_stationId(
                                    PX_EUT_DESC[0].stationId
                ))))) -> value v_eutGeoNw { // Unexpected DEN message
                    tc_ac.stop;
                    // Now, we have to check for EUT4 to broadcast the DENM message
                    tc_ac.start;
                    repeat;
                }
                [] eutGeoNetworkingPort.receive(
                    mw_eutGeoNwInd_withLinkLayerDestination(
                        mw_geoNwPdu(
                            mw_geoNwTsbPacketWithNextHeader_denm(
                                ?,
                                ?,
                                e_btpB, 
                                mw_denm_stationId(
                                    PX_EUT_DESC[3].stationId
                         ))),
                         c_llBroadcast
                )) -> value v_eutGeoNw { // Receives a broadcast MAC address from EUT4
                    tc_ac.stop;
                    log("*** " & testcasename() & ": PASS: DEN message was broadcasted by EUT4 ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                }
                [] eutGeoNetworkingPort.receive { // TODO Use a default
                    tc_ac.stop;
                    tc_ac.start;
                    repeat;
                }
                [] geoNetworkingPort.receive { // TODO Use a default
                    tc_ac.stop;
                    tc_ac.start;
                    repeat;
                }
                [] tc_ac.timeout {
                    log("*** " & testcasename() & ": FAIL: Forwarding message scenario (GREEDY, GREEDY, GREEDY) is incomplete ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                }
            } // End of 'alt' statement
            
            // Postamble
            f_poDefault();
            f_cfPtcDown(p_eut);
            
        } // End of f_TC_AUTO_IOT_DENM_MFW_BV_01_eut2
        
        /**
         * @desc    Behavior function for EUT3 (TC_AUTO_IOT_DENM_MFW_BV_01)
         */
        function f_TC_AUTO_IOT_DENM_MFW_BV_01_eut3(
                                                   in ItsAutoInteropGeonetworking p_eut, 
                                                   in integer p_eut_id
        ) runs on ItsAutoInteropGeonetworking {
            
            // Local variables
            var EutGeoNetworking v_eutGeoNw;
            
            // Test component configuration
            f_cfPtcUp(p_eut);
            
            // Preamble
            f_prNeighbour();
            f_selfOrClientSyncAndVerdict(c_prDone, e_success);
            
            // Test Body
            tc_ac.start;
             alt {
                [] eutGeoNetworkingPort.receive(
                    mw_eutGeoNwInd_withLinkLayerDestination(
                        mw_geoNwPdu(
                            mw_geoNwTsbPacketWithNextHeader_denm(
                                ?,
                                ?,
                                e_btpB, 
                                mw_denm_stationId(
                                    PX_EUT_DESC[3].stationId
                         ))),
                         c_llBroadcast
                )) -> value v_eutGeoNw { // Receives a broadcast MAC address from EUT4
                    tc_ac.stop;
                    log("*** " & testcasename() & ": PASS: DEN message was broadcasted by EUT4 ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                }
                [] eutGeoNetworkingPort.receive { 
                    log("*** " & testcasename() & ": FAIL: Unexpected message was received ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                }
                [] geoNetworkingPort.receive { // TODO Use a default
                    tc_ac.stop;
                    tc_ac.start;
                    repeat;
                }
                [] tc_ac.timeout {
                    log("*** " & testcasename() & ": FAIL: Forwarding message scenario (GREEDY, GREEDY, GREEDY) is incomplete ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                }
            } // End of 'alt' statement
            
            // Postamble
            f_poDefault();
            f_cfPtcDown(p_eut);
            
        } // End of f_TC_AUTO_IOT_DENM_MFW_BV_01_eut3
        
        /**
         * @desc    Behavior function for EUT4 (TC_AUTO_IOT_DENM_MFW_BV_01)
         */
        function f_TC_AUTO_IOT_DENM_MFW_BV_01_eut4(
                                                   in ItsAutoInteropGeonetworking p_eut, 
                                                   in integer p_eut_id
        ) runs on ItsAutoInteropGeonetworking {
            
            // Local variables
            var GeoNetworkingInd v_gnInd;
            var EutGeoNetworking v_eutGeoNw;
            var integer v_denm_counter := 0;
            
            // Test component configuration
            f_cfPtcUp(p_eut);
            
            // Preamble
            f_prNeighbour();
            f_selfOrClientSyncAndVerdict(c_prDone, e_success);
            
            // Test Body
            tc_ac.start;
             alt {
                [] eutGeoNetworkingPort.receive(
                    mw_eutGeoNwInd_withLinkLayerDestination(
                        mw_geoNwPdu(
                            mw_geoNwTsbPacketWithNextHeader_denm(
                                ?,
                                ?,
                                e_btpB,
                                mw_denm_stationId(
                                    PX_EUT_DESC[0].stationId
                         ))),
                         PX_EUT_DESC[p_eut_id].ll_mac_address
                )) -> value v_eutGeoNw { // Receive a DEN message from EUT2
                    tc_ac.stop;
                    // Now check that EUT4 brodcasts the DENM message
                    tc_ac.start;
                    repeat;
                }
                [] geoNetworkingPort.receive(
                    mw_geoNwInd_withLinkLayerDestination(
                        mw_geoNwPdu(
                            mw_geoNwTsbPacketWithNextHeader_denm(
                                ?,
                                ?,
                                e_btpB,
                                mw_denm_stationId(
                                    PX_EUT_DESC[3].stationId
                         ))),
                         c_llBroadcast
                )) -> value v_gnInd { // EUT4 has brodcasted the DENM message
                    tc_ac.stop;
                    // Re-send DEN message to the other EUTs
                    eutGeoNetworkingPort.send(
                                              m_forward_geoNetworkingInd(
                                                  v_gnInd
                    ));
                    log("*** " & testcasename() & ": PASS: Forwarding message scenario (GREEDY, GREEDY, GREEDY) succeed ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                }
                [] eutGeoNetworkingPort.receive { // TODO Use a default
                    tc_ac.stop;
                    tc_ac.start;
                    repeat;
                }
                [] geoNetworkingPort.receive { // TODO Use a default
                    tc_ac.stop;
                    tc_ac.start;
                    repeat;
                }
                [] tc_ac.timeout {
                    log("*** " & testcasename() & ": FAIL: Forwarding message scenario (GREEDY, GREEDY, GREEDY) is incomplete ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                }
            } // End of 'alt' statement
            
            // Postamble
            f_poDefault();
            f_cfPtcDown(p_eut);
            
        } // End of f_TC_AUTO_IOT_DENM_MFW_BV_01_eut4
        
    } // End of group g_TC_AUTO_IOT_DENM_MFW_BV_01
    
    /**
     * @desc    Verify complete Road Works Warning scenario
     * <pre>
     * Pics Selection: 
     * Config Id: CF-02
     * Initial conditions:
     *  with {
     *      EUT1 sends Road Work Warning DEN messages D1 
     *          containing a speedLimit
     *              indicating the value 30
     *          containing a drivingLaneStatus
     *              indicating the value 0001B
     *          containing a trafficFlowRule
     *              indicating the value passToRight
     *          and EUT1 sends a DEN message D2
     *              containing a speedLimit
     *                  indicating the value 30
     *              containing a drivingLaneStatus
     *                  indicating the value 0011B
     *              containing a trafficFlowRule
     *                  indicating the value passToRight
     *          and EUT1 sends a DEN message D3
     *              containing a speedLimit
     *                  indicating the value 30
     *              containing a drivingLaneStatus
     *                  indicating the value 0101B
     *              containing a trafficFlowRule
     *                  indicating the value passToLeft
     *          and EUT2 (vehicle) receives the DEN messages D1, D2 and D3
     *  }
     * Expected behaviour:
     *  ensure that {
     *      when {
     *          EUT2 (vehicle) reaches the position POS0
     *      }
     *      then {
     *          EUT2 (vehicle) already indicates the speed limit information
     *      }
     *      when {
     *          EUT2 (vehicle) reaches the position POS1
     *      }
     *      then {
     *          EUT2 (vehicle) still indicates the speed limit information 
     *          and EUT2 (vehicle) already indicates the most outer lane closed
     *          and EUT2 (vehicle) already indicates the hardshoulder opened
     *      }
     *      when {
     *          EUT2 (vehicle) reaches the position POS2
     *      }
     *      then {
     *          EUT2 (vehicle) still indicates the speed limit information 
     *          and EUT2 (vehicle) already indicates the two most outer lanes closed
     *          and EUT2 (vehicle) already indicates the hardshoulder opened
     *      }
     *      when {
     *          EUT2 (vehicle) reaches the position POS3
     *      }
     *      then {
     *          EUT2 (vehicle) still indicates the speed limit information 
     *          and EUT2 (vehicle) already indicates the most right lane closed
     *          and EUT2 (vehicle) already indicates the hardshoulder closed
     *      }
     *      when {
     *          EUT2 (vehicle) reaches the position POS4
     *      }
     *      then {
     *          EUT2 (vehicle) stops indicating the speed limit information 
     *          and EUT2 (vehicle) stops indicating the lanes status
     *      }
     *  }
     * </pre>
     *
     * @see         Draft ETSI TS yyy xxx-2 V0.0.8 (2017-02) TD_AUTO_IOT_DENM_RWW_BV_01
     * @reference   ETSI EN 302 637-3 [5]
     */
    testcase TC_AUTO_IOT_DENM_RWW_BV_01() runs on ItsMtc system ItsAutoInteropGeoNetworkingSystem {
        
        // Local variables
        var ItsAutoInteropGeonetworking v_eut1;
        var ItsAutoInteropGeonetworking v_eut2;
        
        // Test control
        /*if (not PICS_GN_LS_FWD) {
            log("*** " & testcasename() & ": PICS_GN_LS_FWD required for executing the TC ***");
            setverdict(inconc);
            stop;
        }*/
        
        // Test component configuration
        f_mtcCf02Up(v_eut1, v_eut2);
        
        // Preamble
        
        // Start components
        v_eut1.start(f_TC_AUTO_IOT_DENM_RWW_BV_01_eut1(v_eut1, 0));
        v_eut2.start(f_TC_AUTO_IOT_DENM_RWW_BV_01_eut2(v_eut2, 1));
        
        // Synchronization
        f_serverSyncNClientsAndStop(2, {c_prDone, c_tbDone, c_poDone});
        
        // Cleanup
        f_mtcCf02Down(v_eut1, v_eut2);
        
    } // End of TC_AUTO_IOT_DENM_RWW_BV_01
    
    group g_TC_AUTO_IOT_DENM_RWW_BV_01 { 
        
        /**
         * @desc    Behavior function for EUT1 (TD_AUTO_IOT_DENM_RWW_BV_01)
         */
        function f_TC_AUTO_IOT_DENM_RWW_BV_01_eut1(
                                                   in ItsAutoInteropGeonetworking p_eut,
                                                   in integer p_eut_id
        ) runs on ItsAutoInteropGeonetworking {
            
            // Local variables
            var GeoNetworkingInd v_gnInd;
            
            // Test component configuration
            f_cfPtcUp(p_eut);
            
            // Preamble
            f_prNeighbour();
            // Nothing to do
            f_selfOrClientSyncAndVerdict(c_prDone, e_success);
            
            // Test Body
            tc_ac.start;
            alt {
                [] geoNetworkingPort.receive(
                    mw_geoNwInd(
                        mw_geoNwPdu(
                            mw_geoNwTsbPacketWithNextHeader_denm(
                                ?,
                                ?,
                                e_btpB,
                                mw_denm_stationId(
                                    PX_EUT_DESC[p_eut_id].stationId
                ))))) -> value v_gnInd { // Receive a DEN message
                    tc_ac.stop;
                    // Re-send DEN message to the other EUTs
                    eutGeoNetworkingPort.send(
                                              m_forward_geoNetworkingInd(
                                                  v_gnInd
                    ));
                    tc_ac.start;
                    repeat;
                }
                [] tc_ac.timeout {
                    log("*** " & testcasename() & ": PASS: Test done ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                }
            } // End of 'alt' statement
            
            // Postamble
            f_poDefault();
            f_cfPtcDown(p_eut);
            
        } // End of f_TC_AUTO_IOT_DENM_RWW_BV_01_eut1
        
        /**
         * @desc    Behavior function for EUT2 (TD_AUTO_IOT_DENM_RWW_BV_01)
         */
        function f_TC_AUTO_IOT_DENM_RWW_BV_01_eut2(
                                                   in ItsAutoInteropGeonetworking p_eut,
                                                   in integer p_eut_id
        ) runs on ItsAutoInteropGeonetworking {
            
            // Local variables
            var GeoNetworkingInd v_gnInd;
            var EutGeoNetworking v_eutGeoNw;
            var HmiSignageEventInd v_hmiSignageEventInd;
            var integer v_counter;
            var integer is_on_position := -1; // Set to unknown position
            
            // Test component configuration
            f_cfPtcUp(p_eut);
            
            // Preamble
            f_prNeighbour();
            // Wait for EUT_1 DEN messages
            v_counter := 0;
            tc_ac.start;
            alt {
                [] eutGeoNetworkingPort.receive(
                    mw_eutGeoNwInd(
                        mw_geoNwPdu(
                            mw_geoNwTsbPacketWithNextHeader_denm(
                                ?,
                                ?,
                                e_btpB,
                                mw_denm_stationId
                )))) -> value v_eutGeoNw { // Receive a DEN message
                    tc_ac.stop;
                    v_counter := v_counter + 1;
                    if (v_counter < 3) {
                        tc_ac.start;
                    } else {
                        log("*** " & testcasename() & ": INFO: EUT2 (vehicle) does not receive RWW DENMs D1, D2 and D3 ***");
                        f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                    }
                }
                [] tc_ac.timeout {
                    log("*** " & testcasename() & ":FAIL: EUT2 (vehicle) does not receive RWW DENMs D1, D2 and D3 ***");
                    f_selfOrClientSyncAndVerdict(c_prDone, e_error);
                }
            } // End of 'alt' statement
            
            // Test Body
            tc_wait.start;
             alt {
                [] geoNetworkingPort.receive( 
                    mw_geoNwInd_withLinkLayerDestination(
                        mw_geoNwPdu(
                            mw_geoNwShbPacketWithNextHeader_cam(
                                ?,
                                ?,
                                e_btpB, 
                                mw_cam_stationId(
                                    -,
                                    PX_EUT_DESC[p_eut_id].stationId
                         ))),
                         c_llBroadcast
                )) -> value v_gnInd { //  Receives a broadcast MAC address
                    // TODO Compute position using PositionVector
                    // TODO Set the correct step
                    repeat;
                }
                [is_on_position == 0] hmiPort.receive(
                    HmiSignageEventInd:?/*TODO*/
                ) -> value v_hmiSignageEventInd {
                }
                [is_on_position == 1] hmiPort.receive(
                    HmiSignageEventInd:?/*TODO*/
                ) -> value v_hmiSignageEventInd {
                }
                [is_on_position == 2] hmiPort.receive(
                    HmiSignageEventInd:?/*TODO*/
                ) -> value v_hmiSignageEventInd {
                }
                [is_on_position == 3] hmiPort.receive(
                    HmiSignageEventInd:?/*TODO*/
                ) -> value v_hmiSignageEventInd {
                }
                [] eutGeoNetworkingPort.receive { // TODO Use default 
                    repeat;
                }
                [] geoNetworkingPort.receive { // TODO Use default
                    // Nothing to do
                    repeat;
                }
                [] tc_wait.timeout {
                    log("*** " & testcasename() & ": PASS: Road Works Warning scenario completed ***");
                    f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                }
             } // End of 'alt' statement
            
            // Postamble
            f_poDefault();
            f_cfPtcDown(p_eut);
            
        } // End of f_TC_AUTO_IOT_DENM_RWW_BV_01_eut2
        
    } // End of group g_TC_AUTO_IOT_DENM_RWW_BV_01
    
    /**
     * @desc    Verify complete neighbors detection scenario based on CA messages and/or beacons
     * <pre>
     * Pics Selection: 
     * Config Id: CF-03
     * Initial conditions:
     * with {
     *     EUT1 sends CA messages C1 
     *         containing cam
     *             containing camParameters
     *                 containing basicContainer 
     *                     containing referencePosition
     *                         indicating POSITION_1
     *     and EUT2 sends a CA message C2
     *             containing cam
     *                 containing camParameters 
     *                 containing basicContainer 
     *                     containing referencePosition
     *                         indicating POSITION_2
     *     and EUT3 sends a CA message C3
     *       containing cam
     *             containing camParameters
     *                 containing basicContainer 
     *                     containing referencePosition
     *                         indicating POSITION_3
     *     }
     * Expected behaviour:
     * ensure that {
     *     when {
     *         EUT1 receives C2
     *     }
     *     then {
     *         EUT1 still indicates EUT2 as neighbor
     *     }
     *     when {
     *         EUT1 receives C3
     *     }
     *     then {
     *         EUT1 still indicates EUT3 as neighbor
     *     }
     *     when {
     *         EUT2 receives C1
     *     }
     *     then {
     *         EUT2 still indicates EUT1 as neighbor
     *     }
     *     when {
     *         EUT2 receives C3
     *     }
     *     then {
     *         EUT2 still indicates EUT3 as neighbor
     *     }
     *     when {
     *         EUT3 receives C1
     *     }
     *     then {
     *         EUT3 still indicates EUT1 as neighbor
     *     }
     *     when {
     *         EUT3 receives C2
     *     }
     *     then {
     *         EUT3 still indicates EUT2 as neighbor
     *     }
     * }
     * </pre>
     *
     * @see         Draft ETSI TS yyy xxx-2 V0.0.8 (2017-02) TD_AUTO_IOT_CAM_NBD_BV_01
     * @reference   ETSI EN 302 636-2 ETSI EN 302 637-2 [4]
     */
    testcase TC_AUTO_IOT_CAM_NBD_BV_01() runs on ItsMtc system ItsAutoInteropGeoNetworkingSystem {
        
        // Local variables
        var ItsAutoInteropGeonetworking v_eut1;
        var ItsAutoInteropGeonetworking v_eut2;
        var ItsAutoInteropGeonetworking v_eut3;
        
        // Test control
        /*if (not PICS_GN_LS_FWD) {
            log("*** " & testcasename() & ": PICS_GN_LS_FWD required for executing the TC ***");
            setverdict(inconc);
            stop;
        }*/
        
        // Test component configuration
        f_mtcCf03Up(v_eut1, v_eut2, v_eut3);
        
        // Preamble
        
        // Start components
        v_eut1.start(f_TC_AUTO_IOT_CAM_NBD_BV_01_eut(v_eut1, 0));
        v_eut2.start(f_TC_AUTO_IOT_CAM_NBD_BV_01_eut(v_eut2, 1));
        v_eut3.start(f_TC_AUTO_IOT_CAM_NBD_BV_01_eut(v_eut3, 2));
        
        // Synchronization
        f_serverSyncNClientsAndStop(3, {c_prDone, c_tbDone, c_poDone});
        
        // Cleanup
        f_mtcCf03Down(v_eut1, v_eut2, v_eut3);
        
    } // End of TC_AUTO_IOT_CAM_NBD_BV_01
    
    group g_TC_AUTO_IOT_CAM_NBD_BV_01 { 
        
        /**
         * @desc    Behavior function for EUT (TD_AUTO_IOT_CAM_NBD_BV_01)
         */
        function f_TC_AUTO_IOT_CAM_NBD_BV_01_eut(
                                                 in ItsAutoInteropGeonetworking p_eut,
                                                 in integer p_eut_id
        ) runs on ItsAutoInteropGeonetworking {
            
            // Local variables
            var GeoNetworkingInd v_gnInd;
            var HmiNeighborEventInd v_hmiNeighborEventInd;
            var HmiNeighborEventInds v_expected_neighbors := {};
            
            // Build the list of the expected neighbors
            for (var integer i := 0; i < lengthof(PX_EUT_DESC); i := i + 1) {
                if (i != p_eut_id) {
                    var octetstring v := int2oct(PX_EUT_DESC[i].stationId, 4); // FIXME How to improve type conversion
                    v_expected_neighbors[lengthof(v_expected_neighbors)].mid := PX_EUT_DESC[i].mid;
                    v_expected_neighbors[lengthof(v_expected_neighbors)].stationId := oct2int(v); // FIXME How to improve type conversion
                }
            } // End of 'for' statement
            
            // Test component configuration
            f_cfPtcUp(p_eut);
            
            // Preamble
            f_prDefault();
            f_selfOrClientSyncAndVerdict(c_prDone, e_success);
            
            // Test Body
            tc_wait.start;
            alt { // TODO Add beacon support
                [] geoNetworkingPort.receive( // Filter broadcasted CAM
                    mw_geoNwInd_withLinkLayerDestination(
                        mw_geoNwPdu(
                            mw_geoNwShbPacketWithNextHeader_cam(
                                ?,
                                ?,
                                e_btpB, 
                                mw_cam_stationId(
                                    -,
                                    complement(PX_EUT_DESC[p_eut_id].stationId)
                         ))),
                         c_llBroadcast
                )) -> value v_gnInd { //  Receives a broadcast MAC address
                    // Broadcast CA message to the other EUTs
                    eutGeoNetworkingPort.send(
                                              m_forward_geoNetworkingInd(
                                                  v_gnInd
                    ));
                    repeat;
                }
                [] eutGeoNetworkingPort.receive( 
                    mw_eutGeoNwInd_withLinkLayerDestination(
                        mw_geoNwPdu(
                            mw_geoNwShbPacketWithNextHeader_cam(
                                ?,
                                ?,
                                e_btpB, 
                                mw_cam_stationId(
                                    -,
                                    PX_EUT_DESC[p_eut_id].stationId
                         ))),
                         c_llBroadcast
                )) { //  Receives a broadcast MAC address
                    // Receive CAM from other EUTs
                    repeat;
                }
                [] hmiPort.receive(
                    HmiNeighborEventInd:?/*TODO*/
                ) -> value v_hmiNeighborEventInd {
                    if (match(v_expected_neighbors, superset(m_hmiNeighborEventInd(v_hmiNeighborEventInd.mid, v_hmiNeighborEventInd.stationId)))) {
                        // Remove item
                        for (var integer i := 0; i < lengthof(v_expected_neighbors); i := i + 1) {
                            if (v_expected_neighbors[i].mid == v_hmiNeighborEventInd.mid) {
                                v_expected_neighbors[i] := {};
                                break;
                            }
                        }
                    } // else nothing to do
                    // Check if all neighbors were detected
                    if (lengthof(v_expected_neighbors) == 0) {
                        log("*** " & testcasename() & ": PASS: Neighbors were detected by EUT #", p_eut_id, " ***");
                        f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                    } else {
                        repeat;
                    }
                }
                [] tc_wait.timeout {
                    log("*** " & testcasename() & ": FAIL: Neighbors were not be detected by EUT #", p_eut_id, " ***");
                }
            } // End of 'alt' statement
            
            // Postamble
            f_poDefault();
            f_cfPtcDown(p_eut);
            
        } // End of f_TC_AUTO_IOT_CAM_NBD_BV_01_eut
        
    } // End of group g_TC_AUTO_IOT_CAM_NBD_BV_01
    
} // End of module AtsInterop_TestCases