/// <summary> /// Iterates through the hashtable, gathering the tag, length, and /// value as it goes. For each entry, it encodes the TLV into a byte /// array. It is assumed that the tags and length are already in network /// byte order. /// </summary> /// <returns>An ArrayList consisting of byte array entries, each of which /// is a TLV. Returns an empty ArrayList if the TLV table is empty.</returns> public ArrayList GenerateByteEncodedTlv() { if (tlvTable == null || tlvTable.Count <= 0) { return(new ArrayList(0)); } ArrayList tlvs = new ArrayList(); IDictionaryEnumerator iterator = tlvTable.GetEnumerator(); ArrayList elem = new ArrayList(); while (iterator.MoveNext()) { elem.Clear(); //tag-2 bytes elem.AddRange(BitConverter.GetBytes(((UInt16)iterator.Key))); //length-2 bytes byte[] nextVal = (byte[])iterator.Value; UInt16 tlvLength = UnsignedNumConverter.SwapByteOrdering(((UInt16)(nextVal).Length)); elem.AddRange(BitConverter.GetBytes(tlvLength)); //value elem.AddRange(nextVal); elem.TrimToSize(); //copy it over to a byte array tlvs.Add(elem.ToArray(typeof(byte))); } tlvs.TrimToSize(); return(tlvs); }
/// <summary> /// Gets the optional parameter bytes associated with the given tag. /// </summary> /// <param name="tag">The tag in TLV.</param> /// <returns>The optional parameter bytes, null if not found.</returns> /// <exception cref="ApplicationException">Thrown if the tag cannot be found.</exception> public byte[] GetOptionalParamBytes(UInt16 tag) { object val = tlvTable[tag]; if (val == null) { throw new ApplicationException("TLV tag " + tag + " not found."); } else { byte[] bVal = (byte[])val; #if DEBUG StringBuilder sb = new StringBuilder(); sb.Append("Getting tag " + UnsignedNumConverter.SwapByteOrdering(tag)); sb.Append("\nValue: "); for (int i = 0; i < bVal.Length; i++) { sb.Append(bVal[i]); sb.Append(" "); } Console.WriteLine(sb); #endif return(bVal); } }
/// <summary> /// Creates an Unsuccess address. This will trim down the address given to /// it for use in future operations. /// </summary> /// <param name="address">The bytes of the response.</param> public UnsuccessAddress(ref byte[] address) { DestinationAddressTon = (Pdu.TonType)address[0]; DestinationAddressNpi = (Pdu.NpiType)address[1]; DestinationAddress = SmppStringUtil.GetCStringFromBody(ref address, 2); //convert error status to host order ErrorStatusCode = UnsignedNumConverter.SwapByteOrdering( BitConverter.ToUInt32(address, 0)); //now we have to trim off four octets to account for the status code long length = address.Length - 4; byte[] newRemainder = new byte[length]; Array.Copy(address, 4, newRemainder, 0, length); //and change the reference address = newRemainder; newRemainder = null; }
/// <summary> /// Using the given tlvData byte array and the given starting index, inserts /// the tag and value(as a byte array)into the hashtable. Note that the /// tlvData needs to be in the SMPP v3.4 format(tag, length, value). This /// assumes that the tag and length (from the tlvData array) are in network byte order. /// /// Note also that this will advance the index by the TLV data length so that /// it may be used for consecutive reads from the same array. /// </summary> /// <param name="tlvData">The TLV data as a byte array.</param> /// <param name="index">The index of the array to start reading from.</param> private void InjectTlv(byte[] tlvData, ref Int32 index) { byte[] temp = new byte[2]; temp[0] = tlvData[index]; temp[1] = tlvData[index + 1]; #if DEBUG Console.WriteLine("tag bytes " + temp[0].ToString("X").PadLeft(2, '0') + temp[1].ToString("X").PadLeft(2, '0')); #endif UInt16 tag = BitConverter.ToUInt16(temp, 0); index += 2; temp[0] = tlvData[index]; temp[1] = tlvData[index + 1]; UInt16 length = UnsignedNumConverter.SwapByteOrdering(BitConverter.ToUInt16(temp, 0)); index += 2; //decode the value #if DEBUG Console.WriteLine("TLV Length " + length); #endif ArrayList data = new ArrayList(length); int total = index + length; for (int k = index; (k < index + length) && k < tlvData.Length; k++) { data.Add(tlvData[k]); } data.TrimToSize(); //add the values to the hashtable tlvTable.Add(tag, data.ToArray(typeof(byte))); //set it up for the next run index += length; }
/// <summary> /// Sets the given TLV(as a byte array)into the table. This ignores null values. /// </summary> /// <param name="tag">The tag in TLV.</param> /// <param name="val">The value of this TLV.</param> public void SetOptionalParamBytes(UInt16 tag, byte[] val) { #if DEBUG StringBuilder sb = new StringBuilder(); sb.Append("Setting tag " + UnsignedNumConverter.SwapByteOrdering(tag)); sb.Append("\nValue: "); for (int i = 0; i < val.Length; i++) { sb.Append(val[i]); sb.Append(" "); } Console.WriteLine(sb); #endif if (val != null) { if (val.Length > UInt16.MaxValue) { throw new Exception("Optional parameter value for " + tag + " is too large."); } tlvTable.Add(tag, val); } }