285 lines
11 KiB
C#
285 lines
11 KiB
C#
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|