Exemple #1
0
        /***************************************************************************
        *  函数名称:NetworkDataProcessing
        *  功能:进行网络数据处理
        *  参数:无
        *  返回值:无
        * *************************************************************************/
        public void NetworkDataProcessing()
        {
            //int uncompressed_field_byte_num = 0; //非压缩字段字节数
            try
            {
                Object data = null;
                if (this.Component_reveice_queue.Count > 0)
                {
                    //读取网络数据处理模块组件接收队列数据
                    data = this.Component_reveice_queue.Dequeue();
                    PDU_Network IPv6_packet = (PDU_Network)data;

                    //检查目的地址是否为服务器IPv6地址
                    isReceive = true;
                    for (Int16 i = 0; i < 8; i++)
                    {
                        if (IPv6_packet.dest_ipv6_address[i] != IPv6_address[i])
                        {
                            isReceive = false; //丢弃该IPv6报文
                        }
                    }

                    if (isReceive)
                    {
                        NetworkPacketProcess(IPv6_packet); //进行网络报文处理
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("MessageBuffering错误情况:" + e.Message);
            }
        }
Exemple #2
0
        /******************************************************************************
         *  函数名称:IPv6_Packet_Buffering()
         *  功能:执行IPv6报文缓冲
         *  参数:data表示所收到的IPv6报文
         *  返回值:无
         * ***************************************************************************/
        private void IPv6_Packet_Buffering(object data)
        {
            PDU_Network pdu_ipv6 = (PDU_Network)data;

            //IPv6报文进入缓冲队列
            this.Buffer_queue.Enqueue(pdu_ipv6);
            //缓冲队列数据出队
            PDU_Network IPv6_Packet = (PDU_Network)this.Buffer_queue.Dequeue();

            //IPv6报文进入组件发送队列
            this.Component_send_queue.Enqueue(IPv6_Packet);
        }
        /******************************************************************************
         *  函数名称:ConvertBetween_ConnID_IPv6()
         *  功能:实现ConnID协议到IPv6协议的转换
         *  参数:data表示ConnID报文;
         *  返回值:IPv6_packet 返回IPv6报文
         * ***************************************************************************/

        private PDU_Network ConvertBetween_ConnID_IPv6(Object data)
        {
            PDU_ConnID pdu_connid = (PDU_ConnID)data;

            IPv6_packet = new PDU_Network();                      //构造IPv6数据报
            UDP_packet  = new PDU_Transport();                    //构造UDP数据报

            UInt64        connid   = pdu_connid.connid;           //获取ConnID报文连接标识ConnID
            List <Byte[]> app_data = pdu_connid.application_data; //获取ConnID报文应用层数据

            Communicarion_Patameter commPata = (Communicarion_Patameter)CommPara_ConnID_Mapping[connid];

            IPv6_packet.version       = 0x6;    //版本号4bit
            IPv6_packet.traffic_class = 0x00;   //通信类型8bit
            IPv6_packet.flow_label    = 0x0000; //流标签20bit
            IPv6_packet.flow_label2   = 0x0;


            IPv6_packet.next_header         = commPata.next_header;      //下一首部8bit
            IPv6_packet.hop_limit           = commPata.hop_limit;        //跳数限制8bit
            IPv6_packet.source_ipv6_address = commPata.source_ipv6_addr; //源IPv6地址
            IPv6_packet.dest_ipv6_address   = commPata.dest_ipv6_addr;   //目的IPv6地址

            UDP_packet.source_port  = commPata.source_port;              //源端口号
            UDP_packet.dest_port    = commPata.dest_port;                //目的端口号
            UDP_packet.udp_checksum = 0x0000;

            UInt16 app_data_len = 0x0000; //应用层数据字节数

            foreach (Byte[] B in app_data)
            {
                foreach (Byte b in B)
                {
                    app_data_len++;
                }
            }

            //================== UDP长度 =====================//
            UDP_packet.udp_length = (UInt16)(0x0008 + app_data_len); //UDP长度为UDP报头+UDP数据长度

            //================ IPv6有效载荷长度 ===============//
            IPv6_packet.payload_length = UDP_packet.udp_length;

            //================== UDP数据 ======================//
            UDP_packet.application_data = app_data;

            //================ IPv6上层PDU ====================//
            IPv6_packet.pdu_transport = UDP_packet;

            return(IPv6_packet);
        }
        /******************************************************************************
         *  函数名称:ProtocolConversion()
         *  功能:执行协议转换功能
         *  参数:无
         *  返回值:无
         * ***************************************************************************/
        public void ProtocolConversion()
        {
            try
            {
                Object data = null;
                if (this.Component_reveice_queue.Count > 0)
                {
                    //读取协议转换器接收队列数据
                    data = this.Component_reveice_queue.Dequeue();

                    switch ((data.GetType().Name))
                    {
                    case "PDU_LoWPAN_IPHC":     //若为6LoWPAN报文数据

                        //执行6LoWPAN报文到IPv6报文的转换
                        this.IPv6_packet = ConvertBetween_LoWPAN_IPv6(data);

                        //IPv6报文进入组件发送队列
                        this.Component_send_queue.Enqueue(this.IPv6_packet);
                        break;

                    case "PDU_ConnID":    //若为ConnID报文数据

                        //执行ConnID报文到IPv6报文的转换
                        this.IPv6_packet = ConvertBetween_ConnID_IPv6(data);

                        //IPv6报文进入组件发送队列
                        this.Component_send_queue.Enqueue(this.IPv6_packet);

                        break;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("协议转换器错误情况:" + e.Message + " " + e.StackTrace);
            }
        }
Exemple #5
0
        /******************************************************************************
         *  函数名称:Routing
         *  功能:路由选择
         *  参数:无
         *  返回值:无
         * ***************************************************************************/
        public void Routing()
        {
            try
            {
                Object data = null;
                if (this.Component_reveice_queue.Count > 0)
                {
                    //读取缓冲区组件接收队列数据
                    data = this.Component_reveice_queue.Dequeue();
                    PDU_Network ipv6_packet = (PDU_Network)data;

                    //foreach (UInt16 I in ipv6_packet.dest_ipv6_address)
                    //    Console.WriteLine(string.Format("{0:X4}",I));

                    //目的IPv6地址 2001:da8:d818:0082::1234
                    UInt16[] dest_ipv6_address = { 0x0120, 0xa80d, 0x18d8, 0x8200,
                                                   0x0000, 0x0000, 0x0000, 0x3412 };

                    bool isEqual = true;
                    for (Int16 i = 0; i < 8; i++)
                    {
                        if (ipv6_packet.dest_ipv6_address[i] != dest_ipv6_address[i])
                        {
                            isEqual = false;
                        }
                    }
                    if (isEqual)
                    {
                        //进入组件发送队列
                        this.Component_send_queue.Enqueue(ipv6_packet);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("路由选择错误情况:" + e.Message);
            }
        }
Exemple #6
0
        /***************************************************************************
        *  函数名称:NetworkPacketProcess
        *  功能:进行网络报文处理
        *        依据源IPv6地址接口标识获得节点标识,填充“节点标识-网络前缀”映射表
        *        依据源IPv6地址网络前缀判断通信技术类型
        *        依据源端口号判断数据类型
        *  参数:无
        *  返回值:无
        * *************************************************************************/
        private void NetworkPacketProcess(PDU_Network IPv6_packet)
        {
            //获取源IPv6地址
            UInt16[] source_IPv6_addr = IPv6_packet.source_ipv6_address;
            UInt16[] IPv6_Prefix      = new UInt16[4]; //网络前缀
            UInt16[] IPv6_IID         = new UInt16[4]; //接口标识
            bool[]   Category         = new bool[4];   //子网类别
            bool[]   Tech_ID          = new bool[4];   //通信技术类型


            for (Int16 i = 0; i < 4; i++)
            {
                IPv6_Prefix[i] = source_IPv6_addr[i];
            }
            int j = 0;

            for (Int16 i = 4; i < 8; i++)
            {
                IPv6_IID[j++] = source_IPv6_addr[i];
            }

            //填充“节点标识-网络前缀”映射表
            NodeIID_NetPrefix_Mapping.Add(IPv6_IID, IPv6_Prefix);

            //获取网络前缀第四字段
            Byte[]   temp_arr    = BitConverter.GetBytes(IPv6_Prefix[3]);
            BitArray temp_bitarr = new BitArray(temp_arr); //同一字节低位优先

            //网络前缀中,第四字段5、6、7、8位为子网类别,对应存储位为4、3、2、1

            j = 0;
            for (Int16 i = 3; i >= 0; i--)
            {
                Category[j++] = temp_bitarr[i];
            }


            //若子网类别为0x8;0x9;0xA;0xB;则可判断为源节点来自物联子网
            if ((Category[0] && !Category[1] && !Category[2] && !Category[3]) ||
                (Category[0] && !Category[1] && !Category[2] && Category[3]) ||
                (Category[0] && !Category[1] && Category[2] && !Category[3]) ||
                (Category[0] && !Category[1] && Category[2] && Category[3]))
            {
                //获取通信技术类型
                //网络前缀中,第四字段9、10、11、12位为子网类别,对应存储位为15、14、13、12
                j = 0;
                for (Int16 i = 15; i >= 12; i--)
                {
                    Tech_ID[j++] = temp_bitarr[i];
                }

                //Console.WriteLine("----------------------------------------------------------------");
                //Console.Write(Tech_ID[0] + " "+Tech_ID[1] + " "+Tech_ID[2] + " "+Tech_ID[3] + " ");

                //若Tech ID为0x9,则采用6LoWPAN技术
                if (Tech_ID[0] && !Tech_ID[1] && !Tech_ID[2] && Tech_ID[3])
                {
                    LoWPAN_data = IPv6_packet.pdu_transport.application_data;
                    //Console.WriteLine("LoWPAN_data长度=" + LoWPAN_data.Count);


                    switch (IPv6_packet.pdu_transport.source_port)
                    {
                    case 0xF0BF:                    //若采用6LoWPAN技术的报文源端口号为0xF0BF,则为血压数据

                        BloodPressure_data.Clear(); //血压数据列表变量清空

                        for (int i = 0; i < LoWPAN_data.Count - 1; i = i + 2)
                        {
                            BloodPressureDataType bpData = new BloodPressureDataType();

                            bpData.HighBP = BitConverter.ToInt16(LoWPAN_data[i], 0);
                            bpData.LowBP  = BitConverter.ToInt16(LoWPAN_data[i + 1], 0);

                            BloodPressure_data.Add(bpData);
                        }
                        //Console.WriteLine("BloodPressure_data长度=" + BloodPressure_data.Count);

                        //lock (lockObject)
                        //{
                        //血压数据进入网络数据处理组件发送队列
                        this.Component_send_queue.Enqueue(BloodPressure_data);
                        //}
                        break;

                        //可扩展... ...
                    }
                }

                //若Tech ID为0xA,则采用ConnID技术
                else if (Tech_ID[0] && !Tech_ID[1] && Tech_ID[2] && !Tech_ID[3])
                {
                    ConnID_data = IPv6_packet.pdu_transport.application_data;

                    //Console.WriteLine(IPv6_packet.pdu_transport.source_port + " ");

                    switch (IPv6_packet.pdu_transport.source_port)
                    {
                    case 0xF0BF:                  //若采用ConnID技术且报文源端口号为0xF0BF,则为体温数据

                        Temperature_data.Clear(); //体温数据列表变量清空
                        for (int i = 0; i < ConnID_data.Count - 1; i = i + 2)
                        {
                            TemperatureDataType tempData = new TemperatureDataType();

                            tempData.TemperatureInteger = ConnID_data[i][0];
                            tempData.TemperatureDecimal = ConnID_data[i + 1][0];

                            Temperature_data.Add(tempData);
                        }

                        this.Component_send_queue.Enqueue(Temperature_data);


                        break;

                    case 0xF0BE:     //若采用ConnID技术且报文源端口号为0xF0BE,则为心率数据


                        HeartRate_data.Clear();      //心率数据列表变量清空
                        for (int i = 0; i < ConnID_data.Count - 1; i = i + 1)
                        {
                            HeartRateDataType hrData = new HeartRateDataType();

                            hrData.HeartRate = BitConverter.ToInt16(ConnID_data[i], 0);

                            HeartRate_data.Add(hrData);
                        }

                        this.Component_send_queue.Enqueue(HeartRate_data);
                        break;
                    }
                }
            }
        }
        /******************************************************************************
         *  函数名称:ConvertBetween_LoWPAN_IPv6()
         *  功能:实现6LoWPAN协议到IPv6协议的转换
         *  参数:data表示6LoWPAN报文;
         *  返回值:IPv6_packet 返回IPv6报文
         * ***************************************************************************/

        private PDU_Network ConvertBetween_LoWPAN_IPv6(Object data)
        {
            PDU_LoWPAN_IPHC pdu_lowpan = (PDU_LoWPAN_IPHC)data;

            Byte          dispatch    = pdu_lowpan.dispatch;              //获取6LoWPAN报文分派值
            Byte          iphc_header = pdu_lowpan.iphc_header;           //获取6LoWPAN报文IPHC报头
            Byte          context_id  = pdu_lowpan.context_identifier;    //获取6LoWPAN报文上下文标识符
            List <Byte[]> unzip_field = pdu_lowpan.IP_uncompressed_field; //获取6LoWPAN报文IP域非压缩字段
            Byte          nhc_header  = pdu_lowpan.nhc_header;            //获取6LoWPAN报文NHC报头
            List <Byte[]> nh_field    = pdu_lowpan.NH_field;              //获取6LoWPAN报文下一个首部域字段
            List <Byte[]> app_data    = pdu_lowpan.application_data;      //获取6LoWPAN报文应用层数据

            IPv6_packet = new PDU_Network();                              //构造IPv6数据报
            UDP_packet  = new PDU_Transport();                            //构造UDP数据报

            //================ IPv6 版本号 =====================//
            IPv6_packet.version = 0x6; //版本号4bit

            //依据IPHC报头执行转换
            Byte[]   dispatch_arr = { dispatch };
            BitArray arr          = new BitArray(dispatch_arr);

            bool[] TF = new bool[2]; //通信类型&流标签
            TF[0] = arr[arr.Count - 4];
            TF[1] = arr[arr.Count - 5];
            String TF_value = "";

            if (!TF[0] && !TF[1])
            {
                TF_value = "00";     //2bitECN+6bitDSCP+4bitPAD+20bit流标签
            }
            else if (!TF[0] && TF[1])
            {
                TF_value = "01";     //2bitECN+2bitPAD+20bit流标签
            }
            else if (TF[0] && !TF[1])
            {
                TF_value = "10";     //2bitECN+6bitDSCP
            }
            else
            {
                TF_value = "11";     //通信类型&流标签全部压缩
            }
            switch (TF_value)
            {
            case "00":
                break;

            case "01":
                break;

            case "10":
                break;

            case "11":
                //================ IPv6 通信类型&流标签 =====================//
                IPv6_packet.traffic_class = 0x00;    //通信类型8bit
                IPv6_packet.flow_label    = 0x0000;  //流标签20bit
                IPv6_packet.flow_label2   = 0x0;
                break;
            }

            bool NH = arr[arr.Count - 6];  //下一报头

            switch (NH)
            {
            case false:     //不压缩 (包含于非压缩字段)
                break;

            case true:      //用LoWPAN_NHC压缩
                //读取NHC Header字段各比特位值
                Byte[]   nhc_header_arr = { nhc_header };
                BitArray arr2           = new BitArray(nhc_header_arr);
                if (arr2[arr2.Count - 1] && arr2[arr2.Count - 2] && arr2[arr2.Count - 3] &&
                    arr2[arr2.Count - 4] && !arr2[arr2.Count - 5])      //若NHC Header前5位为11110,则下一首部为UDP报头
                {
                    //================== IPv6 下一个首部=============================//
                    IPv6_packet.next_header = 0x11;   //下一首部11H,表示UDP报文

                    switch (arr2[arr2.Count - 6])     //第6为C位表示UDP校验和是否压缩
                    {
                    //============================ UDP 校验和 =====================================//
                    case false:            //UDP校验和不压缩
                        UDP_packet.udp_checksum = BitConverter.ToUInt16(nh_field.ElementAt(1), 0);
                        break;

                    case true:             //UDP校验和压缩
                        UDP_packet.udp_checksum = 0x0000;
                        break;
                    }

                    //第7、8位为P位,表示源端口和目的端口是否压缩
                    if (!arr2[arr2.Count - 7] && !arr2[arr2.Count - 8])
                    {
                    }                                                               //00,源端口、目的端口都不压缩
                    else if (!arr2[arr2.Count - 7] && arr2[arr2.Count - 8])
                    {
                    }                                                               //01,源端口不压缩,目的端口前8位为0xF0,被省略
                    else if (arr2[arr2.Count - 7] && !arr2[arr2.Count - 8])
                    {
                    }         //10,目的端口不压缩,源端口前8位为0xF0,被省略
                    else      //11,源端口、目的端口前12位均为0XF0B,被省略
                    {
                        BitArray arr1      = new BitArray(nh_field.ElementAt(0));
                        bool[]   zip_ports = new bool[8];
                        zip_ports[0] = arr1[arr1.Count - 1];
                        zip_ports[1] = arr1[arr1.Count - 2];
                        zip_ports[2] = arr1[arr1.Count - 3];
                        zip_ports[3] = arr1[arr1.Count - 4];
                        zip_ports[4] = arr1[arr1.Count - 5];
                        zip_ports[5] = arr1[arr1.Count - 6];
                        zip_ports[6] = arr1[arr1.Count - 7];
                        zip_ports[7] = arr1[arr1.Count - 8];
                        //================================ UDP 端口号 ==============================//
                        //源端口
                        if (!zip_ports[0] && !zip_ports[1] && !zip_ports[2] && !zip_ports[3])         //0000
                        {
                            UDP_packet.source_port = 0xF0B0 + 0x0;
                        }
                        else if (!zip_ports[0] && !zip_ports[1] && !zip_ports[2] && zip_ports[3])     //0001
                        {
                            UDP_packet.source_port = 0xF0B0 + 0x1;
                        }
                        else if (!zip_ports[0] && !zip_ports[1] && zip_ports[2] && !zip_ports[3])     //0010
                        {
                            UDP_packet.source_port = 0xF0B0 + 0x2;
                        }
                        else if (!zip_ports[0] && !zip_ports[1] && zip_ports[2] && zip_ports[3])      //0011
                        {
                            UDP_packet.source_port = 0xF0B0 + 0x3;
                        }
                        else if (!zip_ports[0] && zip_ports[1] && !zip_ports[2] && !zip_ports[3])     //0100
                        {
                            UDP_packet.source_port = 0xF0B0 + 0x4;
                        }
                        else if (!zip_ports[0] && zip_ports[1] && !zip_ports[2] && zip_ports[3])      //0101
                        {
                            UDP_packet.source_port = 0xF0B0 + 0x5;
                        }
                        else if (!zip_ports[0] && zip_ports[1] && zip_ports[2] && !zip_ports[3])      //0110
                        {
                            UDP_packet.source_port = 0xF0B0 + 0x6;
                        }
                        else if (!zip_ports[0] && zip_ports[1] && zip_ports[2] && zip_ports[3])       //0111
                        {
                            UDP_packet.source_port = 0xF0B0 + 0x7;
                        }
                        else if (zip_ports[0] && !zip_ports[1] && !zip_ports[2] && !zip_ports[3])     //1000
                        {
                            UDP_packet.source_port = 0xF0B0 + 0x8;
                        }
                        else if (zip_ports[0] && !zip_ports[1] && !zip_ports[2] && zip_ports[3])      //1001
                        {
                            UDP_packet.source_port = 0xF0B0 + 0x9;
                        }
                        else if (zip_ports[0] && !zip_ports[1] && zip_ports[2] && !zip_ports[3])      //1010
                        {
                            UDP_packet.source_port = 0xF0B0 + 0xA;
                        }
                        else if (zip_ports[0] && !zip_ports[1] && zip_ports[2] && zip_ports[3])       //1011
                        {
                            UDP_packet.source_port = 0xF0B0 + 0xB;
                        }
                        else if (zip_ports[0] && zip_ports[1] && !zip_ports[2] && !zip_ports[3])      //1100
                        {
                            UDP_packet.source_port = 0xF0B0 + 0xC;
                        }
                        else if (zip_ports[0] && zip_ports[1] && !zip_ports[2] && zip_ports[3])       //1101
                        {
                            UDP_packet.source_port = 0xF0B0 + 0xD;
                        }
                        else if (zip_ports[0] && zip_ports[1] && zip_ports[2] && !zip_ports[3])       //1110
                        {
                            UDP_packet.source_port = 0xF0B0 + 0xE;
                        }
                        else                                                                          //1111
                        {
                            UDP_packet.source_port = 0xF0B0 + 0xF;
                        }

                        //目的端口
                        if (!zip_ports[4] && !zip_ports[5] && !zip_ports[6] && !zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0x0;
                        }
                        else if (!zip_ports[4] && !zip_ports[5] && !zip_ports[6] && zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0x1;
                        }
                        else if (!zip_ports[4] && !zip_ports[5] && zip_ports[6] && !zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0x2;
                        }
                        else if (!zip_ports[4] && !zip_ports[5] && zip_ports[6] && zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0x3;
                        }
                        else if (!zip_ports[4] && zip_ports[5] && !zip_ports[6] && !zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0x4;
                        }
                        else if (!zip_ports[4] && zip_ports[5] && !zip_ports[6] && zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0x5;
                        }
                        else if (!zip_ports[4] && zip_ports[5] && zip_ports[6] && !zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0x6;
                        }
                        else if (!zip_ports[4] && zip_ports[5] && zip_ports[6] && zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0x7;
                        }
                        else if (zip_ports[4] && !zip_ports[5] && !zip_ports[6] && !zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0x8;
                        }
                        else if (zip_ports[4] && !zip_ports[5] && !zip_ports[6] && zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0x9;
                        }
                        else if (zip_ports[4] && !zip_ports[5] && zip_ports[6] && !zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0xA;
                        }
                        else if (zip_ports[4] && !zip_ports[5] && zip_ports[6] && zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0xB;
                        }
                        else if (zip_ports[4] && zip_ports[5] && !zip_ports[6] && !zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0xC;
                        }
                        else if (zip_ports[4] && zip_ports[5] && !zip_ports[6] && zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0xD;
                        }
                        else if (zip_ports[4] && zip_ports[5] && zip_ports[6] && !zip_ports[7])
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0xE;
                        }
                        else
                        {
                            UDP_packet.dest_port = 0xF0B0 + 0xF;
                        }
                    }    // else  //11,源端口、目的端口前12位均为0XF0B,被省略
                }
                break;
            }//switch (NH)


            bool[] HLIM = new bool[2]; //跳数限制
            HLIM[0] = arr[arr.Count - 7];
            HLIM[1] = arr[arr.Count - 8];
            String HLIM_value = "";

            if (!HLIM[0] && !HLIM[1])
            {
                HLIM_value = "00";     //跳数限制不压缩
            }
            else if (!HLIM[0] && HLIM[1])
            {
                HLIM_value = "01";     //跳数限制为1
            }
            else if (HLIM[0] && !HLIM[1])
            {
                HLIM_value = "10";     //跳数限制为64
            }
            else
            {
                HLIM_value = "11";     //跳数限制为255
            }
            switch (HLIM_value)
            {
            //========================= IPv6  跳数限制======================//
            case "00":
                IPv6_packet.hop_limit = unzip_field.ElementAt(0)[0];     //非压缩字段1为未压缩的跳数限制字段,1字节
                break;

            case "01":
                IPv6_packet.hop_limit = 0x01;
                break;

            case "10":
                IPv6_packet.hop_limit = 0x40;
                break;

            case "11":
                IPv6_packet.hop_limit = 0xFF;
                break;
            }

            Byte[]   iphc_header_arr    = { iphc_header };
            BitArray iphc_header_bitarr = new BitArray(iphc_header_arr);

            Byte[]   context_id_arr    = { context_id };
            BitArray context_id_bitarr = new BitArray(context_id_arr);

            bool CID = iphc_header_bitarr[iphc_header_bitarr.Count - 1]; //上下文标识扩展

            UInt16[] source_IPv6_addr_prefix = null;                     //定义源IPv6地址前缀
            UInt16[] dest_IPv6_addr_prefix   = null;                     //定义目的IPv6地址前缀
            switch (CID)
            {
            case false:                                               //使用默认上下文 0x0
                source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0x0]; //获取源IPv6地址前缀
                dest_IPv6_addr_prefix   = (UInt16[])DCI_Mapping[0x0]; //获取目的IPv6地址前缀
                break;

            case true:                    //使用指定上下文
                bool[] SCI = new bool[4]; //源地址上下文标识符
                bool[] DCI = new bool[4]; //目的地址上下文标识符

                SCI[0] = context_id_bitarr[context_id_bitarr.Count - 1];
                SCI[1] = context_id_bitarr[context_id_bitarr.Count - 2];
                SCI[2] = context_id_bitarr[context_id_bitarr.Count - 3];
                SCI[3] = context_id_bitarr[context_id_bitarr.Count - 4];

                DCI[0] = context_id_bitarr[context_id_bitarr.Count - 5];
                DCI[1] = context_id_bitarr[context_id_bitarr.Count - 6];
                DCI[2] = context_id_bitarr[context_id_bitarr.Count - 7];
                DCI[3] = context_id_bitarr[context_id_bitarr.Count - 8];

                if (!SCI[0] && !SCI[1] && !SCI[2] && !SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0x0];
                }
                else if (!SCI[0] && !SCI[1] && !SCI[2] && SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0x1];
                }
                else if (!SCI[0] && !SCI[1] && SCI[2] && !SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0x2];
                }
                else if (!SCI[0] && !SCI[1] && SCI[2] && SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0x3];
                }
                else if (!SCI[0] && SCI[1] && !SCI[2] && !SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0x4];
                }
                else if (!SCI[0] && SCI[1] && !SCI[2] && SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0x5];
                }
                else if (!SCI[0] && SCI[1] && SCI[2] && !SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0x6];
                }
                else if (!SCI[0] && SCI[1] && SCI[2] && SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0x7];
                }
                else if (SCI[0] && !SCI[1] && !SCI[2] && !SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0x8];
                }
                else if (SCI[0] && !SCI[1] && !SCI[2] && SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0x9];
                }
                else if (SCI[0] && !SCI[1] && SCI[2] && !SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0xA];
                }
                else if (SCI[0] && !SCI[1] && SCI[2] && SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0xB];
                }
                else if (SCI[0] && SCI[1] && !SCI[2] && !SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0xC];
                }
                else if (SCI[0] && SCI[1] && !SCI[2] && SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0xD];
                }
                else if (SCI[0] && SCI[1] && SCI[2] && !SCI[3])
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0xE];
                }
                else
                {
                    source_IPv6_addr_prefix = (UInt16[])SCI_Mapping[0xF];
                }

                if (!DCI[0] && !DCI[1] && !DCI[2] && !DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0x0];
                }
                else if (!DCI[0] && !DCI[1] && !DCI[2] && DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0x1];
                }
                else if (!DCI[0] && !DCI[1] && DCI[2] && !DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0x2];
                }
                else if (!DCI[0] && !DCI[1] && DCI[2] && DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0x3];
                }
                else if (!DCI[0] && DCI[1] && !DCI[2] && !DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0x4];
                }
                else if (!DCI[0] && DCI[1] && !DCI[2] && DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0x5];
                }
                else if (!DCI[0] && DCI[1] && DCI[2] && !DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0x6];
                }
                else if (!DCI[0] && DCI[1] && DCI[2] && DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0x7];
                }
                else if (DCI[0] && !DCI[1] && !DCI[2] && !DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0x8];
                }
                else if (DCI[0] && !DCI[1] && !DCI[2] && DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0x9];
                }
                else if (DCI[0] && !DCI[1] && DCI[2] && !DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0xA];
                }
                else if (DCI[0] && !DCI[1] && DCI[2] && DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0xB];
                }
                else if (DCI[0] && DCI[1] && !DCI[2] && !DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0xC];
                }
                else if (DCI[0] && DCI[1] && !DCI[2] && DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0xD];
                }
                else if (DCI[0] && DCI[1] && DCI[2] && !DCI[3])
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0xE];
                }
                else
                {
                    dest_IPv6_addr_prefix = (UInt16[])DCI_Mapping[0xF];
                }

                break;
            }// switch (CID)

            bool SAC = iphc_header_bitarr[iphc_header_bitarr.Count - 2]; //源地址压缩状态

            bool[] SAM = new bool[2];    //源地址模式
            SAM[0] = iphc_header_bitarr[iphc_header_bitarr.Count - 3];
            SAM[1] = iphc_header_bitarr[iphc_header_bitarr.Count - 4];

            bool M = iphc_header_bitarr[iphc_header_bitarr.Count - 5];   //组播压缩

            bool DAC = iphc_header_bitarr[iphc_header_bitarr.Count - 6]; //目的地址压缩状态

            bool[] DAM = new bool[2];                                    //目的地址模式
            DAM[0] = iphc_header_bitarr[iphc_header_bitarr.Count - 7];
            DAM[1] = iphc_header_bitarr[iphc_header_bitarr.Count - 8];

            UInt16[] source_IPv6_addr_IID = null; //定义源IPv6地址IID
            UInt16[] dest_IPv6_addr_IID   = null; //定义目的IPv6地址IID

            switch (SAC)
            {
            case false:       //无状态压缩
                break;

            case true:        //有状态压缩
                if (!SAM[0] && !SAM[1])
                {
                }                                //保留
                else if (!SAM[0] && SAM[1])      //64bit IID串联发送,前64bit由上下文计算得出
                {
                    Byte[] temp1 = { unzip_field.ElementAt(1)[0], unzip_field.ElementAt(1)[1] };
                    Byte[] temp2 = { unzip_field.ElementAt(1)[2], unzip_field.ElementAt(1)[3] };
                    Byte[] temp3 = { unzip_field.ElementAt(1)[4], unzip_field.ElementAt(1)[5] };
                    Byte[] temp4 = { unzip_field.ElementAt(1)[6], unzip_field.ElementAt(1)[7] };

                    source_IPv6_addr_IID    = new UInt16[4];
                    source_IPv6_addr_IID[0] = BitConverter.ToUInt16(temp1, 0);     //两个Byte类型转UInt16
                    source_IPv6_addr_IID[1] = BitConverter.ToUInt16(temp2, 0);
                    source_IPv6_addr_IID[2] = BitConverter.ToUInt16(temp3, 0);
                    source_IPv6_addr_IID[3] = BitConverter.ToUInt16(temp4, 0);
                }
                else if (SAM[0] && !SAM[1])
                {
                }                                   //16bit 短地址串联发送,前112bit由上下文计算得出
                else
                {
                }                 //0bit,全部由上下文计算得出
                break;
            }

            switch (DAC)
            {
            case false:       //无状态压缩
                break;

            case true:        //有状态压缩
                if (!DAM[0] && !DAM[1])
                {
                }                                //保留
                else if (!DAM[0] && DAM[1])      //64bit IID串联发送,前64bit由上下文计算得出
                {
                    Byte[] temp1 = { unzip_field.ElementAt(2)[0], unzip_field.ElementAt(2)[1] };
                    Byte[] temp2 = { unzip_field.ElementAt(2)[2], unzip_field.ElementAt(2)[3] };
                    Byte[] temp3 = { unzip_field.ElementAt(2)[4], unzip_field.ElementAt(2)[5] };
                    Byte[] temp4 = { unzip_field.ElementAt(2)[6], unzip_field.ElementAt(2)[7] };

                    dest_IPv6_addr_IID    = new UInt16[4];
                    dest_IPv6_addr_IID[0] = BitConverter.ToUInt16(temp1, 0);     //两个Byte类型转UInt16
                    dest_IPv6_addr_IID[1] = BitConverter.ToUInt16(temp2, 0);
                    dest_IPv6_addr_IID[2] = BitConverter.ToUInt16(temp3, 0);
                    dest_IPv6_addr_IID[3] = BitConverter.ToUInt16(temp4, 0);
                }
                else if (DAM[0] && !DAM[1])
                {
                }                                   //16bit 短地址串联发送,前112bit由上下文计算得出
                else
                {
                }                 //0bit,全部由上下文计算得出
                break;
            }

            //================================= IPv6 源地址、目的地址======================================//
            //计算源IPv6地址
            IPv6_packet.source_ipv6_address = new UInt16[source_IPv6_addr_prefix.Length + source_IPv6_addr_IID.Length];
            source_IPv6_addr_prefix.CopyTo(IPv6_packet.source_ipv6_address, 0);
            source_IPv6_addr_IID.CopyTo(IPv6_packet.source_ipv6_address, source_IPv6_addr_prefix.Length);

            //计算目的IPv6地址
            IPv6_packet.dest_ipv6_address = new UInt16[dest_IPv6_addr_prefix.Length + dest_IPv6_addr_IID.Length];
            dest_IPv6_addr_prefix.CopyTo(IPv6_packet.dest_ipv6_address, 0);
            dest_IPv6_addr_IID.CopyTo(IPv6_packet.dest_ipv6_address, dest_IPv6_addr_prefix.Length);

            UInt16 app_data_len = 0x0000; //应用层数据字节数

            foreach (Byte[] B in app_data)
            {
                foreach (Byte b in B)
                {
                    app_data_len++;
                }
            }

            //================== UDP长度 =====================//
            UDP_packet.udp_length = (UInt16)(0x0008 + app_data_len); //UDP长度为UDP报头+UDP数据长度

            //================ IPv6有效载荷长度 ===============//
            IPv6_packet.payload_length = UDP_packet.udp_length;

            //================== UDP数据 ======================//
            UDP_packet.application_data = app_data;

            //================ IPv6上层PDU ====================//
            IPv6_packet.pdu_transport = UDP_packet;

            return(IPv6_packet);
        }