/// <summary>
 /// The callback method to receive data from transport layer.
 /// </summary>
 private void OnDataReceived(byte[] data, uint channelId)
 {
     lock (receivedList)
     {
         RdpegfxPdu pdu      = new RdpegfxPdu();
         bool       fSucceed = false;
         bool       fResult  = PduMarshaler.Unmarshal(data, pdu);
         if (fResult)
         {
             byte[] pduData = new byte[pdu.Header.pduLength];
             Array.Copy(data, pduData, pduData.Length);
             if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CAPSADVERTISE)
             {
                 RDPGFX_CAPS_ADVERTISE recv = new RDPGFX_CAPS_ADVERTISE();
                 fSucceed = AddToReceivedList(pduData, recv);
             }
             else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_FRAMEACKNOWLEDGE)
             {
                 RDPGFX_FRAME_ACK recv = new RDPGFX_FRAME_ACK();
                 fSucceed = AddToReceivedList(pduData, recv);
             }
             else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CACHEIMPORTOFFER)
             {
                 RDPGFX_CACHE_IMPORT_OFFER recv = new RDPGFX_CACHE_IMPORT_OFFER();
                 fSucceed = AddToReceivedList(pduData, recv);
             }
         }
         if (!fResult || !fSucceed)
         {
             RdpegfxUnkownPdu unkown = new RdpegfxUnkownPdu();
             PduMarshaler.Unmarshal(data, unkown);
             receivedList.Add(unkown);
         }
     }
 }
        /// <summary>
        /// The AddToReceivedList method to add receive message into receive list.
        /// </summary>
        private bool AddToReceivedList(byte[] pduData, RdpegfxPdu recv)
        {
            bool fSucceed = false;

            try
            {
                fSucceed = PduMarshaler.Unmarshal(pduData, recv);
                receivedList.Add(recv);
            }
            catch (PDUDecodeException decodeExceptioin)
            {
                RdpegfxUnkownPdu unkown = new RdpegfxUnkownPdu();
                fSucceed = PduMarshaler.Unmarshal(decodeExceptioin.DecodingData, unkown);
                receivedList.Add(unkown);
            }
            return(fSucceed);
        }
        /// <summary>
        /// Decode one PDU
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static RdpegfxPdu DecodeSinglePdu(byte[] data)
        {
            RdpegfxPdu pdu     = new RdpegfxPdu();
            bool       fResult = PduMarshaler.Unmarshal(data, pdu);

            if (fResult)
            {
                RdpegfxServerPdu receivedPdu = null;
                if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_WIRETOSURFACE_1)
                {
                    receivedPdu = new RDPGFX_WIRE_TO_SURFACE_PDU_1();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_WIRETOSURFACE_2)
                {
                    receivedPdu = new RDPGFX_WIRE_TO_SURFACE_PDU_2();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_DELETEENCODINGCONTEXT)
                {
                    receivedPdu = new RDPGFX_DELETE_ENCODING_CONTEXT();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_SOLIDFILL)
                {
                    receivedPdu = new RDPGFX_SOLIDFILL();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_SURFACETOSURFACE)
                {
                    receivedPdu = new RDPGFX_SURFACE_TO_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_SURFACETOCACHE)
                {
                    receivedPdu = new RDPGFX_SURFACE_TO_CACHE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CACHETOSURFACE)
                {
                    receivedPdu = new RDPGFX_CACHE_TO_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_EVICTCACHEENTRY)
                {
                    receivedPdu = new RDPGFX_EVICT_CACHE_ENTRY();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CREATESURFACE)
                {
                    receivedPdu = new RDPGFX_CREATE_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_DELETESURFACE)
                {
                    receivedPdu = new RDPGFX_DELETE_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_STARTFRAME)
                {
                    receivedPdu = new RDPGFX_START_FRAME();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_ENDFRAME)
                {
                    receivedPdu = new RDPGFX_END_FRAME();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_RESETGRAPHICS)
                {
                    receivedPdu = new RDPGFX_RESET_GRAPHICS();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOOUTPUT)
                {
                    receivedPdu = new RDPGFX_MAPSURFACE_TO_OUTPUT();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CACHEIMPORTREPLY)
                {
                    receivedPdu = new RDPGFX_CACHE_IMPORT_REPLY();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CAPSCONFIRM)
                {
                    receivedPdu = new RDPGFX_CAPS_CONFIRM();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOWINDOW)
                {
                    receivedPdu = new RDPGFX_MAP_SURFACE_TO_WINDOW();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE)
                {
                    receivedPdu = new RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOSCALEDOUTPUT)
                {
                    receivedPdu = new RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOSCALEDWINDOW)
                {
                    receivedPdu = new RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU();
                }

                if (receivedPdu != null && PduMarshaler.Unmarshal(data, receivedPdu))
                {
                    return(receivedPdu);
                }
            }
            RdpegfxUnkownPdu unkown = new RdpegfxUnkownPdu();

            PduMarshaler.Unmarshal(data, unkown);
            return(unkown);
        }