public TPDUConnection(byte[] packet) { int pos; int li = packet[0]; TPDU.TPDU_TYPES type = (TPDU.TPDU_TYPES)(packet[1] >> 4); if ((type != TPDU.TPDU_TYPES.CR) && (type != TPDU.TPDU_TYPES.CC)) { throw new ApplicationException("TPDU: This can only handle CC/CR TDPUs"); } if (BitConverter.IsLittleEndian) { DstRef = ByteConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 2)); SrcRef = ByteConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 4)); } else { DstRef = BitConverter.ToUInt16(packet, 2); SrcRef = BitConverter.ToUInt16(packet, 4); } ClassOption = ((packet[6] & 0xf0) >> 4); if (ClassOption > 4) { throw new Exception("TPDU: Class option number not allowed."); } pos = 7; // read variable part Varpart = new ArrayList(); try { while (pos < li) { VarParam vp = new VarParam(); vp.code = packet[pos]; pos += 1; vp.length = packet[pos]; pos += 1; vp.value = new byte[vp.length]; Array.Copy(packet, pos, vp.value, 0, vp.length); pos += vp.length; Varpart.Add(vp); } } catch (Exception) { throw new Exception("TPDU: Error parsing variable part of CR/CC PDU."); } }
// Handle connect request and build a connect confirm packet public TPDUConnection HandleConnectRequest(List <byte[]> LocalTsaps, int maxTPDUSize, bool enableTsapCheck) { ArrayList varpart = new ArrayList(); TPDUConnection ccpdu = new TPDUConnection(); Random random = new Random(); this.MaxTPDUSize = maxTPDUSize; ccpdu.DstRef = SrcRef; ccpdu.SrcRef = Convert.ToUInt16(random.Next(1, 32766)); ccpdu.ClassOption = 0; // Compare Destination TSAP int indDstTsap = Varpart.IndexOf((byte)VP.DST_TSAP); if (indDstTsap < 0) { throw new Exception("TPDU: Missing destination tsap in connect request."); } if (enableTsapCheck) { bool validTsapFound = false; foreach (byte[] tsap in LocalTsaps) { // Check length if (((VarParam)Varpart[indDstTsap]).length == tsap.Length) { for (int i = 0; i < tsap.Length; i++) { if (((VarParam)Varpart[indDstTsap]).value[i] == tsap[i]) { if (i == tsap.Length - 1) { validTsapFound = true; break; } } else { break; } } } if (validTsapFound) { break; } } if (validTsapFound == false) { throw new Exception("TPDU: Destination tsap mismatch."); } } int indSrcTsap = Varpart.IndexOf((byte)VP.SRC_TSAP); if (indSrcTsap < 0) { throw new Exception("TPDU: Missing source tsap in connect request."); } // Add parameters VarParam vp = new VarParam(); ccpdu.Varpart = new ArrayList(); vp.code = (byte)VP.SRC_TSAP; vp.length = ((VarParam)Varpart[indSrcTsap]).length; vp.value = new byte[vp.length]; Array.Copy(((VarParam)Varpart[indSrcTsap]).value, vp.value, vp.length); ccpdu.Varpart.Add(vp); vp.code = (byte)VP.DST_TSAP; vp.length = ((VarParam)Varpart[indDstTsap]).length; vp.value = new byte[vp.length]; Array.Copy(((VarParam)Varpart[indDstTsap]).value, vp.value, vp.length); ccpdu.Varpart.Add(vp); int indPduSize = Varpart.IndexOf((byte)VP.TPDU_SIZE); int TPDUSizeId = GetTPDUSizeIdFromOctetCount(MaxTPDUSize); if (indPduSize >= 0) { if (((VarParam)Varpart[indPduSize]).value[0] < TPDUSizeId) { TPDUSizeId = ((VarParam)Varpart[indPduSize]).value[0]; } } ccpdu.MaxTPDUSize = GetTPDUOctetCountFromSizeId(TPDUSizeId); vp.code = (byte)VP.TPDU_SIZE; vp.length = 1; vp.value = new byte[1]; vp.value[0] = Convert.ToByte(TPDUSizeId); ccpdu.Varpart.Add(vp); return(ccpdu); }