304 lines
13 KiB
C#
304 lines
13 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Text;
|
||
using System.Net;
|
||
using System.Net.Sockets;
|
||
using System.Threading;
|
||
using System.Collections;
|
||
using SafeMobileLib;
|
||
|
||
/*
|
||
< rsp sid="SID" id="100111" mode="MOD" HW_Type="Hw_type"
|
||
subscriber="Phone_nr" RFID="RFID" time="TIME"
|
||
Latitude="" Longitude="" Speed="" ai1="" ai2="" ai3="" ai4=""
|
||
ai5="" ai6="" ai7="" ai8="" di="" ao1="" ao2="" do=""> </rsp>
|
||
*/
|
||
|
||
namespace CPlus_GW
|
||
{
|
||
|
||
class ReceiveSMSThread
|
||
{
|
||
public UInt16 port;
|
||
//public MotoTRBOGW parent;
|
||
string gwID;
|
||
private UdpMulticast udpMulticast;
|
||
|
||
public ReceiveSMSThread(ushort p_port, string p_gwID)
|
||
{
|
||
port = p_port;
|
||
gwID = p_gwID;
|
||
|
||
udpMulticast = new UdpMulticast(Program.cfg.multi_IP, Program.cfg.multi_port);
|
||
CPlusGW.TextQueue.PostItem($"Receive SMS Thread started ");
|
||
}
|
||
|
||
// -------------------------------------------------------------------
|
||
// Main
|
||
// -------------------------------------------------------------------
|
||
public void HandleConnection()
|
||
{
|
||
while (true)
|
||
{
|
||
try
|
||
{
|
||
//IPEndPoint object will allow us to read datagrams sent from any source.
|
||
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
|
||
SafeMobileLib.Utils.WriteLine("Starting SMS Receiving Thread on port " + port, ConsoleColor.Cyan);
|
||
// Blocks until a message returns on this socket from a remote host.
|
||
Byte[] receiveBytes = CPlusGW.smsUDPclient.Receive(ref RemoteIpEndPoint);
|
||
string returnData = Encoding.ASCII.GetString(receiveBytes);
|
||
|
||
// Uses the IPEndPoint object to determine which of these two hosts responded.
|
||
SafeMobileLib.Utils.WriteLine("\n--------------------");
|
||
SafeMobileLib.Utils.WriteLine($"SMS Received {receiveBytes.Length} bytes from {RemoteIpEndPoint.Address.ToString()}:{RemoteIpEndPoint.Port.ToString()}");
|
||
/*
|
||
SafeMobileLib.Utils.WriteLine("SMSThRecv(" + port + "): " + LocationThread.Byte2String(receiveBytes, 0, receiveBytes[1] + 2));
|
||
SafeMobileLib.Utils.WriteLine("From " + RemoteIpEndPoint.Address.ToString() +
|
||
":" + RemoteIpEndPoint.Port.ToString());
|
||
*/
|
||
header_T hret = DecodePacket(receiveBytes, RemoteIpEndPoint);
|
||
|
||
|
||
//we got ACK for message add it to DB
|
||
if ((hret.header == 0xBF) || (hret.header == 0x9F))
|
||
{
|
||
SafeMobileLib.Utils.WriteLine("Got ACK with header:" + hret.header + " with seq_id :" + hret.seq_no, ConsoleColor.Green);
|
||
lock (CPlusGW.waitConfSMSList.SyncRoot)
|
||
{
|
||
int index = -1;
|
||
int count = 0;
|
||
foreach (SMSmsg msg in CPlusGW.waitConfSMSList)
|
||
{
|
||
if (msg.seq_no == hret.seq_no)
|
||
{
|
||
index = count;
|
||
CPlusGW.confSMSQueue.PostItem(msg);
|
||
|
||
string test = "#242#1#";
|
||
String cmdok = "#" + msg.DBmsg_id + test;
|
||
Int32 tmp = cmdok.Length + 1;
|
||
tmp += tmp.ToString().Length;
|
||
cmdok = "#" + tmp.ToString() + cmdok;
|
||
System.Text.Encoding enc = System.Text.Encoding.ASCII;
|
||
byte[] buf = enc.GetBytes(cmdok);
|
||
//send SMS ack to message bus
|
||
udpMulticast.Send(buf, buf.Length);
|
||
}
|
||
count++;
|
||
}
|
||
if (index > -1)//we've found the message
|
||
CPlusGW.waitConfSMSList.RemoveAt(index);
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
SafeMobileLib.Utils.WriteLine("Exception in SMSThread:HandleConnection(): \r\n\tData=" +
|
||
ex.Data + "\r\n\tSource=" +
|
||
ex.Source + "\r\n\tStackTrace=" +
|
||
ex.StackTrace + "\r\n\tMessage=" +
|
||
ex.Message + "\r\n\tInnerException=" +
|
||
ex.InnerException, ConsoleColor.Red);
|
||
}
|
||
|
||
} // end while
|
||
}
|
||
|
||
// -------------------------------------------------------------------
|
||
// Aux functions
|
||
// -------------------------------------------------------------------
|
||
|
||
struct header_T
|
||
{
|
||
public string address;
|
||
public bool ext, ext2, ack, cntl;
|
||
public byte pdu_type;
|
||
public byte seq_no;
|
||
public byte encoding;
|
||
public byte header;
|
||
}
|
||
|
||
header_T DecodePacket(Byte[] data, IPEndPoint RemoteIpEndPoint)
|
||
{
|
||
header_T hret = new header_T();
|
||
int i, j, pdata;
|
||
//Console.WriteLine("--------------------");
|
||
|
||
pdata = (int)data[0];
|
||
pdata <<= 8;
|
||
pdata |= (int)data[1];
|
||
|
||
// parse header
|
||
int header = data[2];
|
||
hret.header = data[2];
|
||
//Console.WriteLine("Header: " + header.ToString("X"));
|
||
if ((header & 0x80) != 0)
|
||
hret.ext = true;
|
||
else hret.ext = false;
|
||
|
||
if ((header & 0x40) != 0)
|
||
{
|
||
hret.ack = true;
|
||
}
|
||
else hret.ack = false;
|
||
|
||
if ((header & 0x10) != 0)
|
||
hret.cntl = true;
|
||
else hret.cntl = false; // txt message
|
||
|
||
hret.pdu_type = (byte)(header & 0x0f);
|
||
|
||
// parse address
|
||
int addrsize = data[3];
|
||
i = 4;
|
||
//remove second byte of encoding( ex: "1" is ecncoded 0x31 0x00)
|
||
string adrs = "";
|
||
for (int ind = i; ind < addrsize + 2; ind += 2)
|
||
{
|
||
adrs += Encoding.UTF8.GetString(new byte[] { data[ind] });
|
||
}
|
||
hret.address = adrs;
|
||
|
||
//SafeMobileLib.Utils.WriteLine("Address: " + adrs);
|
||
for (j = 0; j < addrsize; j++)
|
||
{
|
||
//Console.Write(data[i + j].ToString("X"));
|
||
}
|
||
i += j;
|
||
string suid = hret.address.Split('.')[0];
|
||
|
||
// parse rest of headers
|
||
if (hret.ext)
|
||
{
|
||
byte h2 = data[i];
|
||
if ((h2 & 0x80) != 0)
|
||
hret.ext2 = true;
|
||
else hret.ext2 = false;
|
||
|
||
hret.seq_no = (byte)(h2 & 0x1F);
|
||
i++;
|
||
|
||
if (hret.ext2)
|
||
{ // parse third header
|
||
byte seqNr_MSB = (byte)(data[i] & 0x60);
|
||
hret.seq_no += seqNr_MSB;
|
||
hret.encoding = (byte)(data[i] & 0x0f);
|
||
i++;
|
||
}
|
||
}
|
||
|
||
if (hret.ack)
|
||
{
|
||
Thread.Sleep(500);
|
||
// The client needs an ACK
|
||
//string addrs = "10000.4@tserv<mailto:" + suid + ".1>";
|
||
string addrs = "10000.4<mailto:" + suid + ".1>";
|
||
int addrs_len = addrs.Length;
|
||
// The client needs an ACK
|
||
byte extension_header = 0;
|
||
if (hret.seq_no > 0x1F)
|
||
extension_header = 1;
|
||
Byte[] sendBytes = new Byte[5 + addrs_len * 2 + extension_header];
|
||
sendBytes[0] = 0x00; // len (2B)
|
||
sendBytes[1] = (byte)(3 + addrs_len * 2 + extension_header);
|
||
sendBytes[2] = 0xBF; // first header (req)
|
||
|
||
sendBytes[3] = (byte)(addrs_len * 2); // addr size
|
||
for (int indx = 0; indx < addrs_len; indx++)
|
||
{
|
||
sendBytes[4 + indx * 2] = (byte)addrs[indx];
|
||
sendBytes[4 + indx * 2 + 1] = 0;
|
||
}
|
||
|
||
sendBytes[4 + addrs_len * 2] = (byte)(hret.seq_no & 0x1F); // 2nd header (opt)
|
||
if (extension_header == 1)
|
||
{
|
||
sendBytes[4 + addrs_len * 2] += 0x80; //added the extension header info
|
||
sendBytes[4 + addrs_len * 2 + 1] = (byte)(hret.seq_no & 0x60);
|
||
}
|
||
SafeMobileLib.Utils.WriteLine("<22><><EFBFBD> SMSReceiveThread ACK sent address: " + addrs + "seq_id: " + hret.seq_no, ConsoleColor.White);
|
||
|
||
//MotoTRBOGW.smsUDPclient.Send(sendBytes, sendBytes[1] + 2, new IPEndPoint(IPAddress.Parse(MotoTRBOGW.cfg.ctrlIP), Convert.ToInt32(MotoTRBOGW.cfg.smsPort)));
|
||
|
||
UdpClient uc = new UdpClient();
|
||
uc.Send(sendBytes, sendBytes[1] + 2, new IPEndPoint(IPAddress.Parse(Program.cfg.ctrlIP), Convert.ToInt32(Program.cfg.smsPort)));
|
||
CPlusGW.smsUDPclient.Send(sendBytes, sendBytes[1] + 2, RemoteIpEndPoint);
|
||
SafeMobileLib.Utils.WriteLine($"<22><><EFBFBD> SMS ACK sent to {Program.cfg.ctrlIP}:{Program.cfg.smsPort}", ConsoleColor.White);
|
||
}
|
||
|
||
int crc = 0;
|
||
if ((! hret.cntl) && (hret.pdu_type==0))
|
||
{ // the rest is the txt message
|
||
//Console.Write("SMS Message: ");
|
||
Char[] cs = new Char[100];
|
||
int k;
|
||
for (j = i, k = 0; j < pdata + 2; j++)
|
||
{
|
||
//Console.Write(" 0x" + data[j].ToString("X"));
|
||
if (data[j] != 0)
|
||
{
|
||
cs[k++] = (Char)data[j];
|
||
crc |= (Char)data[j];
|
||
}
|
||
}
|
||
//Console.WriteLine();
|
||
|
||
// save message in inbox ht
|
||
string s = new string(cs, 0, k);
|
||
s.Replace("\r\n", "");
|
||
s = s.Replace(System.Environment.NewLine, string.Empty);
|
||
|
||
SafeMobileLib.Utils.WriteLine("Message [" + s + "]" + " from unit " + suid, ConsoleColor.Green);
|
||
|
||
if (s.StartsWith("Rfid"))
|
||
{
|
||
string rfid_string = new string(cs, 4, s.Length - 4);
|
||
Console.WriteLine("RFID detected:" + rfid_string);
|
||
OC4Jrfid rfid = new OC4Jrfid();
|
||
rfid.suid = suid;
|
||
rfid.rfid = rfid_string;
|
||
//MotoTRBOGW.DBQueueRFID.PostItem(rfid);
|
||
}
|
||
else
|
||
{
|
||
CPlusGW.TextQueue.PostItem("SMS received from unit:" + suid );
|
||
//send SMS
|
||
string seqID = "1." + GetSecondsLocalFromDT(DateTime.Now).ToString() + DateTime.Now.Millisecond.ToString();
|
||
string test = "#132#" + suid + "#" + s + "#hyt#";
|
||
String cmdok = "#" + seqID + test; Int32 tmp = cmdok.Length + 1; tmp += tmp.ToString().Length; cmdok = "#" + tmp.ToString() + cmdok;
|
||
System.Text.Encoding enc = System.Text.Encoding.ASCII;
|
||
byte[] buf = enc.GetBytes(cmdok);
|
||
//send to messagebus
|
||
udpMulticast.Send(buf, buf.Length);
|
||
}
|
||
}
|
||
//Console.WriteLine("i=" + i);
|
||
SafeMobileLib.Utils.WriteLine("--------------------");
|
||
|
||
return hret;
|
||
}
|
||
|
||
public static Int32 GetSecondsLocalFromDT(DateTime param)
|
||
{
|
||
System.DateTime datetime = param;
|
||
long nOfSeconds;
|
||
System.DateTime dt70 = new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||
System.DateTime dttmp1 = new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||
System.DateTime dttmp2;
|
||
dttmp2 = dttmp1.ToLocalTime();
|
||
TimeSpan span2 = dttmp2 - dttmp1;
|
||
TimeSpan span = datetime - dt70;
|
||
//nOfSeconds = (long)span.TotalSeconds - (long)span2.TotalSeconds -3600; //mai scot o ora - 3600
|
||
if (System.TimeZone.CurrentTimeZone.IsDaylightSavingTime(param)) nOfSeconds = (long)span.TotalSeconds - (long)span2.TotalSeconds - 3600; //mai scot o ora - 3600
|
||
else nOfSeconds = (long)span.TotalSeconds - (long)span2.TotalSeconds;
|
||
return ((Int32)nOfSeconds);
|
||
}
|
||
|
||
|
||
}
|
||
} |