ItsGeoNetworking_TpFunctions.ttcn 806 KB
Newer Older
berge's avatar
berge committed
                            m_geoNwReq_withLinkLayerDestination(
                                m_geoNwPdu(
                                    m_geoNwUnicastPacket(
                                        f_getPosition(c_compNodeC),
                                        f_longPosVector2ShortPosVector(v_longPosVectorNodeA),
                                        vc_localSeqNumber
berge's avatar
berge committed
                                    c_defaultHopLimit - 1
                                ),
                                -,
                                f_getIutMacAddress()
                            )
                        );
                        
                        tc_noac.start;
                        alt {
                            [] geoNetworkingPort.receive(
                                mw_geoNwInd(
                                    mw_geoNwPdu(
                                        mw_geoNwUnicastPacket(
                                            mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(v_longPosVectorNodeA)),
                                            ?
                                        )
                                    )
berge's avatar
berge committed
                            ) {
                                tc_noac.stop;
                                log("*** " & testcasename() & ": FAIL: Duplicate GUC was forwarded ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                            }
                            [] tc_noac.timeout {
                                log("*** " & testcasename() & ": PASS: Duplicate GUC not forwarded ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_success);                            
                            }
                        }
                        
                        // Postamble
                        f_poNeighbour();
                        
                    } // end f_GEONW_PON_GUC_GRD_BO_07_nodeB
                    
                    /**
                     * @desc    Behavior function for NodeC (TC_GEONW_PON_GUC_GRD_BO_07)
                     */
                    function f_GEONW_PON_GUC_GRD_BO_07_nodeC() runs on ItsGeoNetworking {
                        
                        // Local variables
                        var LongPosVector v_longPosVectorNodeA := f_getPosition(c_compNodeA);
                        
                        // Preamble
                        f_prNeighbour();
                        f_sendGeoNetMessage(
                            m_geoNwReq_withLinkLayerDestination(
                                m_geoNwPdu(
                                    m_geoNwUnicastPacket(
                                        f_getPosition(c_compNodeC),
                                        f_longPosVector2ShortPosVector(v_longPosVectorNodeA),
                                        vc_localSeqNumber
                                    ),
                                    -,
                                    c_defaultHopLimit
                                ),
                                -,
                                f_getIutMacAddress()
berge's avatar
berge committed
                        );
                        f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                        
                        // Test Body
                        tc_noac.start;
                        alt {
                            [] geoNetworkingPort.receive(
                                mw_geoNwInd(
                                    mw_geoNwPdu(
                                        mw_geoNwUnicastPacket(
                                            mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(v_longPosVectorNodeA)),
                                            ?
                                        )
                                    )
                                )
                            ) {
                                tc_noac.stop;
                                log("*** " & testcasename() & ": FAIL: Duplicate GUC was forwarded ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                            }
                            [] tc_noac.timeout {
                                log("*** " & testcasename() & ": PASS: Duplicate GUC not forwarded ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_success);                            
                            }
berge's avatar
berge committed
                        
                        // Postamble
                        f_poNeighbour();
                        
                    } // end f_GEONW_PON_GUC_GRD_BO_07_nodeC
                    
                } // end GEONW_PON_GUC_GRD_BO_07

			} // end gucGreedyForwarding

			group gucContentionBasedForwarding {
				
                group GEONW_PON_GUC_CBF_BV_01 {
                    
                    /**
                     * @desc    TP Function for TC_GEONW_PON_GUC_CBF_BV_01
                     */
                    function f_GEONW_PON_GUC_CBF_BV_01() runs on ItsMtc {
                        
                        // Local variables
                        var ItsGeoNetworking v_nodeB;
                        var ItsGeoNetworking v_nodeC;
                        
                        // Test control
                        if (not PICS_GN_GUC_SRC) {
                            log("*** " & testcasename() & ": PICS_GN_GUC_SRC required for executing the TC ***");
                            setverdict(inconc);
                            stop;
berge's avatar
berge committed
                        if (f_getNonAreaForwardingAlgorithm() != e_cbf) {
                            log("*** " & testcasename() & ": PICS_GN_NON_AREA_FORWARDING_ALGORITHM == e_cbf required for executing the TC ***");
                            setverdict(inconc);
                            stop;
                        }
                        
                        // Test component configuration
                        f_cf03Up();
                        
                        // Preamble
                        
                        // Start components
                        v_nodeB := f_getComponent(c_compNodeB);
                        v_nodeC := f_getComponent(c_compNodeC);
                        v_nodeB.start(f_GEONW_PON_GUC_CBF_BV_01_nodeB());
                        v_nodeC.start(f_GEONW_PON_GUC_CBF_BV_01_nodeC());
                        
                        // Synchronization
                        f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
                        
                        // Cleanup
                        f_cf03Down();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_01
berge's avatar
berge committed
                    /**
                     * @desc    Behavior function for NodeB (TC_GEONW_PON_GUC_CBF_BV_01)
                     */
                    function f_GEONW_PON_GUC_CBF_BV_01_nodeB() runs on ItsGeoNetworking {
                        
                        // Local variables
                        var LongPosVector v_longPosVectorNodeB := f_getPosition(c_compNodeB);
                        
                        // Preamble
                        f_prNeighbour();
                        f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                        
                        // Test Body
                        if(not f_utTriggerEvent(m_generateGeoUnicastMessage(v_longPosVectorNodeB.gnAddr))) {
                            log("*** " & testcasename() & ": INCONC: Trigger failed ***");
                            f_selfOrClientSyncAndVerdict(c_tbDone, e_timeout);
                        }
                        tc_ac.start;
                        alt {
                            [] geoNetworkingPort.receive(
                                mw_geoNwInd(
                                    mw_geoNwPdu(
                                        mw_geoNwUnicastPacket(
                                            mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(v_longPosVectorNodeB)),
                                            ?
                                        )
                                    )
                                )
                            ) {
                                tc_ac.stop;
                                log("*** " & testcasename() & ": PASS: GUC received ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                            }
                            [] tc_ac.timeout {
                                log("*** " & testcasename() & ": FAIL: GUC was not received ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                            }
                        }
                        
                        // Postamble
                        f_poNeighbour();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_01_nodeB
berge's avatar
berge committed
                    /**
                     * @desc    Behavior function for NodeC (TC_GEONW_PON_GUC_CBF_BV_01)
                     */
                    function f_GEONW_PON_GUC_CBF_BV_01_nodeC() runs on ItsGeoNetworking {
                        
                        // Local variables
                        var LongPosVector v_longPosVectorNodeB := f_getPosition(c_compNodeB);
                        
                        // Preamble
                        f_prNeighbour();
                        f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                        
                        // Test Body
                        tc_ac.start;
                        alt {
                            [] geoNetworkingPort.receive(
                                mw_geoNwInd(
                                    mw_geoNwPdu(
                                        mw_geoNwUnicastPacket(
                                            mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(v_longPosVectorNodeB)),
                                            ?
                                        )
                                    )
                                )
                            ) {
                                tc_ac.stop;
                                log("*** " & testcasename() & ": PASS: broadcasted GUC received ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                            }
                            [] tc_ac.timeout {
                                log("*** " & testcasename() & ": FAIL: GUC was not broadcasted ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                            }
                        }
                        
                        // Postamble
                        f_poNeighbour();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_01_nodeC
                                    
                } // end GEONW_PON_GUC_CBF_BV_01

                group GEONW_PON_GUC_CBF_BV_02 {
berge's avatar
berge committed
                    /**
                     * @desc    TP Function for TC_GEONW_PON_GUC_CBF_BV_02
                     */
                    function f_GEONW_PON_GUC_CBF_BV_02() runs on ItsMtc {
                        
                        // Local variables
                        var ItsGeoNetworking v_nodeB;
                        var ItsGeoNetworking v_nodeC;
                        var float v_distance := int2float(f_getCbfMaxCommunicationRange() - 10);
                        var LongPosVector v_longPosVectorIut, v_longPosVectorNodeA;
                        
                        // Test control
                        if (not PICS_GN_GUC_FWD) {
                            log("*** " & testcasename() & ": PICS_GN_GUC_FWD required for executing the TC ***");
                            setverdict(inconc);
                            stop;
                        }
                        if (f_getNonAreaForwardingAlgorithm() != e_cbf) {
                            log("*** " & testcasename() & ": PICS_GN_NON_AREA_FORWARDING_ALGORITHM == e_cbf required for executing the TC ***");
                            setverdict(inconc);
                            stop;
                        }
                        
                        // Test component configuration
                        f_cf03Up();
                        // re-compute NodeA's position.
                        v_longPosVectorIut := f_getIutLongPosVector();
                        v_longPosVectorNodeA := f_computePositionUsingDistance(v_longPosVectorIut, v_distance, 0);
                        v_longPosVectorNodeA.gnAddr := f_getTsGnLocalAddress(c_compNodeA);
                        
                        // Preamble
                        
                        // Start components
                        v_nodeB := f_getComponent(c_compNodeB);
                        v_nodeC := f_getComponent(c_compNodeC);
                        v_nodeB.start(f_GEONW_PON_GUC_CBF_BV_02_nodeB(v_distance, v_longPosVectorNodeA));
                        v_nodeC.start(f_GEONW_PON_GUC_CBF_BV_02_nodeC(v_longPosVectorNodeA));
                        
                        // Synchronization
                        f_serverSync2ClientsAndStop({c_prDone, c_msgSent, c_tbDone});
                        
                        // Cleanup
                        f_cf03Down();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_02
                    
                    /**
                     * @desc    Behavior function for NodeB (TC_GEONW_PON_GUC_CBF_BV_02)
                     * @param   p_distanceToNodeA       Distance between IUT and NodeA
                     * @param   p_longPosVectorNodeA    Position vector of NodeA
                     */
                    function f_GEONW_PON_GUC_CBF_BV_02_nodeB(in float p_distanceToNodeA, in LongPosVector p_longPosVectorNodeA) runs on ItsGeoNetworking {
                        
                        // Local variables
                        timer t_toCbf := (int2float(f_getCbfMaxTime())
                            + (
                                int2float(f_getCbfMinTime() - f_getCbfMaxTime())
                                / int2float(f_getCbfMaxCommunicationRange())
                            ) * p_distanceToNodeA) * 0.95 / 1000.0;
                        
                        // Preamble
                        f_prNeighbour();
                        f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                        
                        // Test Body
                        log("*** " & testcasename() & ": INFO: Message sent ***");
                        f_selfOrClientSyncAndVerdict(c_msgSent, e_success);
                        
                        tc_ac.start;
                        t_toCbf.start;
                        alt {
                            [] geoNetworkingPort.receive(
                                mw_geoNwInd(
                                    mw_geoNwPdu(
                                        mw_geoNwUnicastPacket(
                                            mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(p_longPosVectorNodeA)),
                                            ?
                                        )
                                    )
                                )
                            ) {
                                tc_ac.stop;
                                if(t_toCbf.running) {
                                    t_toCbf.stop;
                                    log("*** " & testcasename() & ": FAIL: IUT re-broadcasted the packet too early ***");
                                    f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                                }
                                else {
                                    log("*** " & testcasename() & ": PASS: Forwarded GUC received ***");
                                    f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                                }
                            }
                            [] t_toCbf.timeout {
                                log("*** " & testcasename() & ": INFO: Ready for receiving re-broadcasting ***");
                                repeat;
                            }
                            [] tc_ac.timeout {
                                log("*** " & testcasename() & ": FAIL: GUC was not forwarded ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                            }
                        }
                        
                        // Postamble
                        f_poNeighbour();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_02_nodeB
berge's avatar
berge committed
                    /**
                     * @desc    Behavior function for NodeC (TC_GEONW_PON_GUC_CBF_BV_02)
                     * @param   p_longPosVectorNodeA    Position vector of NodeA
                     */
                    function f_GEONW_PON_GUC_CBF_BV_02_nodeC(in LongPosVector p_longPosVectorNodeA) runs on ItsGeoNetworking {
                        
                        // Local variables
                        
                        // Preamble
                        f_prNeighbour();
                        f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                        
                        // Test Body
                        f_sendGeoNetMessage(
                            m_geoNwReq_withLinkLayerDestination(
                                m_geoNwPdu(
                                    m_geoNwUnicastPacket(
                                        f_getPosition(c_compNodeC),
                                        f_longPosVector2ShortPosVector(p_longPosVectorNodeA),
                                        vc_localSeqNumber
                                    ),
                                    -,
                                    c_defaultHopLimit
berge's avatar
berge committed
                                f_getIutMacAddress()
                            )
                        );
                        log("*** " & testcasename() & ": INFO: Message sent ***");
                        f_selfOrClientSyncAndVerdict(c_msgSent, e_success);
                        
                        tc_ac.start;
                        alt {
                            [] geoNetworkingPort.receive(
                                mw_geoNwInd(
                                    mw_geoNwPdu(
                                        mw_geoNwUnicastPacket(
                                            mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(p_longPosVectorNodeA)),
                                            ?
                                        )
berge's avatar
berge committed
                            ) {
                                tc_ac.stop;
                                log("*** " & testcasename() & ": PASS: Re-broadcasted GUC received ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                            }
berge's avatar
berge committed
                            [] tc_ac.timeout {
                                log("*** " & testcasename() & ": FAIL: GUC was not re-broadcasted ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                            }
berge's avatar
berge committed
                        
                        // Postamble
                        f_poNeighbour();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_02_nodeC
berge's avatar
berge committed
                } // end GEONW_PON_GUC_CBF_BV_02

				group GEONW_PON_GUC_CBF_BV_07 {
                
					/**
					 * @desc    TP Function for TC_GEONW_PON_GUC_CBF_BV_07
					 */
					function f_GEONW_PON_GUC_CBF_BV_07() runs on ItsMtc {
                    
						// Local variables
						var ItsGeoNetworking v_nodeB;
						var ItsGeoNetworking v_nodeC;
						var float v_distance := int2float(f_getCbfMaxCommunicationRange() - 10);
						var LongPosVector v_longPosVectorIut, v_longPosVectorNodeA;
                    
						// Test control
						if (not PICS_GN_GUC_FWD) {
							log("*** " & testcasename() & ": PICS_GN_GUC_FWD required for executing the TC ***");
							setverdict(inconc);
							stop;
						}
						if (f_getNonAreaForwardingAlgorithm() != e_cbf) {
							log("*** " & testcasename() & ": PICS_GN_NON_AREA_FORWARDING_ALGORITHM == e_cbf required for executing the TC ***");
							setverdict(inconc);
							stop;
						}
                    
						// Test component configuration
						f_cf03Up();
						// re-compute NodeA's position.
						v_longPosVectorIut := f_getIutLongPosVector();
						v_longPosVectorNodeA := f_computePositionUsingDistance(v_longPosVectorIut, v_distance, 0);
						v_longPosVectorNodeA.gnAddr := f_getTsGnLocalAddress(c_compNodeA);
                    
						// Preamble
                    
						// Start components
						v_nodeB := f_getComponent(c_compNodeB);
						v_nodeC := f_getComponent(c_compNodeC);
						v_nodeB.start(f_GEONW_PON_GUC_CBF_BV_07_nodeB(v_longPosVectorNodeA));
						v_nodeC.start(f_GEONW_PON_GUC_CBF_BV_07_nodeC(v_longPosVectorNodeA));
                    
						// Synchronization
						f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
                    
						// Cleanup
						f_cf03Down();
                    
					} // end f_GEONW_PON_GUC_CBF_BV_07
                
					/**
					 * @desc    Behavior function for NodeB (TC_GEONW_PON_GUC_CBF_BV_07)
					 * @param   p_longPosVectorNodeA    Position vector of NodeA
					 */
					function f_GEONW_PON_GUC_CBF_BV_07_nodeB(in LongPosVector p_longPosVectorNodeA) runs on ItsGeoNetworking {
                    
						// Local variables
                    
						// Preamble
						f_prNeighbour();
						f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                    
						// Test Body
						f_sleepIgnoreDef(int2float(f_getCbfMaxTime())/2000.0);
                    
						f_sendGeoNetMessage(
							m_geoNwReq_withLinkLayerDestination(
								m_geoNwPdu(
									m_geoNwUnicastPacket(
										f_getPosition(c_compNodeC),
										f_longPosVector2ShortPosVector(p_longPosVectorNodeA),
										vc_localSeqNumber
									),
									-,
									c_defaultHopLimit - 1
								),
								-,
								f_getIutMacAddress()
							)
						);
                    
						tc_noac.start;
						alt {
							[] geoNetworkingPort.receive(
								mw_geoNwInd(
									mw_geoNwPdu(
										mw_geoNwUnicastPacket(
											mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(p_longPosVectorNodeA)),
											?
										)
									)
								)
							) {
								tc_noac.stop;
								log("*** " & testcasename() & ": FAIL: Forwarded GUC received ***");
								f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
							}
                        
							[] tc_noac.timeout {
								log("*** " & testcasename() & ": PASS: GUC was not forwarded ***");
								f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
							}
						}
                    
						// Postamble
						f_poNeighbour();
                    
					} // end f_GEONW_PON_GUC_CBF_BV_07_nodeB
                
					/**
					 * @desc    Behavior function for NodeC (TC_GEONW_PON_GUC_CBF_BV_07)
					 * @param   p_longPosVectorNodeA    Position vector of NodeA
					 */
					function f_GEONW_PON_GUC_CBF_BV_07_nodeC(in LongPosVector p_longPosVectorNodeA) runs on ItsGeoNetworking {
                    
						// Local variables
                    
						// Preamble
						f_prNeighbour();
						f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                    
						// Test Body
						//Note: Sending of the GUC packet move to test body in contrast to the test purpose due to time critical behaviour
						f_sendGeoNetMessage(
							m_geoNwReq_withLinkLayerDestination(
								m_geoNwPdu(
									m_geoNwUnicastPacket(
										f_getPosition(c_compNodeC),
										f_longPosVector2ShortPosVector(p_longPosVectorNodeA),
										vc_localSeqNumber
									),
									-,
									c_defaultHopLimit
								),
								-,
								f_getIutMacAddress()
							)
						);
                    
						tc_noac.start;
						alt {
							[] geoNetworkingPort.receive(
								mw_geoNwInd(
									mw_geoNwPdu(
										mw_geoNwUnicastPacket(
											mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(p_longPosVectorNodeA)),
											?
										)
									)
								)
							) {
								tc_ac.stop;
								log("*** " & testcasename() & ": FAIL: Forwarded GUC received ***");
								f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
							}
							[] tc_noac.timeout {
								log("*** " & testcasename() & ": PASS: GUC was not forwarded ***");
								f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
							}
						}
                    
						// Postamble
						f_poNeighbour();
                    
					} // end f_GEONW_PON_GUC_CBF_BV_07_nodeC
                
				} // end GEONW_PON_GUC_CBF_BV_07                

                group GEONW_PON_GUC_CBF_BV_20 {
berge's avatar
berge committed
                    /**
                     * @desc    TP Function for TC_GEONW_PON_GUC_CBF_BV_20
                     */
                    function f_GEONW_PON_GUC_CBF_BV_20() runs on ItsMtc {
                        
                        // Local variables
                        var ItsGeoNetworking v_nodeB;
                        var ItsGeoNetworking v_nodeC;
                        var float v_distance := int2float(f_getCbfMaxCommunicationRange() * 2);
                        var LongPosVector v_longPosVectorIut, v_longPosVectorNodeC;
                        
                        // Test control
                        if (not PICS_GN_GUC_FWD) {
                            log("*** " & testcasename() & ": PICS_GN_GUC_FWD required for executing the TC ***");
                            setverdict(inconc);
                            stop;
                        }
                        if (f_getNonAreaForwardingAlgorithm() != e_cbf) {
                            log("*** " & testcasename() & ": PICS_GN_NON_AREA_FORWARDING_ALGORITHM == e_cbf required for executing the TC ***");
                            setverdict(inconc);
                            stop;
                        }
                        
                        // Test component configuration
                        f_cf03Up();
                        // re-compute NodeC's position.
                        v_longPosVectorIut := f_getIutLongPosVector();
                        v_longPosVectorNodeC := f_computePositionUsingDistance(v_longPosVectorIut, v_distance, 180);
                        v_longPosVectorNodeC.gnAddr := f_getTsGnLocalAddress(c_compNodeC);
                        
                        // Preamble
                        
                        // Start components
                        v_nodeB := f_getComponent(c_compNodeB);
                        v_nodeC := f_getComponent(c_compNodeC);
                        v_nodeB.start(f_GEONW_PON_GUC_CBF_BV_20_nodeB(v_longPosVectorNodeC));
                        v_nodeC.start(f_GEONW_PON_GUC_CBF_BV_20_nodeC(v_longPosVectorNodeC));
                        
                        // Synchronization
                        f_serverSync2ClientsAndStop({c_prDone, c_msgSent, c_tbDone});
                        
                        // Cleanup
                        f_cf03Down();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_20
berge's avatar
berge committed
                    /**
                     * @desc    Behavior function for NodeB (TC_GEONW_PON_GUC_CBF_BV_20)
                     * @param   p_longPosVectorNodeC    Position vector of NodeC
                     */
                    function f_GEONW_PON_GUC_CBF_BV_20_nodeB(in LongPosVector p_longPosVectorNodeC) runs on ItsGeoNetworking {
                        
                        // Local variables
                        timer t_toCbf := int2float(f_getCbfMinTime()) / 1000.0;
						var LongPosVector v_longPosVectorNodeA := f_getPosition(c_compNodeA);
						
                        // Preamble
                        f_prNeighbour();
                        f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                        
                        // Test Body
                        log("*** " & testcasename() & ": INFO: Message sent ***");
                        f_selfOrClientSyncAndVerdict(c_msgSent, e_success);
                        
                        tc_ac.start;
                        t_toCbf.start;
                        alt {
                            [] geoNetworkingPort.receive(
                                mw_geoNwInd(
                                    mw_geoNwPdu(
                                        mw_geoNwUnicastPacket(
                                            mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(v_longPosVectorNodeA)),
                                            ?
                                        )
                                    )
                                )
                            ) {
                                tc_ac.stop;
                                if(t_toCbf.running) {
                                    t_toCbf.stop;
                                    log("*** " & testcasename() & ": FAIL: IUT re-broadcasted the packet too early ***");
                                    f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                                }
                                else {
                                    log("*** " & testcasename() & ": PASS: Forwarded GUC received ***");
                                    f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                                }
                            }
                            [] t_toCbf.timeout {
                                log("*** " & testcasename() & ": INFO: Ready for receiving re-broadcasting ***");
                                repeat;
                            }
                            
                            [] tc_ac.timeout {
                                log("*** " & testcasename() & ": FAIL: GUC was not forwarded ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                            }
                        }
                        
                        // Postamble
                        f_poNeighbour();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_20_nodeB
berge's avatar
berge committed
                    /**
                     * @desc    Behavior function for NodeC (TC_GEONW_PON_GUC_CBF_BV_20)
                     * @param   p_longPosVectorNodeC    Position vector of NodeC
                     */
                    function f_GEONW_PON_GUC_CBF_BV_20_nodeC(LongPosVector p_longPosVectorNodeC) runs on ItsGeoNetworking {
                        
                        // Local variables
						var LongPosVector v_longPosVectorNodeA := f_getPosition(c_compNodeA);
                        
                        // Preamble
                        f_prNeighbour();
                        f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                        
                        // Test Body
                        f_sendGeoNetMessage(
                            m_geoNwReq_withLinkLayerDestination(
                                m_geoNwPdu(
                                    m_geoNwUnicastPacket(
						                p_longPosVectorNodeC,
                                        f_longPosVector2ShortPosVector(v_longPosVectorNodeA),
                                        vc_localSeqNumber
                                    ),
                                    -,
                                    c_defaultHopLimit
berge's avatar
berge committed
                                f_getIutMacAddress()
                            )
                        );
                        log("*** " & testcasename() & ": INFO: Message sent ***");
                        f_selfOrClientSyncAndVerdict(c_msgSent, e_success);
                        
                        tc_ac.start;
                        alt {
                            [] geoNetworkingPort.receive(
                                mw_geoNwInd(
                                    mw_geoNwPdu(
                                        mw_geoNwUnicastPacket(
                                            mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(v_longPosVectorNodeA)),
                                            ?
                                        )
berge's avatar
berge committed
                            ) {
                                tc_ac.stop;
                                log("*** " & testcasename() & ": PASS: Forwarded GUC received ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                            }
                            [] tc_ac.timeout {
                                log("*** " & testcasename() & ": FAIL: GUC was not forwarded ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                            }
berge's avatar
berge committed
                          
                        // Postamble
                        f_poNeighbour();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_20_nodeC
berge's avatar
berge committed
                } // end GEONW_PON_GUC_CBF_BV_20
berge's avatar
berge committed
                group GEONW_PON_GUC_CBF_BV_21 {
berge's avatar
berge committed
                    /**
                     * @desc    TP Function for TC_GEONW_PON_GUC_CBF_BV_21
                     */
                    function f_GEONW_PON_GUC_CBF_BV_21() runs on ItsMtc {
                        
                        // Local variables
                        var ItsGeoNetworking v_nodeB;
                        var ItsGeoNetworking v_nodeC;
						var ItsGeoNetworking v_nodeD;
                        var float v_distance := int2float(f_getCbfMaxCommunicationRange() - 10);
                        var LongPosVector v_longPosVectorIut, v_longPosVectorNodeA;
                        
                        // Test control
                        if (not PICS_GN_GUC_FWD) {
                            log("*** " & testcasename() & ": PICS_GN_GUC_FWD required for executing the TC ***");
                            setverdict(inconc);
                            stop;
                        }
                        if (f_getNonAreaForwardingAlgorithm() != e_cbf) {
                            log("*** " & testcasename() & ": PICS_GN_NON_AREA_FORWARDING_ALGORITHM == e_cbf required for executing the TC ***");
                            setverdict(inconc);
                            stop;
                        }
                        
                        // Test component configuration
                        f_cf04Up();
                        // re-compute NodeA's position.
                        v_longPosVectorIut := f_getIutLongPosVector();
                        v_longPosVectorNodeA := f_computePositionUsingDistance(v_longPosVectorIut, v_distance, 0);
                        v_longPosVectorNodeA.gnAddr := f_getTsGnLocalAddress(c_compNodeA);
                        
                        // Preamble
                        
                        // Start components
                        v_nodeB := f_getComponent(c_compNodeB);
                        v_nodeC := f_getComponent(c_compNodeC);
						v_nodeD := f_getComponent(c_compNodeD);
                        v_nodeB.start(f_GEONW_PON_GUC_CBF_BV_21_nodeB(v_longPosVectorNodeA));
                        v_nodeC.start(f_GEONW_PON_GUC_CBF_BV_21_nodeC(v_longPosVectorNodeA));
						v_nodeC.start(f_GEONW_PON_GUC_CBF_BV_21_nodeD(v_longPosVectorNodeA));
                        
                        // Synchronization
                        f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
                        
                        // Cleanup
                        f_cf04Down();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_21
berge's avatar
berge committed
                    /**
                     * @desc    Behavior function for NodeB (TC_GEONW_PON_GUC_CBF_BV_21)
                     * @param   p_longPosVectorNodeA    Position vector of NodeA
                     */
                    function f_GEONW_PON_GUC_CBF_BV_21_nodeB(in LongPosVector p_longPosVectorNodeA) runs on ItsGeoNetworking {
                        
                        // Local variables
                        
                        // Preamble
                        f_prNeighbour();
                        f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                        
                        // Test Body                        
                        tc_ac.start;
                        alt {
                            [] geoNetworkingPort.receive(
                                mw_geoNwInd(
                                    mw_geoNwPdu(
                                        mw_geoNwUnicastPacket(
                                            mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(p_longPosVectorNodeA)),
                                            ?
                                        )
berge's avatar
berge committed
                            ) {
                                tc_ac.stop;
                                log("*** " & testcasename() & ": PASS: Re-broadcasted GUC received ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                            }
berge's avatar
berge committed
                            
                            [] tc_ac.timeout {
                                log("*** " & testcasename() & ": FAIL: GUC was not forwarded ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                            }
berge's avatar
berge committed
                        // Postamble
                        f_poNeighbour();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_21_nodeB
berge's avatar
berge committed
                    /**
                     * @desc    Behavior function for NodeC (TC_GEONW_PON_GUC_CBF_BV_21)
                     * @param   p_longPosVectorNodeA    Position vector of NodeA
                     */
                    function f_GEONW_PON_GUC_CBF_BV_21_nodeC(in LongPosVector p_longPosVectorNodeA) runs on ItsGeoNetworking {
                        
                        // Local variables
                        
                        // Preamble
                        f_prNeighbour();
                        f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                        
                        // Test Body
                        tc_ac.start;
                        alt {
                            [] geoNetworkingPort.receive(
                                mw_geoNwInd(
                                    mw_geoNwPdu(
                                        mw_geoNwUnicastPacket(
                                            mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(p_longPosVectorNodeA)),
                                            ?
                                        )
berge's avatar
berge committed
                            ) {
                                tc_ac.stop;
                                log("*** " & testcasename() & ": PASS: Re-broadcasted GUC received ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
                            }
                            [] tc_ac.timeout {
                                log("*** " & testcasename() & ": FAIL: GUC was not forwarded ***");
                                f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
                            }
berge's avatar
berge committed
                        
                        // Postamble
                        f_poNeighbour();
                        
                    } // end f_GEONW_PON_GUC_CBF_BV_21_nodeC

					/**
					 * @desc    Behavior function for NodeD (TC_GEONW_PON_GUC_CBF_BV_21)
                     * @param   p_longPosVectorNodeA    Position vector of NodeA
					 */
					function f_GEONW_PON_GUC_CBF_BV_21_nodeD(in LongPosVector p_longPosVectorNodeA) runs on ItsGeoNetworking {
                            
						// Local variables
						var LongPosVector v_longPosVectorNodeC := f_getPosition(c_compNodeC);
						timer t_toCbf := int2float(f_getCbfMaxTime()) * 0.95 / 1000.0;
                            
						// Preamble
						f_prNonNeighbour();
						f_selfOrClientSyncAndVerdict(c_prDone, e_success);
                            
						// Test Body
						f_sendGeoNetMessage(
                        	m_geoNwReq_withLinkLayerDestination(
                        		m_geoNwPdu(
                        			m_geoNwUnicastPacket(
                        				f_getPosition(c_compNodeC),
                        				f_longPosVector2ShortPosVector(p_longPosVectorNodeA),
                        				vc_localSeqNumber
                        			),
                        			-,
                        			c_defaultHopLimit
                        		),
                        		-,
                        		f_getIutMacAddress()
                        	)
                        );
                            
						t_toCbf.start;                    
						tc_ac.start;
						alt {
							[] geoNetworkingPort.receive(
								mw_geoNwInd(
									mw_geoNwPdu(
										mw_geoNwUnicastPacket(
											mw_shortPosVectorPosition(f_longPosVector2ShortPosVector(p_longPosVectorNodeA)),
											?
										)
									)
								)
							) {
								tc_ac.stop;                           
                                    
								if(t_toCbf.running) {                               
									t_toCbf.stop;
									log("*** " & testcasename() & ": FAIL: GUC retransmitted before CBF timer expiration ***");
									f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
								}
								else {
									log("*** " & testcasename() & ": PASS: GUC message received ***");
									f_selfOrClientSyncAndVerdict(c_tbDone, e_success);
								}
							}
							[] t_toCbf.timeout {
								log("*** " & testcasename() & ": INFO: GUC timer elapsed ***");
								repeat;
							}
							[] tc_ac.timeout {
								log("*** " & testcasename() & ": FAIL: GUC message not received ***");
								f_selfOrClientSyncAndVerdict(c_tbDone, e_error);
							}
						}
                            
						// Postamble
						f_poDefault();
                            
					} // end f_GEONW_PON_GUC_CBF_BV_21_nodeD                        
berge's avatar
berge committed
                } // end GEONW_PON_GUC_CBF_BV_21
berge's avatar
berge committed
				group GEONW_PON_GUC_CBF_BV_22 {
berge's avatar
berge committed
					/**
					 * @desc    TP Function for TC_GEONW_PON_GUC_CBF_BV_22
					 */
					function f_GEONW_PON_GUC_CBF_BV_22() runs on ItsMtc {
berge's avatar
berge committed
						// Local variables
						var ItsGeoNetworking v_nodeB;
						var ItsGeoNetworking v_nodeC;
						var ItsGeoNetworking v_nodeD;
						var float v_distance := int2float(f_getCbfMaxCommunicationRange() - 10);
						var LongPosVector v_longPosVectorIut, v_longPosVectorNodeA;
                        
						// Test control
						if (not PICS_GN_GUC_FWD) {
							log("*** " & testcasename() & ": PICS_GN_GUC_FWD required for executing the TC ***");
							setverdict(inconc);
							stop;
						}
						if (f_getNonAreaForwardingAlgorithm() != e_cbf) {
							log("*** " & testcasename() & ": PICS_GN_NON_AREA_FORWARDING_ALGORITHM == e_cbf required for executing the TC ***");
							setverdict(inconc);
							stop;
						}
                        
						// Test component configuration
						f_cf04Up();
						// re-compute NodeA's position.
						v_longPosVectorIut := f_getIutLongPosVector();
						v_longPosVectorNodeA := f_computePositionUsingDistance(v_longPosVectorIut, v_distance, 0);
						v_longPosVectorNodeA.gnAddr := f_getTsGnLocalAddress(c_compNodeA);
                        
						// Preamble
                        
						// Start components
						v_nodeB := f_getComponent(c_compNodeB);
						v_nodeC := f_getComponent(c_compNodeC);
						v_nodeD := f_getComponent(c_compNodeD);
						v_nodeB.start(f_GEONW_PON_GUC_CBF_BV_22_nodeB(v_longPosVectorNodeA));
						v_nodeC.start(f_GEONW_PON_GUC_CBF_BV_22_nodeC(v_longPosVectorNodeA));
						v_nodeC.start(f_GEONW_PON_GUC_CBF_BV_22_nodeD(v_longPosVectorNodeA));
                        
						// Synchronization
						f_serverSync2ClientsAndStop({c_prDone, c_tbDone});
                        
						// Cleanup
						f_cf04Down();
                        
					} // end f_GEONW_PON_GUC_CBF_BV_22
berge's avatar
berge committed
					/**
					 * @desc    Behavior function for NodeB (TC_GEONW_PON_GUC_CBF_BV_22)
					 * @param   p_longPosVectorNodeA    Position vector of NodeA
					 */
					function f_GEONW_PON_GUC_CBF_BV_22_nodeB(in LongPosVector p_longPosVectorNodeA) runs on ItsGeoNetworking {
                        
						// Local variables
                        
						// Preamble
						f_prNeighbour();
						f_selfOrClientSyncAndVerdict(c_prDone, e_success);