using LibrarySDR.Enums; using LibrarySDR.Flags; using System; using System.Collections; using System.Globalization; using System.Text; using static LibrarySDR.Helpers.BinaryHexHelper; namespace LibrarySDR.Requests { public class TextSDSRequest { private static int sendingReference = 0; public static int SendingReference { get { // rest counter to value 0 after max value inside a byte if (sendingReference > 255) sendingReference = 0; return sendingReference; } } private static PDUType PduType = PDUType.DATA_REQ_RESP; private static ProtocolIdentifier protocolIdentifier = ProtocolIdentifier.SimpleTextWithoutSDSTL; private Int64 sourceISSI; public Int64 SourceISSI { get { return sourceISSI; } } private Int64 destinationISSI; public Int64 DestinationISSI { get { return destinationISSI; } } private ProtocolIdentifier pi; public ProtocolIdentifier ProtocolIdentifier { get { return pi; } } private Int16 messageReference; public Int16 MessageRefence { get { return messageReference; } } private Int16 areaSelection; public Int16 AreaSelection { get { return areaSelection; } } private Int16 validityPeriod; public Int16 ValidityPeriod { get { return validityPeriod; } } private Int64 forwardAddress; public Int64 ForwardAddress { get { return forwardAddress; } } private Int16 flags; public Int16 Flags { get { return flags; } } private DataFlag dataFlag; public DataFlag DataFlags { get { return dataFlag; } } private Int16 lengthBits; public Int16 LengthBits { get { return lengthBits; } } private Int16 lengthBytes; public Int16 LengthBytes { get { return lengthBytes; } } private Int16 textEncoding; public Int16 TextEncoding { get { return textEncoding; } } private String message; public String Message { get { return message; } } private String hexMessage; public String HexMessage { get { return hexMessage; } } private static Int64 transactionId = 1; public static Int64 TransactionId { get { return transactionId++; } } public static Int32 EncodingType = 26; public TextSDSRequest(string hexSimpleTextSDSReceived) { String resp = hexSimpleTextSDSReceived; int i = 0; int prevIdx = 0; // get source SSI (32 bits = 4 byte = 8 hex characters) String hex = LittleToBigEndianHexString(resp.Substring(i = i + prevIdx, prevIdx = 4*2)); Int64.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out sourceISSI); // get destination SSI (32 bits = 4 byte = 8 hex characters) hex = LittleToBigEndianHexString(resp.Substring(i = i + prevIdx, prevIdx = 4*2)); Int64.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out destinationISSI); // get protocol identifier (8 bits = 1 byte = 2 hex characters) Int16 pi = 0; hex = LittleToBigEndianHexString(resp.Substring(i = i + prevIdx, prevIdx = 2)); Int16.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out pi); this.pi = (ProtocolIdentifier)pi; // get message reference (8 bits = 1 byte = 2 hex characters) hex = LittleToBigEndianHexString(resp.Substring(i = i + prevIdx, prevIdx = 2)); Int16.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out messageReference); // get area selection (8 bits = 1 byte = 2 hex characters) hex = LittleToBigEndianHexString(resp.Substring(i = i + prevIdx, prevIdx = 2)); Int16.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out areaSelection); // get validity period (8 bits = 1 byte = 2 hex characters) hex = LittleToBigEndianHexString(resp.Substring(i = i + prevIdx, prevIdx = 2)); Int16.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out validityPeriod); // get forward address (32 bits = 4 byte = 8 hex characters) hex = LittleToBigEndianHexString(resp.Substring(i = i + prevIdx, prevIdx = 4 * 2)); Int64.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out forwardAddress); // get flags (8 bits = 1 byte = 2 hex characters) hex = LittleToBigEndianHexString(resp.Substring(i = i + prevIdx, prevIdx = 2)); Int16.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out flags); // parse the data flag dataFlag = new DataFlag(flags); // get length bits (16 bits = 2 byte = 4 hex characters) hex = LittleToBigEndianHexString(resp.Substring(i = i + prevIdx, prevIdx = 4)); Int16.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out lengthBits); // get length bytes (16 bits = 2 byte = 4 hex characters) hex = LittleToBigEndianHexString(resp.Substring(i = i + prevIdx, prevIdx = 4)); Int16.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out lengthBytes); // get encoding (8 bits = 1 byte = 2 hex characters) hex = LittleToBigEndianHexString(resp.Substring(i = i + prevIdx, prevIdx = 2)); Int16.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out textEncoding); hexMessage = resp.Substring(i = i + prevIdx); // LittleToBigEndianHexString(resp.Substring(i = i + prevIdx)); for (int w = 0; w < hexMessage.Length /2; w++) message += (char)Convert.ToInt16(hexMessage.Substring(w * 2, 2), 16); ; } public static String GetInstance(Int64 sourceISSI, Int64 destinationISSI, String text, bool isConfirmationReq) { //text = "\u0006\u0006G\u0006D\u0006\u0006H\u00063\u0006G\u0006D\u0006"; //text = "\u70B9\u83DC"; StringBuilder sb = new StringBuilder(""); // PDU Type (8 bits) sb.Append(GetBits((int)PduType, 8)); // Source ISSI (32 bits) sb.Append(GetBits(sourceISSI, 32)); // Destination ISSI (32 bits) sb.Append(GetBits(destinationISSI, 32)); // Protocol Identifier (8 bits) sb.Append(GetBits(0x82, 8)); // Message reference (8 bits) - ignored for Simple Text) ++sendingReference; sb.Append(GetBits(SendingReference, 8)); // Area selection (8 bits) - unused sb.Append(GetBits(0x00, 8)); // Validity period (8 bits) - unused sb.Append(GetBits(0x00, 8)); // Forward Address (32 bits) - ignored for Simple Text sb.Append(GetBits(0x00, 32)); // Flags (8 bits) sb.Append(GetBits(isConfirmationReq ? 0x40 : 0x00, 8)); // Length in bites (16 bits) + the encoding one sb.Append(GetBits((text.Length * 2 + 1) * 8 , 16)); // Length in bytes (16 bits) + the encoding one sb.Append(GetBits(text.Length * 2 + 1, 16)); // Encoding (8 bits) - Latin-1 sb.Append(GetBits(EncodingType, 8)); // Text message if (EncodingType == 1) sb.Append(GetBits(text, Encoding.Unicode)); else { /* byte[] bytesUtf16 = Encoding.Unicode.GetBytes(text); String btit = ToBitString(new BitArray(bytesUtf16)); sb.Append(btit);*/ for (int i = 0; i < text.Length; i++) { int unicode = text[i]; string convertedUtf16 = GetEscapeSequence(text[i]); BitArray b3 = new BitArray(StringToByteArrayFastest(convertedUtf16.Substring(2, 2))); //BitArray b2 = new BitArray(StringToByteArrayFastest(convertedUtf16.Substring(2, 1))); //BitArray b1 = new BitArray(StringToByteArrayFastest(convertedUtf16.Substring(1, 1))); BitArray b0 = new BitArray(StringToByteArrayFastest(convertedUtf16.Substring(0, 2))); String btit = ToBitString(new BitArray(b0), Endian.BIG); sb.Append(btit.Substring(4, 4)); sb.Append(btit.Substring(0, 4)); //btit = ToBitString(new BitArray(b2)); //sb.Append(btit); //btit = ToBitString(new BitArray(b1)); //sb.Append(btit); btit = ToBitString(new BitArray(b3), Endian.BIG); sb.Append(btit.Substring(4, 4)); sb.Append(btit.Substring(0, 4)); /* byte[] bytesUtf16 = Encoding.Unicode.GetBytes(convertedUtf16); String btit = ToBitString(new BitArray(bytesUtf16)); sb.Append(btit); byte[] bytesUtf16 = Encoding.Unicode.GetBytes(convertedUtf16.Substring(2, 2)); String btit = ToBitString(new BitArray(bytesUtf16)); sb.Append(btit); bytesUtf16 = Encoding.Unicode.GetBytes(convertedUtf16.Substring(0,2)); btit = ToBitString(new BitArray(bytesUtf16)); sb.Append(btit); */ /* for (int w = 0; w < convertedUtf16.Length; w++) { Int16 unicodeVal = Int16.Parse(convertedUtf16[w] + "", NumberStyles.HexNumber); //string convertedUtf16 = Encoding.Unicode.GetString(text[i]); sb.Append(GetBits(unicodeVal, 8)); }*/ } } /* // Transaction Id sb.Append(GetBits(TransactionId, 32)); // Gw Report sb.Append(GetBits(0x01, 8));*/ // get the header with the length String header = Header.GetHeaderBinary(sb.ToString().Length / 8); // add header in front of the request return BinaryStringToHexString($"{header}{sb.ToString()}", Padding.RIGHT); } public static byte[] GetBytes(Int64 sourceISSI, Int64 destinationISSI, String text, bool isConfirmationReq) { String res = GetInstance(sourceISSI, destinationISSI, text, isConfirmationReq); byte[] response = new byte[res.Length / 2]; for (int i = 0; i < res.Length / 2; i++) response[i] = (byte)Convert.ToInt16(res.Substring(i * 2, 2), 16); return response; } } }