/// <summary> /// [TD Reference 3.2.5.3.4] /// Decode MCS Connect Response PDU with GCC Conference Create Response /// </summary> /// <param name="data">data to be parsed</param> /// <returns>decoded MCS Connect Response PDU with GCC Conference Create Response PDU</returns> public StackPacket DecodeMcsConnectResponsePDU(byte[] data) { // initialize int currentIndex = 0; Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response pdu = new Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response(); // McsConnectResponse: TpktHeader pdu.tpktHeader = ParseTpktHeader(data, ref currentIndex); // McsConnectResponse: X224 pdu.x224Data = ParseX224Data(data, ref currentIndex); // T125 Data: decode McsConnectResponse int t125DataLength = data.Length - currentIndex; if (t125DataLength <= 0) { throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE); } byte[] t125Data = new byte[t125DataLength]; Array.Copy(data, currentIndex, t125Data, 0, t125Data.Length); Connect_Response mcsConnectResponse = new Connect_Response(); Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(t125Data); mcsConnectResponse.BerDecode(decodeBuffer); // McsConnectResponse:result pdu.mcsCrsp.result = (int)mcsConnectResponse.result.Value; byte[] userData = mcsConnectResponse.userData.ByteArrayValue; // T125 Data: decode McsConnectResponse's user data Asn1DecodingBuffer connectDataBuffer = new Asn1DecodingBuffer(userData); ConnectData connectData = new ConnectData(); connectData.PerDecode(connectDataBuffer); // T125 Data: get Gcc data int gccDataLength = userData.Length - ConstValue.GCC_DATA_OFFSET; if (gccDataLength <= 0) { throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE); } byte[] gccData = new byte[gccDataLength]; Array.Copy(userData, ConstValue.GCC_DATA_OFFSET, gccData, 0, gccData.Length); // T125 Data: decode Gcc user data ConnectGCCPDU gccPdu = new ConnectGCCPDU(); Asn1DecodingBuffer gccPduBuffer = new Asn1DecodingBuffer(gccData); gccPdu.PerDecode(gccPduBuffer); // McsConnectResponse: H221Key ConferenceCreateResponse conferenceResponse = (ConferenceCreateResponse)gccPdu.GetData(); H221NonStandardIdentifier identifier = (H221NonStandardIdentifier)conferenceResponse.userData.Elements[0].key.GetData(); pdu.mcsCrsp.gccPdu.H221Key = Encoding.ASCII.GetString(identifier.ByteArrayValue); // McsConnectResponse: ccrResult pdu.mcsCrsp.gccPdu.ccrResult = (int)conferenceResponse.result.Value; // McsConnectResponse: nodeID pdu.mcsCrsp.gccPdu.nodeID = (int)conferenceResponse.nodeID.Value; // McsConnectResponse: tag pdu.mcsCrsp.gccPdu.tag = (int)conferenceResponse.tag.Value; // T125 Data: get Gcc user data byte[] gccUserData = conferenceResponse.userData.Elements[0].value.ByteArrayValue; // Reset current index currentIndex = 0; while (currentIndex < gccUserData.Length) { // Peek data type int tempIndex = currentIndex; TS_UD_HEADER_type_Values type = (TS_UD_HEADER_type_Values)ParseUInt16(gccUserData, ref tempIndex, false); // Parse data by type switch (type) { case TS_UD_HEADER_type_Values.SC_CORE: pdu.mcsCrsp.gccPdu.serverCoreData = ParseTsUdScCore(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_NET: pdu.mcsCrsp.gccPdu.serverNetworkData = ParseTsUdScNet(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_SECURITY: pdu.mcsCrsp.gccPdu.serverSecurityData = ParseTsUdScSec1(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_MCS_MSGCHANNEL: pdu.mcsCrsp.gccPdu.serverMessageChannelData = ParseTsUdScMSGChannel(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_MULTITRANSPORT: pdu.mcsCrsp.gccPdu.serverMultitransportChannelData = ParseTsUdScMultiTransport(gccUserData, ref currentIndex); break; default: throw new FormatException(ConstValue.ERROR_MESSAGE_ENUM_UNRECOGNIZED); } } // Check if data length exceeded expectation VerifyDataLength(gccUserData.Length, currentIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED); return pdu; }
/// <summary> /// Encode this structure into byte array. /// </summary> /// <returns>The byte array of the structure.</returns> public override byte[] ToBytes() { List<byte> totalBuffer = new List<byte>(); RdpbcgrEncoder.EncodeStructure(totalBuffer, tpktHeader); RdpbcgrEncoder.EncodeStructure(totalBuffer, x224Data); if (mcsCrsp != null) { byte[] gccData = EncodeGccRspData(mcsCrsp.gccPdu); #region Filling MCS Connect Response PDU Connect_Response connectResponse = new Connect_Response(); connectResponse.result = new Result(mcsCrsp.result); connectResponse.calledConnectId = new Asn1Integer(mcsCrsp.calledConnectId); connectResponse.domainParameters = new DomainParameters(new Asn1Integer(mcsCrsp.domainParameters.maxChannelIds), new Asn1Integer(mcsCrsp.domainParameters.maxUserIds), new Asn1Integer(mcsCrsp.domainParameters.maxTokenIds), new Asn1Integer(mcsCrsp.domainParameters.numPriorities), new Asn1Integer(mcsCrsp.domainParameters.minThroughput), new Asn1Integer(mcsCrsp.domainParameters.maxHeight), new Asn1Integer(mcsCrsp.domainParameters.maxMcsPduSize), new Asn1Integer(mcsCrsp.domainParameters.protocolVersion)); connectResponse.userData = new Asn1OctetString(gccData); #endregion Filling MCS Connect Response PDU #region Encode MCS Connect Initial PDU Asn1BerEncodingBuffer berEncodeBuffer = new Asn1BerEncodingBuffer(); connectResponse.BerEncode(berEncodeBuffer); #endregion MCS Connect Initial PDU RdpbcgrEncoder.EncodeBytes(totalBuffer, berEncodeBuffer.Data); } byte[] encodedBytes = RdpbcgrUtility.ToBytes(totalBuffer); // ToDo: Ugly dump message code here // ETW Provider Dump Code RdpbcgrUtility.ETWProviderDump(this.GetType().Name, encodedBytes); return encodedBytes; }