Gcc used in MCSConnectInitial.
        /// <summary>
        /// Encode GCC Conference Create Request according to [T124].
        /// </summary>
        /// <param name="gccPdu">The data to be encoded.</param>
        /// <returns>The encoded data.</returns>
        private static byte[] EncodeGccRspData(ConnectGCCRsp gccPdu)
        {
            if (gccPdu == null)
            {
                return null;
            }

            #region Encode userData
            List<byte> userData = new List<byte>();

            #region Encode serverCoreData structure TS_UD_CS_CORE
            if (gccPdu.serverCoreData != null)
            {
                List<byte> coreData = new List<byte>();
                RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.serverCoreData.header);
                RdpbcgrEncoder.EncodeStructure(coreData, (uint)gccPdu.serverCoreData.version);
                RdpbcgrEncoder.EncodeStructure(coreData, (uint)gccPdu.serverCoreData.clientRequestedProtocols);
                //earlyCapabilityFlags is optional.
                if(gccPdu.serverCoreData.earlyCapabilityFlags != 0)
                    RdpbcgrEncoder.EncodeStructure(coreData, (uint)gccPdu.serverCoreData.earlyCapabilityFlags);

                userData.AddRange(coreData.ToArray());
            }
            #endregion Encode serverCoreData structure TS_UD_CS_CORE

            #region Encode serverNetworkData TS_UD_CS_NET
            if (gccPdu.serverNetworkData != null)
            {
                List<byte> networkData = new List<byte>();
                RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.header);
                RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.MCSChannelId);
                RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.channelCount);
                for (int i = 0; i < gccPdu.serverNetworkData.channelCount; ++i)
                {
                    RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.channelIdArray[i]);
                }
                if (gccPdu.serverNetworkData.Pad != null)
                {
                    RdpbcgrEncoder.EncodeBytes(networkData, gccPdu.serverNetworkData.Pad);
                }
                userData.AddRange(networkData.ToArray());
            }
            #endregion Encode serverNetworkData TS_UD_CS_NET

            #region Encode serverSecurityData TS_UD_CS_SEC
            if (gccPdu.serverSecurityData != null)
            {
                List<byte> securityData = new List<byte>();
                RdpbcgrEncoder.EncodeStructure(securityData, gccPdu.serverSecurityData.header);
                RdpbcgrEncoder.EncodeStructure(securityData, (uint)gccPdu.serverSecurityData.encryptionMethod);
                RdpbcgrEncoder.EncodeStructure(securityData, (uint)gccPdu.serverSecurityData.encryptionLevel);

                if (gccPdu.serverSecurityData.encryptionMethod != EncryptionMethods.ENCRYPTION_METHOD_NONE ||
                    gccPdu.serverSecurityData.encryptionLevel != EncryptionLevel.ENCRYPTION_LEVEL_NONE)
                {
                    RdpbcgrEncoder.EncodeStructure(securityData, gccPdu.serverSecurityData.serverRandomLen.actualData);
                    RdpbcgrEncoder.EncodeStructure(securityData, gccPdu.serverSecurityData.serverCertLen.actualData);
                    if (gccPdu.serverSecurityData.serverRandom != null)
                    {
                        RdpbcgrEncoder.EncodeBytes(securityData, gccPdu.serverSecurityData.serverRandom);
                    }

                    #region Encode certificate
                    if (gccPdu.serverSecurityData.serverCertificate != null)
                    {
                        RdpbcgrEncoder.EncodeStructure(securityData, (uint)gccPdu.serverSecurityData.serverCertificate.dwVersion);
                        if (gccPdu.serverSecurityData.serverCertificate.dwVersion == SERVER_CERTIFICATE_dwVersion_Values.CERT_CHAIN_VERSION_1)
                        {
                            PROPRIETARYSERVERCERTIFICATE cert = (PROPRIETARYSERVERCERTIFICATE)gccPdu.serverSecurityData.serverCertificate.certData;
                            RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.dwSigAlgId);
                            RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.dwKeyAlgId);
                            RdpbcgrEncoder.EncodeStructure(securityData, (ushort)cert.wPublicKeyBlobType);
                            RdpbcgrEncoder.EncodeStructure(securityData, cert.wPublicKeyBlobLen);
                            RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.PublicKeyBlob.magic);
                            RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.keylen);
                            RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.bitlen);
                            RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.datalen);
                            RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.pubExp);
                            RdpbcgrEncoder.EncodeBytes(securityData, cert.PublicKeyBlob.modulus);
                            RdpbcgrEncoder.EncodeStructure(securityData, (ushort)cert.wSignatureBlobType);
                            RdpbcgrEncoder.EncodeStructure(securityData, cert.wSignatureBlobLen);
                            RdpbcgrEncoder.EncodeBytes(securityData, cert.SignatureBlob);
                        }
                        else if (gccPdu.serverSecurityData.serverCertificate.dwVersion == SERVER_CERTIFICATE_dwVersion_Values.CERT_CHAIN_VERSION_2)
                        {
                            X509_CERTIFICATE_CHAIN cert = (X509_CERTIFICATE_CHAIN)gccPdu.serverSecurityData.serverCertificate.certData;
                            RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.NumCertBlobs);
                            for (int i = 0; i < cert.CertBlobArray.Length; i++)
                            {
                                RdpbcgrEncoder.EncodeStructure(securityData, cert.CertBlobArray[i].cbCert);
                                RdpbcgrEncoder.EncodeBytes(securityData, cert.CertBlobArray[i].abCert);
                            }
                            RdpbcgrEncoder.EncodeBytes(securityData, cert.Padding);
                        }
                    }
                    #endregion
                }
                userData.AddRange(securityData.ToArray());
            }
            #endregion Encode serverSecurityData TS_UD_CS_SEC

            #region Encode serverMessageChannelData TS_UD_SC_MCS_MSGCHANNEL
            if (gccPdu.serverMessageChannelData != null)
            {
                List<byte> msgChannelData = new List<byte>();
                RdpbcgrEncoder.EncodeStructure(msgChannelData, gccPdu.serverMessageChannelData.header);
                RdpbcgrEncoder.EncodeStructure(msgChannelData, gccPdu.serverMessageChannelData.MCSChannelID);
                userData.AddRange(msgChannelData.ToArray());
            }
            #endregion

            #region Encode serverMultitransportChannelData TS_UD_SC_MULTITRANSPORT
            if (gccPdu.serverMultitransportChannelData != null)
            {
                List<byte> multiTranChannelData = new List<byte>();
                RdpbcgrEncoder.EncodeStructure(multiTranChannelData, gccPdu.serverMultitransportChannelData.header);
                RdpbcgrEncoder.EncodeStructure(multiTranChannelData, (uint)gccPdu.serverMultitransportChannelData.flags);
                userData.AddRange(multiTranChannelData.ToArray());
            }
            #endregion

            #endregion Encode userData

            #region Filling GCC Conference Create Request
            ConferenceCreateResponse gccCCrsp = new ConferenceCreateResponse();
            gccCCrsp.nodeID = new UserID(gccPdu.nodeID);
            gccCCrsp.tag = new Asn1Integer(gccPdu.tag);
            gccCCrsp.result = new ConferenceCreateResponse_result(gccPdu.ccrResult);
            //gccCCrsp.extElem1 = new Asn1OpenExt();
            UserDataElement[] dataElements = new UserDataElement[1];
            dataElements[0] = new UserDataElement();
            dataElements[0].key = new Key(Key.h221NonStandard,
                                          new H221NonStandardIdentifier(gccPdu.H221Key));
            dataElements[0].value = new Asn1OctetString(userData.ToArray());
            gccCCrsp.userData = new UserData(dataElements);
            ConnectGCCPDU cGccPdu = new ConnectGCCPDU(ConnectGCCPDU.conferenceCreateResponse, gccCCrsp);
            #endregion Filling GCC Conference Create Request

            #region Encode ConnectData
            Asn1PerEncodingBuffer perBuffer = new Asn1PerEncodingBuffer(true);
            cGccPdu.PerEncode(perBuffer);
            byte[] asnEncodedData = perBuffer.ByteArrayData;
            Key key = new Key(Key.obj, new Asn1ObjectIdentifier(ConstValue.MCS_ATTRIBUTE_ID));
            ConnectData connectData = new ConnectData(key, new Asn1OctetString(asnEncodedData));
            Asn1PerEncodingBuffer perBuffer2 = new Asn1PerEncodingBuffer(true);
            connectData.PerEncode(perBuffer2);
            #endregion Encode ConnectData

            #region Workaround for Windows encoding issue

            //reset the ConnectPDULength to one-byte length: 0x2A
            byte[] returnButter = null;
            if ((perBuffer2.ByteArrayData[7] & 0x80) == 0x80)
            {
                //If length is two-byte, delete one byte
                returnButter = new byte[perBuffer2.ByteArrayData.Length - 1];
                Array.Copy(perBuffer2.ByteArrayData, returnButter, 7);
                Array.Copy(perBuffer2.ByteArrayData, 8, returnButter, 7, returnButter.Length - 7);
            }
            else
            {
                returnButter = new byte[perBuffer2.ByteArrayData.Length];
                Array.Copy(perBuffer2.ByteArrayData, returnButter, perBuffer2.ByteArrayData.Length);
            }
            returnButter[7] = 0x2A;

            #endregion

            return returnButter;
        }
 public MCSConnectResponse()
 {
     gccPdu = new ConnectGCCRsp();
 }