The RDP_NETCHAR_RESULTS structure is used by the server to send detected network characteristics to the client.
Inheritance: NETWORK_DETECTION_REQUEST
        /// <summary>
        /// Encode a RDP_NETCHAR_RESULT structure for subheader, don't encode the first two field 
        /// </summary>
        /// <param name="bwStop"></param>
        /// <returns></returns>
        public static byte[] EncodeNetCharResult(RDP_NETCHAR_RESULT ncRes)
        {
            List<byte> bufferList = new List<byte>();
            bufferList.AddRange(ToBytes(ncRes.sequenceNumber));
            bufferList.AddRange(ToBytes((ushort)ncRes.requestType));

            if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BANDWIDTH_AVERAGERTT)
            {
                bufferList.AddRange(ToBytes(ncRes.bandwidth));
                bufferList.AddRange(ToBytes(ncRes.averageRTT));
            }
            else if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_AVERAGERTT)
            {
                bufferList.AddRange(ToBytes(ncRes.baseRTT));
                bufferList.AddRange(ToBytes(ncRes.averageRTT));
            }
            else if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_BANDWIDTH_AVERAGERTT)
            {
                bufferList.AddRange(ToBytes(ncRes.baseRTT));
                bufferList.AddRange(ToBytes(ncRes.bandwidth));
                bufferList.AddRange(ToBytes(ncRes.averageRTT));
            }

            return bufferList.ToArray();
        }
        /// <summary>
        /// Parse NETWORK_DETECTION_REQUEST
        /// </summary>
        /// <param name="data"></param>
        /// <param name="currentIndex"></param>
        /// <returns></returns>
        public NETWORK_DETECTION_REQUEST ParseNetworkDectectRequest(byte[] data, ref int currentIndex)
        {
            NETWORK_DETECTION_REQUEST detectRequest = null;
            byte headerLength = ParseByte(data, ref currentIndex);
            HeaderTypeId_Values headerTypeId = (HeaderTypeId_Values)ParseByte(data, ref currentIndex);
            ushort sequenceNumber = ParseUInt16(data, ref currentIndex, false);
            AUTO_DETECT_REQUEST_TYPE requestType = (AUTO_DETECT_REQUEST_TYPE)ParseUInt16(data, ref currentIndex, false);

            if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_IN_CONNECTTIME
                || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_AFTER_CONNECTTIME)
            {
                RDP_RTT_REQUEST req = new RDP_RTT_REQUEST();
                req.headerLength = headerLength;
                req.headerTypeId = headerTypeId;
                req.sequenceNumber = sequenceNumber;
                req.requestType = requestType;

                detectRequest = req;
            }
            else if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_START_IN_CONNECTTIME
                || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_START_AFTER_CONNECTTIME_OR_RELIABLEUDP
                || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_START_AFTER_CONNECTTIME_OR_LOSSYUDP)
            {
                RDP_BW_START req = new RDP_BW_START();
                req.headerLength = headerLength;
                req.headerTypeId = headerTypeId;
                req.sequenceNumber = sequenceNumber;
                req.requestType = requestType;

                detectRequest = req;
            }
            else if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_PAYLOAD)
            {
                RDP_BW_PAYLOAD req = new RDP_BW_PAYLOAD();
                req.headerLength = headerLength;
                req.headerTypeId = headerTypeId;
                req.sequenceNumber = sequenceNumber;
                req.requestType = requestType;
                req.payloadLength = ParseUInt16(data, ref currentIndex, false);
                req.payload = GetBytes(data, ref currentIndex, req.payloadLength);

                detectRequest = req;
            }
            else if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_IN_CONNECTTIME
                || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_RELIABLEUDP
                || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_LOSSYUDP)
            {
                RDP_BW_STOP req = new RDP_BW_STOP();
                req.headerLength = headerLength;
                req.headerTypeId = headerTypeId;
                req.sequenceNumber = sequenceNumber;
                req.requestType = requestType;
                if (req.headerLength > 0x06)
                {
                    req.payloadLength = ParseUInt16(data, ref currentIndex, false);
                    req.payload = GetBytes(data, ref currentIndex, req.payloadLength);
                }

                detectRequest = req;
            }
            else
            {
                RDP_NETCHAR_RESULT req = new RDP_NETCHAR_RESULT();
                req.headerLength = headerLength;
                req.headerTypeId = headerTypeId;
                req.sequenceNumber = sequenceNumber;
                req.requestType = requestType;
                if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BANDWIDTH_AVERAGERTT)
                {
                    req.bandwidth = ParseUInt32(data, ref currentIndex, false);
                    req.averageRTT = ParseUInt32(data, ref currentIndex, false);
                }
                else if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_AVERAGERTT)
                {
                    req.baseRTT = ParseUInt32(data, ref currentIndex, false);
                    req.averageRTT = ParseUInt32(data, ref currentIndex, false);
                }
                else if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_BANDWIDTH_AVERAGERTT)
                {
                    req.baseRTT = ParseUInt32(data, ref currentIndex, false);
                    req.bandwidth = ParseUInt32(data, ref currentIndex, false);
                    req.averageRTT = ParseUInt32(data, ref currentIndex, false);
                }
                detectRequest = req;
            }

            return detectRequest;
        }
        public override NETWORK_DETECTION_REQUEST Clone()
        {
            RDP_NETCHAR_RESULT netCharRes = new RDP_NETCHAR_RESULT();
            netCharRes.headerLength = this.headerLength;
            netCharRes.headerTypeId = this.headerTypeId;
            netCharRes.requestType = this.requestType;
            netCharRes.sequenceNumber = this.sequenceNumber;

            netCharRes.baseRTT = this.baseRTT;
            netCharRes.bandwidth = this.bandwidth;
            netCharRes.averageRTT = this.averageRTT;

            return netCharRes;
        }
        /// <summary>
        /// Parse RDP_NETCHAR_RESULT structure from RDPEMT subheader
        /// </summary>
        /// <param name="data">Data of subheader, not include first two bytes of Parse RDP_NETCHAR_RESULT</param>
        /// <returns></returns>
        public static RDP_NETCHAR_RESULT ParseRdpNetCharResult(byte[] data)
        {
            RDP_NETCHAR_RESULT ncRes = new RDP_NETCHAR_RESULT();
            ncRes.sequenceNumber = ParseUInt16(data, 0);
            ncRes.requestType = (AUTO_DETECT_REQUEST_TYPE)ParseUInt16(data, 2);

            int index = 4;
            if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BANDWIDTH_AVERAGERTT)
            {
                ncRes.bandwidth = ParseUInt32(data, index);
                index += 4;
                ncRes.averageRTT = ParseUInt32(data, index);
                index += 4;
            }
            else if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_AVERAGERTT)
            {
                ncRes.baseRTT = ParseUInt32(data, index);
                index += 4;
                ncRes.averageRTT = ParseUInt32(data, index);
                index += 4;
            }
            else if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_BANDWIDTH_AVERAGERTT)
            {
                ncRes.baseRTT = ParseUInt32(data, index);
                index += 4;
                ncRes.bandwidth = ParseUInt32(data, index);
                index += 4;
                ncRes.averageRTT = ParseUInt32(data, index);
                index += 4;
            }

            return ncRes;
        }