LibItsIpv6OverGeoNetworking_Functions.ttcn 10.4 KB
Newer Older
/**
 *  @author     ETSI / STF405
 *  @version    $URL: svn+ssh://vcs.etsi.org/TTCN3/LIB/LibIts/trunk/ttcn/GeoNetworking/LibItsGeoNetworking_Functions.ttcn $
 *              $Id: LibItsGeoNetworking_Functions.ttcn 168 2010-09-22 15:18:22Z berge $
 *  @desc       Module containing functions for Ipv6OverGeoNetworking
 *
 */
module LibItsIpv6OverGeoNetworking_Functions {
    
    // Libcommon
    import from LibCommon_BasicTypesAndValues all;
    import from LibCommon_DataStrings all;
    import from LibCommon_VerdictControl all;
    
    // LibIts
    import from LibIts_TestSystem all;
    import from LibIts_Interface all; 
    import from LibItsGeoNetworking_TypesAndValues all;
    import from LibItsGeoNetworking_Functions all;
    import from LibItsGeoNetworking_Templates all;
    import from LibItsIpv6OverGeoNetworking_TypesAndValues all;
    import from LibItsIpv6OverGeoNetworking_Templates all;
    
    group ipv6OverGeoConfigurationFunctions {
        
        /**
         * @desc This configuration features:
         *       - one ITS node (IUT)
         *       - two ITS nodes (nodeA, nodeB)
         *       - Area1 which only includes NodeB and IUT
         *       - Area2 which only includes NodeB 
         *         NodeB being close to the area center    
         */
        function f_ipv6_cf01Up() runs on ItsNt {

            // Variables
 
            // Map
            map(self:ipv6OverGeoNetworkingPort, system:ipv6OverGeoNetworkingPort);
            
            f_cf01Up();
            
        } // end f_cf01Up

        /**
         * @desc Deletes configuration cf01
         */
        function f_ipv6_cf01Down() runs on ItsNt {

            // Map
            unmap(self:ipv6OverGeoNetworkingPort, system:ipv6OverGeoNetworkingPort);
            
            f_cf01Down();
            
        } // end f_cf01Down
        
    } // end group ipv6OverGeoConfigurationFunctions
    
    group testAdapter {
        
        function f_taGetInterfaces() {
            
            //TODO
            
        }
        
    } // end group testAdapter
    
    group sendFunctions {
        
        function f_sendGeoBroadcastWithRA(
            in template (value) GvlTableEntry p_gvl,
            in template (value) LongPosVector p_position,
            in template (value) Ipv6Address p_sourceAddr,
            in template (value) Ipv6Address p_destinationAddr
        ) runs on ItsNt {
            f_sendGeoNetMessage(
                m_geoNwReq(
                    m_geoNwPduWithPayload(
                        m_geoBroadcastHeader(
                            p_position,
                            p_position,
                            e_vehicleStation,
                            vc_localSeqNumber,
                            f_getGeoBroadcastArea(p_gvl.area)
                        ),
                        m_ipv6Payload(
                            m_ipv6Packet(
                                p_sourceAddr,
                                p_destinationAddr,
                                c_noNextHdr,
                                m_rtAdvWithOptions(
                                    m_rtAdvOpt_prefixOpt(
                                        p_gvl.prefixLength,
                                        c_lFlag1,
                                        c_aFlag1,
                                        c_validLifetime30s,
                                        c_preferredLifetime30s,
                                        p_gvl.prefix
                                    )
                                )
                            )
                        )
                    )
                )
            );
        }
        
    } //end group sendFunctions
    
