public void S1_Connection_ConnectionFinalization_PositiveTest()
        {
            #region Test Steps
            //1. Initiate an RDP connection and complete the Connection Initiation phase, Basic Setting Exchange phase, Channel Connection phase, RDP Security Commencement phase, Secure Setting Exchange phase, Licensing phase, and Capabilities Exchange phase.
            //2. Test Suite continues the connection by sending the following PDUs sequentially:
            //    Client Synchronize PDU
            //    Client Control PDU - Cooperate
            //    Client Control PDU - Request Control
            //    Client Persistent Key List PDU(optional)
            //    Client Font List PDU
            //3. Test Suite expects and verifies the following PDUs one by one from SUT sequentially:
            //    Server Synchronize PDU
            //    Server Control PDU – Cooperate
            //    Server Control PDU - Granted Control
            //    Server Font Map PDU
            #endregion Test Steps

            #region Test Code

            this.Site.Log.Add(LogEntryKind.Comment, "Establish transport connection with RDP Server, encrypted protocol is {0}.", transportProtocol.ToString());
            rdpbcgrAdapter.ConnectToServer(this.transportProtocol);

            #region Connection Initiation

            this.Site.Log.Add(LogEntryKind.Comment, "Send a Client X.224 Connection Request PDU to SUT, supported security protocol is {0}.", requestProtocol.ToString());
            rdpbcgrAdapter.SendClientX224ConnectionRequest(NegativeType.None, requestProtocol);

            this.Site.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Server X224 Connection Confirm.");
            Server_X_224_Connection_Confirm_Pdu confirmPdu = rdpbcgrAdapter.ExpectPacket <Server_X_224_Connection_Confirm_Pdu>(timeout);
            this.Site.Assert.IsNotNull(confirmPdu, "RDP Server MUST response a Server X224 Connection Confirm PDU after receiving a Client X224 Connection Request PDU.");

            #endregion Connection Initiation

            #region Basic Setting Exchange

            string[] SVCNames = new string[] { RdpConstValue.SVCNAME_RDPEDYC };
            bool     supportMultitransportReliable = false;
            bool     supportMultitransportLossy    = false;
            this.Site.Log.Add(LogEntryKind.Comment, "Send a Client MCS Connect Initial PDU with GCC Conference Create Request to SUT, supportMultitransportReliable is {0}, supportMultitransportLossy is {1}.", supportMultitransportReliable, supportMultitransportLossy);
            rdpbcgrAdapter.SendClientMCSConnectInitialPDU(NegativeType.None, SVCNames, false, false, false, supportMultitransportReliable, supportMultitransportLossy, false);

            this.Site.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Server MCS Connect Response PDU with GCC Conference Create Response.");
            Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response response = rdpbcgrAdapter.ExpectPacket <Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response>(timeout);
            this.Site.Assert.IsNotNull(confirmPdu, "RDP Server MUST response a Server MCS Connect Response after receiving a Client MCS Connect Initial PDU.");

            #endregion Basic Setting Exchange

            #region Channel Connection

            this.Site.Log.Add(LogEntryKind.Comment, "Send a Client MCS Erect Domain Request PDU to SUT.");
            rdpbcgrAdapter.SendClientMCSErectDomainRequest(NegativeType.None);

            this.Site.Log.Add(LogEntryKind.Comment, "Send a Client MCS Attach User Request PDU to SUT.");
            rdpbcgrAdapter.SendClientMCSAttachUserRequest(NegativeType.None);

            this.Site.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Server MCS Attach User Confirm PDU.");
            Server_MCS_Attach_User_Confirm_Pdu attachuserConfirm = rdpbcgrAdapter.ExpectPacket <Server_MCS_Attach_User_Confirm_Pdu>(timeout);
            this.Site.Assert.IsNotNull(attachuserConfirm, "RDP Server MUST response a Server MCS Attach User Confirm PDU after receiving a Client MCS Attach User Request PDU.");

            this.Site.Log.Add(LogEntryKind.Comment, "The test suite proceeds to join the user channel, the input/output (I/O) channel, and all of the static virtual channels.");
            rdpbcgrAdapter.ChannelJoinRequestAndConfirm();

            #endregion Channel Connection

            #region Security Commencement phase, Secure Setting Exchange Phase and Licensing phase

            if (requestProtocol == requestedProtocols_Values.PROTOCOL_RDP_FLAG)
            {
                this.Site.Log.Add(LogEntryKind.Comment, "Standard RDP Security mechanisms are being employed, Test Suite sends a Client Security Exchange PDU to SUT.");
                rdpbcgrAdapter.SendClientSecurityExchangePDU(NegativeType.None);
            }

            this.Site.Log.Add(LogEntryKind.Comment, "Send a Client Info PDU.");
            rdpbcgrAdapter.SendClientInfoPDU(NegativeType.None, CompressionType.PACKET_COMPR_TYPE_RDP61, false);

            Server_License_Error_Pdu_Valid_Client licenseErrorPdu = rdpbcgrAdapter.ExpectPacket <Server_License_Error_Pdu_Valid_Client>(timeout);
            this.Site.Assert.IsNotNull(licenseErrorPdu, "RDP Server MUST send a Server License Error PDU during Licensing phase.");

            #endregion Security Commencement phase, Secure Setting Exchange Phase and Licensing phase

            #region Capabilities Exchange phase

            Server_Demand_Active_Pdu demandActivePdu = rdpbcgrAdapter.ExpectPacket <Server_Demand_Active_Pdu>(timeout);
            this.Site.Assert.IsNotNull(demandActivePdu, "If the Licensing phase of the RDP Connection Sequence is successfully completed, RDP server must send a Server Demand Active PDU.");

            this.Site.Log.Add(LogEntryKind.Comment, "Send a Client Confirm Active PDU.");
            rdpbcgrAdapter.SendClientConfirmActivePDU(NegativeType.None, true, true, true, true, true, true);

            #endregion Capabilities Exchange phase

            this.Site.Log.Add(LogEntryKind.Comment, "Send a Client Synchronize PDU.");
            rdpbcgrAdapter.SendClientSynchronizePDU();

            Server_Synchronize_Pdu synchronizePdu = rdpbcgrAdapter.ExpectPacket <Server_Synchronize_Pdu>(timeout);
            this.Site.Assert.IsNotNull(synchronizePdu, "RDP Server MUST send a Server Synchronize PDU after receiving a Client Confirm Active PDU.");

            Server_Control_Pdu_Cooperate controlPdu = rdpbcgrAdapter.ExpectPacket <Server_Control_Pdu_Cooperate>(timeout);
            this.Site.Assert.IsNotNull(controlPdu, "RDP Server MUST send a Server Control PDU – Cooperate during Connection Finalization phase");

            this.Site.Log.Add(LogEntryKind.Comment, "Send a Client Control PDU - Cooperate.");
            rdpbcgrAdapter.SendClientControlCooperatePDU();

            this.Site.Log.Add(LogEntryKind.Comment, "Send a Client Control PDU - Request Control.");
            rdpbcgrAdapter.SendClientControlRequestPDU();

            Server_Control_Pdu_Granted_Control grantedControlPdu = rdpbcgrAdapter.ExpectPacket <Server_Control_Pdu_Granted_Control>(timeout);
            this.Site.Assert.IsNotNull(grantedControlPdu, "RDP Server MUST send a Server Control PDU – Granted Control during Connection Finalization phase");

            if (rdpbcgrAdapter.IsBitmapCacheHostSupport)
            {
                this.Site.Log.Add(LogEntryKind.Comment, "Bitmap Cache Host is supported, send a Client Persistent Key List PDU.");
                rdpbcgrAdapter.SendClientPersistentKeyListPDU();
            }

            this.Site.Log.Add(LogEntryKind.Comment, "Send a Client Font List PDU.");
            rdpbcgrAdapter.SendClientFontListPDU();

            Server_Font_Map_Pdu fontMapPdu = rdpbcgrAdapter.ExpectPacket <Server_Font_Map_Pdu>(timeout);
            this.Site.Assert.IsNotNull(fontMapPdu, "RDP Server MUST send a Server Font Map PDU during Connection Finalization phase");

            #endregion Test Code
        }
        /// <summary>
        /// Establish a RDP connection with RDP Server
        /// </summary>
        /// <param name="requestedProtocols">Flags indicate supported security protocols</param>
        /// <param name="SVCNames">Array of static virtual channels' name</param>
        /// <param name="highestCompressionTypeSupported">Indicate the highest compression type supported</param>
        /// <param name="isReconnect">Whether this is in a reconnection sequence</param>        ///
        /// <param name="autoLogon">Whether auto logon using username and password in client info PDU</param>
        /// <param name="supportEGFX">Set the support of RDPEGFX</param>
        /// <param name="supportAutoDetect">Set the support of auto-detect</param>
        /// <param name="supportHeartbeatPDU">Set the support of Heartbeat PDU</param>
        /// <param name="supportMultitransportReliable">Set the support of reliable multitransport</param>
        /// <param name="supportMultitransportLossy">Set the support of lossy multitransport</param>
        /// <param name="supportAutoReconnect">Set the support of auto-reconnect</param>
        /// <param name="supportFastPathInput">Set the support of fast-path input</param>
        /// <param name="supportFastPathOutput">Set the support of fast-path output</param>
        /// <param name="supportSurfaceCommands">Set the support of surface commands</param>
        /// <param name="supportSVCCompression">Set the support of static virtual channel data compression</param>
        /// <param name="supportRemoteFXCodec">Set the support of RemoteFX codecs</param>
        public void EstablishRDPConnection(requestedProtocols_Values requestedProtocols,
                                           string[] SVCNames,
                                           CompressionType highestCompressionTypeSupported,
                                           bool isReconnect                   = false,
                                           bool autoLogon                     = false,
                                           bool supportEGFX                   = false,
                                           bool supportAutoDetect             = false,
                                           bool supportHeartbeatPDU           = false,
                                           bool supportMultitransportReliable = false,
                                           bool supportMultitransportLossy    = false,
                                           bool supportAutoReconnect          = false,
                                           bool supportFastPathInput          = false,
                                           bool supportFastPathOutput         = false,
                                           bool supportSurfaceCommands        = false,
                                           bool supportSVCCompression         = false,
                                           bool supportRemoteFXCodec          = false)
        {
            #region logging
            string requestProtocolString = "PROTOCOL_RDP_FLAG";
            if (requestedProtocols.HasFlag(requestedProtocols_Values.PROTOCOL_SSL_FLAG))
            {
                requestProtocolString = requestProtocolString + "|PROTOCOL_SSL_FLAG";
            }
            if (requestedProtocols.HasFlag(requestedProtocols_Values.PROTOCOL_HYBRID_FLAG))
            {
                requestProtocolString = requestProtocolString + "|PROTOCOL_HYBRID_FLAG";
            }
            if (requestedProtocols.HasFlag(requestedProtocols_Values.PROTOCOL_HYBRID_EX))
            {
                requestProtocolString = requestProtocolString + "|PROTOCOL_HYBRID_EX";
            }
            string svcNameString = "";
            if (SVCNames != null && SVCNames.Length > 0)
            {
                foreach (string svcName in SVCNames)
                {
                    svcNameString = svcNameString + svcName + ",";
                }
            }
            this.Site.Log.Add(LogEntryKind.Comment, @"EstablishRDPConnection:
                request Protocols = {0},
                Name of static virtual channels = {1},
                Highest compression type supported = {2},
                Is Reconnect = {3}
                RDPEGFX supported = {4},
                AutoDetect supported = {5},
                HeartbeatPDU supported = {6},
                Reliable Multitransport supported = {7},
                Lossy Multitransport supported = {8},
                AutoReconnect supported = {9},
                FastPathInput supported= {10},
                FastPathOutput supported = {11},
                SurfaceCommands supported = {12},
                SVCCompression supported = {13},
                RemoteFXCodec supported = {14}.",
                              requestProtocolString, svcNameString, highestCompressionTypeSupported.ToString(), isReconnect, supportEGFX, supportAutoDetect, supportHeartbeatPDU,
                              supportMultitransportReliable, supportMultitransportLossy, supportAutoReconnect, supportFastPathInput, supportFastPathOutput, supportSurfaceCommands,
                              supportSVCCompression, supportRemoteFXCodec);
            #endregion logging

            #region Connection Initiation

            SendClientX224ConnectionRequest(NegativeType.None, requestedProtocols);

            Server_X_224_Connection_Confirm_Pdu connectionConfirmPdu = ExpectPacket <Server_X_224_Connection_Confirm_Pdu>(pduWaitTimeSpan);
            if (connectionConfirmPdu == null)
            {
                TimeSpan waitTime = new TimeSpan(0, 0, 1);
                Server_X_224_Negotiate_Failure_Pdu failurePdu = ExpectPacket <Server_X_224_Negotiate_Failure_Pdu>(waitTime);
                if (failurePdu != null)
                {
                    Site.Assert.Fail("Received a Server X224 Connection confirm with RDP_NEG_FAILURE structure, failureCode is {0}.", failurePdu.rdpNegFailure.failureCode);
                }
                Site.Assert.Fail("Expecting a Server X224 Connection Confirm PDU.");
            }

            if (supportEGFX)
            {
                // Verify support of EGFX on Server
                Site.Assert.IsTrue(connectionConfirmPdu.rdpNegData != null &&
                                   connectionConfirmPdu.rdpNegData.flags.HasFlag(RDP_NEG_RSP_flags_Values.DYNVC_GFX_PROTOCOL_SUPPORTED), "The RDP Server should support RDPEGFX.");
            }
            #endregion Connection Initiation

            #region Basic Setting Exchange

            SendClientMCSConnectInitialPDU(NegativeType.None, SVCNames, supportEGFX, supportAutoDetect, supportHeartbeatPDU, supportMultitransportReliable, supportMultitransportLossy, false);

            Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response connectResponsePdu = ExpectPacket <Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response>(pduWaitTimeSpan);
            Site.Assert.IsNotNull(connectResponsePdu, "Expecting a Server MCS Connect Response PDU with GCC Conference Create Response.");
            if (connectResponsePdu.mcsCrsp.gccPdu.serverMultitransportChannelData != null)
            {
                if (connectResponsePdu.mcsCrsp.gccPdu.serverMultitransportChannelData.flags.HasFlag(MULTITRANSPORT_TYPE_FLAGS.TRANSPORTTYPE_UDPFECR))
                {
                    this.serverSupportUDPFECR = true;
                }
                if (connectResponsePdu.mcsCrsp.gccPdu.serverMultitransportChannelData.flags.HasFlag(MULTITRANSPORT_TYPE_FLAGS.TRANSPORTTYPE_UDPFECL))
                {
                    this.serverSupportUDPFECL = true;
                }
                if (connectResponsePdu.mcsCrsp.gccPdu.serverMultitransportChannelData.flags.HasFlag(MULTITRANSPORT_TYPE_FLAGS.TRANSPORTTYPE_UDP_PREFERRED))
                {
                    this.serverSupportUDPPrefferred = true;
                }
            }

            #endregion Basic Setting Exchange

            #region Channel Connection

            SendClientMCSErectDomainRequest(NegativeType.None);

            SendClientMCSAttachUserRequest(NegativeType.None);

            Server_MCS_Attach_User_Confirm_Pdu userConfirmPdu = ExpectPacket <Server_MCS_Attach_User_Confirm_Pdu>(pduWaitTimeSpan);
            Site.Assert.IsNotNull(userConfirmPdu, "Expecting a Server MCS Attach User Confirm PDU.");

            ChannelJoinRequestAndConfirm();

            #endregion

            #region RDP Security Commencement

            if (rdpbcgrClientStack.Context.ServerSelectedProtocol == (uint)selectedProtocols_Values.PROTOCOL_RDP_FLAG)
            {
                SendClientSecurityExchangePDU(NegativeType.None);
            }

            #endregion

            #region Secure Setting Exchange

            SendClientInfoPDU(NegativeType.None, highestCompressionTypeSupported, isReconnect, autoLogon);

            #endregion

            #region Licensing
            Server_License_Error_Pdu_Valid_Client licenseErrorPdu = ExpectPacket <Server_License_Error_Pdu_Valid_Client>(pduWaitTimeSpan);
            Site.Assert.IsNotNull(licenseErrorPdu, "Expecting a Server License Error PDU.");

            #endregion

            #region Capabilities Exchange

            Server_Demand_Active_Pdu demandActivePdu = ExpectPacket <Server_Demand_Active_Pdu>(pduWaitTimeSpan);
            Site.Assert.IsNotNull(demandActivePdu, "Expecting a Server Demand Active PDU.");

            SendClientConfirmActivePDU(NegativeType.None, supportAutoReconnect, supportFastPathInput, supportFastPathOutput, supportSurfaceCommands, supportSVCCompression, supportRemoteFXCodec);

            #endregion

            #region Connection Finalization

            SendClientSynchronizePDU();

            Server_Synchronize_Pdu syncPdu = ExpectPacket <Server_Synchronize_Pdu>(pduWaitTimeSpan);
            Site.Assert.IsNotNull(syncPdu, "Expecting a Server Synchronize PDU.");

            Server_Control_Pdu_Cooperate CoopControlPdu = ExpectPacket <Server_Control_Pdu_Cooperate>(pduWaitTimeSpan);
            Site.Assert.IsNotNull(CoopControlPdu, "Expecting a Server Control PDU - Cooperate.");

            SendClientControlCooperatePDU();

            SendClientControlRequestPDU();

            Server_Control_Pdu_Granted_Control grantedControlPdu = ExpectPacket <Server_Control_Pdu_Granted_Control>(pduWaitTimeSpan);
            Site.Assert.IsNotNull(grantedControlPdu, "Expecting a Server Control PDU - Granted Control.");


            if (IsBitmapCacheHostSupport)
            {
                SendClientPersistentKeyListPDU();
            }

            SendClientFontListPDU();

            Server_Font_Map_Pdu fontMapPdu = ExpectPacket <Server_Font_Map_Pdu>(pduWaitTimeSpan);
            Site.Assert.IsNotNull(fontMapPdu, "Expecting a Server Font Map PDU.");

            #endregion
        }
        private bool EstablishRDPConnection(
            Configs config,
            requestedProtocols_Values requestedProtocols,
            string[] SVCNames,
            CompressionType highestCompressionTypeSupported,
            bool isReconnect                   = false,
            bool autoLogon                     = false,
            bool supportEGFX                   = false,
            bool supportAutoDetect             = false,
            bool supportHeartbeatPDU           = false,
            bool supportMultitransportReliable = false,
            bool supportMultitransportLossy    = false,
            bool supportAutoReconnect          = false,
            bool supportFastPathInput          = false,
            bool supportFastPathOutput         = false,
            bool supportSurfaceCommands        = false,
            bool supportSVCCompression         = false,
            bool supportRemoteFXCodec          = false)
        {
            // Connection Initiation
            SendClientX224ConnectionRequest(requestedProtocols);
            Server_X_224_Connection_Confirm_Pdu connectionConfirmPdu = ExpectPacket <Server_X_224_Connection_Confirm_Pdu>(new TimeSpan(0, 0, 60));

            if (connectionConfirmPdu == null)
            {
                TimeSpan waitTime = new TimeSpan(0, 0, 1);
                Server_X_224_Negotiate_Failure_Pdu failurePdu = ExpectPacket <Server_X_224_Negotiate_Failure_Pdu>(waitTime);
                if (failurePdu != null)
                {
                    DetectorUtil.WriteLog("Received a Server X224 Connection confirm with RDP_NEG_FAILURE structure.");
                }
                DetectorUtil.WriteLog("Expecting a Server X224 Connection Confirm PDU.");
                return(false);
            }

            // Basic Settings Exchange
            SendClientMCSConnectInitialPDU(
                SVCNames,
                supportEGFX,
                supportAutoDetect,
                supportHeartbeatPDU,
                supportMultitransportReliable,
                supportMultitransportLossy,
                false);
            connectResponsePdu = ExpectPacket <Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response>(timeout);
            if (connectResponsePdu == null)
            {
                return(false);
            }

            bool serverSupportUDPFECR = false;
            bool serverSupportUDPFECL = false;

            if (connectResponsePdu.mcsCrsp.gccPdu.serverMultitransportChannelData != null)
            {
                if (connectResponsePdu.mcsCrsp.gccPdu.serverMultitransportChannelData.flags.HasFlag(MULTITRANSPORT_TYPE_FLAGS.TRANSPORTTYPE_UDPFECR))
                {
                    serverSupportUDPFECR = true;
                }
                if (connectResponsePdu.mcsCrsp.gccPdu.serverMultitransportChannelData.flags.HasFlag(MULTITRANSPORT_TYPE_FLAGS.TRANSPORTTYPE_UDPFECL))
                {
                    serverSupportUDPFECL = true;
                }
            }
            detectInfo.IsSupportRDPEMT = serverSupportUDPFECR || serverSupportUDPFECL;

            // Channel Connection
            SendClientMCSErectDomainRequest();
            SendClientMCSAttachUserRequest();
            Server_MCS_Attach_User_Confirm_Pdu userConfirmPdu = ExpectPacket <Server_MCS_Attach_User_Confirm_Pdu>(timeout);

            if (userConfirmPdu == null)
            {
                return(false);
            }
            ChannelJoinRequestAndConfirm();

            // RDP Security Commencement
            if (rdpbcgrClient.Context.ServerSelectedProtocol == (uint)selectedProtocols_Values.PROTOCOL_RDP_FLAG)
            {
                SendClientSecurityExchangePDU();
            }

            // Secure Settings Exchange
            SendClientInfoPDU(config, highestCompressionTypeSupported, isReconnect, autoLogon);
            rdpeleClient = new RdpeleClient(rdpbcgrClient);

            try
            {
                detectInfo.IsSupportRDPELE = ProcessLicenseSequence(config, timeout);
            }
            catch
            {
                detectInfo.IsSupportRDPELE = false;
            }
            rdpeleClient.Dispose();

            // Capabilities Exchange
            Server_Demand_Active_Pdu demandActivePdu = ExpectPacket <Server_Demand_Active_Pdu>(timeout);

            if (demandActivePdu == null)
            {
                return(false);
            }
            SendClientConfirmActivePDU(
                supportAutoReconnect,
                supportFastPathInput,
                supportFastPathOutput,
                supportSVCCompression);

            // Connection Finalization
            SendClientSynchronizePDU();
            Server_Synchronize_Pdu syncPdu = ExpectPacket <Server_Synchronize_Pdu>(timeout);

            if (syncPdu == null)
            {
                return(false);
            }
            Server_Control_Pdu_Cooperate CoopControlPdu = ExpectPacket <Server_Control_Pdu_Cooperate>(timeout);

            if (CoopControlPdu == null)
            {
                return(false);
            }
            SendClientControlCooperatePDU();
            SendClientControlRequestPDU();
            Server_Control_Pdu_Granted_Control grantedControlPdu = ExpectPacket <Server_Control_Pdu_Granted_Control>(timeout);

            if (grantedControlPdu == null)
            {
                return(false);
            }
            SendClientFontListPDU();
            Server_Font_Map_Pdu fontMapPdu = ExpectPacket <Server_Font_Map_Pdu>(timeout);

            if (fontMapPdu == null)
            {
                return(false);
            }
            return(true);
        }
        /// <summary>
        /// [TD Reference 3.2.5.3.20]
        /// Decode Control PDU - Cooperate
        /// </summary>
        /// <param name="data">data to be parsed</param>
        /// <param name="decryptedUserData">decrypted user data to be parsed</param>
        /// <param name="type">security header type</param>
        /// <returns>decoded Control PDU</returns>
        public StackPacket DecodeControlPDU(
            byte[] data,
            byte[] decryptedUserData,
            SecurityHeaderType type)
        {
            // data index
            int dataIndex = 0;

            // ControlPDU: commonHeader
            SlowPathPduCommonHeader commonHeader = ParseMcsCommonHeader(data, ref dataIndex, type);

            // user data index
            int userDataIndex = 0;

            // ControlPDU: controlPduData
            TS_CONTROL_PDU controlPduData = ParseTsControlPdu(decryptedUserData, ref userDataIndex);

            // Get pdu by action type
            StackPacket pdu;
            if (controlPduData.action == action_Values.CTRLACTION_COOPERATE)
            {
                // Control PDU - cooperate
                Server_Control_Pdu_Cooperate cooperatePdu = new Server_Control_Pdu_Cooperate();
                cooperatePdu.commonHeader = commonHeader;
                cooperatePdu.controlPduData = controlPduData;
                pdu = cooperatePdu;
            }
            else if (controlPduData.action == action_Values.CTRLACTION_GRANTED_CONTROL)
            {
                // Control PDU - granted control
                Server_Control_Pdu_Granted_Control grantedPdu = new Server_Control_Pdu_Granted_Control();
                grantedPdu.commonHeader = commonHeader;
                grantedPdu.controlPduData = controlPduData;
                pdu = grantedPdu;
            }
            else
            {
                throw new FormatException(ConstValue.ERROR_MESSAGE_ENUM_UNRECOGNIZED);
            }

            // Check if data length exceeded expectation
            VerifyDataLength(decryptedUserData.Length, userDataIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED);
            return pdu;
        }