    group miscellaneous {
        
        /**
         * @desc Gets the Geographical Virtual link entry associated to an area
         * @param p_areaIndex The index of the area
         */
        function f_getGVL(in integer p_areaIndex) runs on ItsNt return GvlTableEntry {
            return valueof(vc_gvlTable[p_areaIndex]);
        } //end f_getGVL
        
        /**
         * @desc    Retrieves the MAC address from the GN address.
         * @param   p_gnAddr The GN address
         * @return  The MAC address
         */    
        function f_gnAddr2MacAddr(in GN_Address p_gnAddr) return MacAddress {
            return p_gnAddr.mid;
        } // end f_gnAddr2MacAddr
        
        /**
         * @desc    Retrieves the GN address from the MAC address.
         * @param   p_macAddr The MAC address
         * @return  The GN address
         */    
        function f_macAddr2GnAddr(in MacAddress p_macAddr) return GN_Address {
            var GN_Address v_gnAddr := valueof(m_dummyGnAddr);
            v_gnAddr.mid := p_macAddr;
            return v_gnAddr;
        } // end f_macAddr2GnAddr
        
        /**
         * @desc  Compute an Unique Interface ID based on a MAC Address
         * @param p_macAddr MAC Address
         * @return  Unique interface ID
         */
        function f_createUniqueInterfaceId (  
           in  Oct6 p_macAddr
        )
        return Oct8 {
            var UInt8 i;
            var Oct3 v_leftPartMac := int2oct(0,3);
            var Oct3 v_rightPartMac := int2oct(0,3);
            var Bit24 v_leftPartBits := int2bit(0,24);
            var Bit24 v_leftPartBitMask := oct2bit('020000'O);
            
            //get leftPart
            for (i:=0; i<lengthof(p_macAddr)-3; i:=i+1) {
                v_leftPartMac[i] := p_macAddr[i];
            }
            //get rightPart
            for (i:=3; i<lengthof(p_macAddr); i:=i+1) {
                v_rightPartMac[i-3] := p_macAddr[i];
            }
            //flipBit universalBit of leftPart
            v_leftPartBits :=  oct2bit(v_leftPartMac);
            v_leftPartBits := v_leftPartBits xor4b v_leftPartBitMask;
            v_leftPartMac := bit2oct(v_leftPartBits);
            //build InterfaceId
            return v_leftPartMac & 'FFFE'O & v_rightPartMac;
        } // end f_createUniqueInterfaceId

        /**
         * @desc  Compute link-local, global, solicited-node multicast IPv6 addresses<br>
         *    and MAC-Solicited-node Address, based on prefix and MAC address
         * @param p_macAddr MAC Address
         * @param p_prefix Prefix
         * @param   p_prefixLen Prefix Length
         * @param p_lla Computed link-local address
         * @param p_gla Computed global address
         * @param p_solNodeMca Computed solicited-node multicast address
         * @param p_macSolNodeMca Computed MAC solicited-node multicast address
         * @return  Execution status
         */
        function f_createIpAddresses(
            in MacAddress p_macAddr,
            in Oct16 p_prefix, 
            in UInt8 p_prefixLen,
            inout Ipv6Address p_lla,
            inout Ipv6Address p_gla,
            inout Ipv6Address p_solNodeMca,
            inout MacAddress p_macSolNodeMca
        )
        return FncRetCode {
            var UInt8 i;
            const UInt8 c_uniIdLen := 64;
            var Bit128 v_prefixBits := oct2bit(p_prefix);
            var Bit64 v_prefixReadyBits := int2bit(0, 64);
            var Oct8 v_prefixReady := int2oct(0,8);
            var Oct8 v_interfaceIdReady := int2oct(0,8);
            var Oct3 v_rightPartMac := int2oct(0,3);
            
            if (p_prefixLen > 64) {
                log("**** f_createIpAddresses: Wrong prefixLen ****");
                return e_error;
            }
            else {
                //Fill v_prefixReady with existing Prefix
                for (i:=0; i<p_prefixLen; i:=i+1) {
                    v_prefixReadyBits[i] := v_prefixBits[i];
                }
                //Complete v_prefixReady with Zero Bytes
                for (i:=p_prefixLen; i<64; i:=i+1) {
                    v_prefixReadyBits[i] := int2bit(0,1);
                }
                v_prefixReady := bit2oct(v_prefixReadyBits);
            }
            // compute interface ID
            v_interfaceIdReady := f_createUniqueInterfaceId (p_macAddr);
            
            //LLA
            if (p_lla != null) {
                p_lla := 'FE80000000000000'O & v_interfaceIdReady;
            }
            if (p_gla != null) {
                p_gla := v_prefixReady & v_interfaceIdReady;
            }
            
            //get rightPart
            for (i:=3; i<lengthof(p_macAddr); i:=i+1) {
                v_rightPartMac[i-3] := p_macAddr[i];
            }
            
            //SOL_NODE_MCA
            if (p_solNodeMca != null) {
                p_solNodeMca := 'FF0200000000000000000001FF'O & v_rightPartMac;
            }
            if (p_macSolNodeMca != null) {
                p_macSolNodeMca := '3333FF'O & v_rightPartMac;
            }
        }//end f_createIpAddresses

        /**
         * @desc    Derives the traffic class from the IPv6 TrafficClass field
         * @param   p_trafficClass The traffic class value in the IPv6 packet
         * @return  The traffic class based on the definition in ETSI TS 102 636-6-1 Table 1
         */    
        function f_getTrafficClassFromIpv6Packet(in UInt8 p_trafficClass) return TrafficClass {
            var TrafficClass v_trafficClass;
            
            v_trafficClass.reserved := 0;
            v_trafficClass.relevance := 0;
            
            if (p_trafficClass<64) {
                v_trafficClass.reliability := e_low;
                v_trafficClass.latency := e_high
            }
            else if (p_trafficClass>63 and p_trafficClass<128) {
                v_trafficClass.reliability := e_low;
                v_trafficClass.latency := e_medium
            }
            else if (p_trafficClass>127 and p_trafficClass<193) {
                v_trafficClass.reliability := e_low;
                v_trafficClass.latency := e_low
            }
            else {
                v_trafficClass.reliability := e_low;
                v_trafficClass.latency := e_veryLow
            }
            
            return v_trafficClass;
        } // end f_getTrafficClassFromPriority
    
    } // end group miscellaneous

} // end LibItsIpv6OverGeoNetworking_Functions