338 lines
12 KiB
C#
338 lines
12 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Text;
|
|||
|
using System.Net;
|
|||
|
using System.Net.Sockets;
|
|||
|
|
|||
|
using System.Threading;
|
|||
|
using SafeMobileLib;
|
|||
|
|
|||
|
namespace CPlus_GW
|
|||
|
{
|
|||
|
|
|||
|
class SendSMSThread
|
|||
|
{
|
|||
|
private byte WAIT_SMS_SEC = 5; // max no of seconds to wait for SMS ack
|
|||
|
int remoteSMSport;
|
|||
|
private UdpMulticast udpMulticastBusConnection = null;
|
|||
|
|
|||
|
public SendSMSThread(int p_remoteSMSport)
|
|||
|
{
|
|||
|
remoteSMSport = p_remoteSMSport;
|
|||
|
}
|
|||
|
|
|||
|
public void HandleConnection()
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
udpMulticastBusConnection = new UdpMulticast(Program.cfg.multi_IP, Program.cfg.multi_port);
|
|||
|
udpMulticastBusConnection.OnNewDataRecv += new UdpMulticast.newData4Send(udpMulticastBusConnection_OnNewDataRecv);
|
|||
|
udpMulticastBusConnection.StartListen();
|
|||
|
SafeMobileLib.Utils.WriteLine("SMSSendThread successfully registered to multicast group");
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
SafeMobileLib.Utils.WriteLine("SMSSendThread exception while joining the multicast group: " + ex.ToString(), ConsoleColor.Red);
|
|||
|
}
|
|||
|
while (true)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
//MotoTRBOcmdMsg msg = MotoTRBOGW.locationQueue.GetItem(100);
|
|||
|
SMSmsg msg = CPlusGW.sendSMSQueue.GetItem(-1);//block until message is in queue
|
|||
|
SendSMSmsg(msg);
|
|||
|
if (msg.req_conf)
|
|||
|
{
|
|||
|
SafeMobileLib.Utils.WriteLine("Requesting Receive Confirmation");
|
|||
|
lock (CPlusGW.waitConfSMSList.SyncRoot)
|
|||
|
{
|
|||
|
msg.seq_no = this.sms_seq_id - 1;//-1 because was alraedy incremented for next id
|
|||
|
CPlusGW.waitConfSMSList.Add(msg);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
Thread.Sleep(1200);//minimum interval between SMS as per MotoTRBO specs
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
SafeMobileLib.Utils.WriteLine("Exception in OC4JconnThread: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 (true)
|
|||
|
}
|
|||
|
|
|||
|
void udpMulticastBusConnection_OnNewDataRecv(byte[] data, int dataLen)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
string str = System.Text.Encoding.ASCII.GetString(data, 0, dataLen);
|
|||
|
String[] tempArray = str.Trim().Split('#');
|
|||
|
if (tempArray.Length > 3)
|
|||
|
if (tempArray[3].Equals("142") || tempArray[3].Equals("143"))
|
|||
|
{
|
|||
|
//Console.WriteLine("SMSSendThread received from multicast bus: " + str.Trim());
|
|||
|
int sched_timeGMT = 0;
|
|||
|
if (tempArray.Length > 6)
|
|||
|
sched_timeGMT = Convert.ToInt32(tempArray[6]);
|
|||
|
//Console.WriteLine("SMS sched time={0} and current time ={1}",sched_timeGMT, DBmanager.DateTo70Format(DateTime.Now.ToUniversalTime()));
|
|||
|
if (sched_timeGMT <= DateTime.Now.ToUniversalTime().DateTo70Format())
|
|||
|
{
|
|||
|
SMSmsg msg = new SMSmsg();
|
|||
|
msg.conf = true;
|
|||
|
msg.suid = tempArray[4];
|
|||
|
msg.msg = tempArray[5];
|
|||
|
//in this version DMmsg_id is replaced with seqID
|
|||
|
msg.DBmsg_id = tempArray[2];
|
|||
|
|
|||
|
//check to see if we already sent the message
|
|||
|
lock (CPlusGW.waitConfSMSList.SyncRoot)
|
|||
|
{
|
|||
|
int index = -1;
|
|||
|
int count = 0;
|
|||
|
foreach (SMSmsg msgTmp in CPlusGW.waitConfSMSList)
|
|||
|
{
|
|||
|
if (msg.DBmsg_id == msgTmp.DBmsg_id)
|
|||
|
{
|
|||
|
index = count;
|
|||
|
break;
|
|||
|
}
|
|||
|
count++;
|
|||
|
}
|
|||
|
if (index == -1)//we didn't found the message
|
|||
|
{
|
|||
|
SafeMobileLib.Utils.WriteLine("Message added to sendSMSQueue");
|
|||
|
CPlusGW.sendSMSQueue.PostItem(msg);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
else if (tempArray[3].Equals("154"))
|
|||
|
{
|
|||
|
string SUID = (tempArray[4].Split('.'))[2]; ;
|
|||
|
|
|||
|
String consoleMessage = String.Format($"Poll request received for unit {SUID}");
|
|||
|
SafeMobileLib.Utils.WriteLine("»»» " + consoleMessage, ConsoleColor.White);
|
|||
|
CPlusGW.TextQueue.PostItem(consoleMessage);
|
|||
|
|
|||
|
LocationThread.SendPollLocationRequest(SUID);
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
SM.Debug(ex.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//TODO: remove send SMS from arsthread or create a send SMS object ...
|
|||
|
public bool SendSMSmsg(SMSmsg p_msg)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
SendSMS_with_addrs("10000.4@tserv<mailto:" + p_msg.suid + ".1>", p_msg.msg, p_msg.conf);
|
|||
|
return true;
|
|||
|
}
|
|||
|
catch (Exception exc)
|
|||
|
{
|
|||
|
Console.WriteLine(exc.ToString());
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public void SendSMS_with_addrs(string address, string msg, bool conf)
|
|||
|
{
|
|||
|
SafeMobileLib.Utils.WriteLine("Sending SMS to:" + address + " msg:" + msg + $" on {Program.cfg.ctrlIP}:{Program.cfg.smsPort}", ConsoleColor.Yellow);
|
|||
|
try
|
|||
|
{
|
|||
|
Byte[] sendBytes = PackSMS_with_addrs(address, msg, conf);
|
|||
|
//Console.WriteLine("Send SMS to SU " + SUID + (conf ? " with confirmation" : " without confirmation") );
|
|||
|
CPlusGW.smsUDPclient.Send(sendBytes, sendBytes.Length, Program.cfg.ctrlIP, Program.cfg.smsPort);
|
|||
|
}
|
|||
|
catch (Exception exc)
|
|||
|
{
|
|||
|
Console.WriteLine(exc.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static void Send_Reg_msg(string address)
|
|||
|
{
|
|||
|
SafeMobileLib.Utils.WriteLine("Sending TMS Service Availability to: " + address + " [" + Program.cfg.ctrlIP + ":" + Program.cfg.smsPort + "]");
|
|||
|
try
|
|||
|
{
|
|||
|
|
|||
|
Byte[] sendBytes = Pack_TMS(address);
|
|||
|
//Console.WriteLine("Send SMS to SU " + SUID + " with confirmation");
|
|||
|
CPlusGW.smsUDPclient.Send(sendBytes, sendBytes.Length, Program.cfg.ctrlIP, Program.cfg.smsPort);
|
|||
|
|
|||
|
}
|
|||
|
catch (Exception exc)
|
|||
|
{
|
|||
|
Console.WriteLine(exc.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
byte[] PackSMS_with_addrs(string addrs, string msg_body, bool confirm)
|
|||
|
{
|
|||
|
int msg_len = msg_body.Length;
|
|||
|
int addrs_len = addrs.Length;
|
|||
|
|
|||
|
if (msg_len > MAX_SMS_SIZE)
|
|||
|
{
|
|||
|
msg_len = MAX_SMS_SIZE;
|
|||
|
SafeMobileLib.Utils.WriteLine("Warning: SMS truncated to " + msg_len + " characters");
|
|||
|
}
|
|||
|
|
|||
|
if (msg_len > msg_body.Length)
|
|||
|
{
|
|||
|
msg_body = msg_body.Remove(MAX_SMS_SIZE);
|
|||
|
}
|
|||
|
// compute the len
|
|||
|
int len = msg_len + addrs_len;
|
|||
|
|
|||
|
len *= 2; // each character is encoded on 2B
|
|||
|
len += 4; // this is for the headers
|
|||
|
Byte[] data = new Byte[len + 2]; //+2 for the msg size
|
|||
|
|
|||
|
int msb = (len & 0xff00) >> 8;
|
|||
|
data[0] = (byte)(msb & 0x00ff);
|
|||
|
data[1] = (byte)(len & 0x00ff);
|
|||
|
|
|||
|
// put the headers
|
|||
|
if (confirm)
|
|||
|
{
|
|||
|
data[2] = 0xe0; // first header
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
data[2] = 0xa0; // first header
|
|||
|
}
|
|||
|
|
|||
|
data[3] = (byte)(addrs_len * 2); // addr size
|
|||
|
for (int i = 0; i < addrs_len; i++)
|
|||
|
{
|
|||
|
data[4 + i * 2] = (byte)addrs[i];
|
|||
|
data[4 + i * 2 + 1] = 0;
|
|||
|
}
|
|||
|
|
|||
|
byte lsb_id = (byte)(sms_seq_id & 0x1f);
|
|||
|
data[4 + addrs_len * 2] = (byte)(0x80 | lsb_id);
|
|||
|
byte msb_id = (byte)(sms_seq_id & 0x60); // keep bits 6:5
|
|||
|
data[5 + addrs_len * 2] = (byte)(msb_id | 0x04);
|
|||
|
|
|||
|
for (int i = 0; i < msg_len; i++)
|
|||
|
{
|
|||
|
data[6 + i * 2 + addrs_len * 2] = (byte)msg_body[i];
|
|||
|
data[6 + i * 2 + 1 + addrs_len * 2] = 0;
|
|||
|
}
|
|||
|
sms_seq_id++;
|
|||
|
//Console.WriteLine("SMS packed: " + Utils.Byte2String(data, 0, data[1] + 2) + "\n\rSMS_SeQ_ID = " + sms_seq_id);
|
|||
|
return data;
|
|||
|
}
|
|||
|
|
|||
|
static byte[] Pack_TMS(string addrs)
|
|||
|
{
|
|||
|
int msg_len = 0;
|
|||
|
int addrs_len = addrs.Length;
|
|||
|
// compute the len
|
|||
|
int len = msg_len + addrs_len;
|
|||
|
|
|||
|
len *= 2; // each character is encoded on 2B
|
|||
|
len += 3; // this is for the headers
|
|||
|
Byte[] data = new Byte[len + 2]; //+2 for the msg size
|
|||
|
|
|||
|
int msb = (len & 0xff00) >> 8;
|
|||
|
data[0] = (byte)(msb & 0x00ff);
|
|||
|
data[1] = (byte)(len & 0x00ff);
|
|||
|
|
|||
|
// put the headers
|
|||
|
|
|||
|
data[2] = 0xD0; // first header
|
|||
|
|
|||
|
data[3] = (byte)(addrs_len * 2); // addr size
|
|||
|
for (int i = 0; i < addrs_len; i++)
|
|||
|
{
|
|||
|
data[4 + i * 2] = (byte)addrs[i];
|
|||
|
data[4 + i * 2 + 1] = 0;
|
|||
|
}
|
|||
|
//second header
|
|||
|
data[4 + addrs_len * 2] = 0x00;
|
|||
|
|
|||
|
//Console.WriteLine("SMS packed: " + Utils.Byte2String(data, 0, data[1] + 2) + "\n\rSMS_SeQ_ID = " + sms_seq_id);
|
|||
|
return data;
|
|||
|
}
|
|||
|
|
|||
|
int MAX_SMS_SIZE = 120;
|
|||
|
int MAX_ID_VAL = 100;
|
|||
|
int sms_seq_id = 1;
|
|||
|
Byte[] PackSMS(string msg_body, bool confirm)
|
|||
|
{
|
|||
|
/*
|
|||
|
Byte[] sendBytes = {
|
|||
|
0x00 , 0x0E , // len
|
|||
|
0xE0 , // header 1
|
|||
|
0x00 , // addr size
|
|||
|
0x88 , 0x04 , // header 2,3
|
|||
|
0x41 , 0x00 , 0x64 , 0x00 , 0x67, 0x00 , 0x6A , 0x00, 0x6D , 0x00 //data
|
|||
|
};
|
|||
|
*/
|
|||
|
|
|||
|
int msg_len = msg_body.Length;
|
|||
|
if (msg_len > MAX_SMS_SIZE)
|
|||
|
{
|
|||
|
msg_len = MAX_SMS_SIZE;
|
|||
|
SafeMobileLib.Utils.WriteLine("Warning: SMS truncked to " + msg_len);
|
|||
|
}
|
|||
|
if (sms_seq_id > MAX_ID_VAL)
|
|||
|
sms_seq_id = 1;
|
|||
|
|
|||
|
if (msg_len > msg_body.Length)
|
|||
|
{
|
|||
|
msg_body = msg_body.Remove(MAX_SMS_SIZE);
|
|||
|
}
|
|||
|
// compute the len
|
|||
|
int len = msg_len;
|
|||
|
|
|||
|
len *= 2; // each character is encoded on 2B
|
|||
|
len += 4; // this is for the headers
|
|||
|
Byte[] data = new Byte[len + 2]; //+2 for the msg size
|
|||
|
|
|||
|
int msb = (len & 0xff00) >> 8;
|
|||
|
data[0] = (byte)(msb & 0x00ff);
|
|||
|
data[1] = (byte)(len & 0x00ff);
|
|||
|
|
|||
|
// put the headers
|
|||
|
if (confirm)
|
|||
|
{
|
|||
|
data[2] = 0xe0; // first header
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
data[2] = 0xa0; // first header
|
|||
|
}
|
|||
|
|
|||
|
data[3] = 0x00; // addr size
|
|||
|
|
|||
|
byte lsb_id = (byte)(sms_seq_id & 0x1f);
|
|||
|
data[4] = (byte)(0x80 | lsb_id);
|
|||
|
byte msb_id = (byte)(sms_seq_id & 0x60); // keep bits 6:5
|
|||
|
data[5] = (byte)(msb_id | 0x04);
|
|||
|
|
|||
|
for (int i = 0; i < msg_len; i++)
|
|||
|
{
|
|||
|
data[6 + i * 2] = (byte)msg_body[i];
|
|||
|
data[6 + i * 2 + 1] = 0;
|
|||
|
}
|
|||
|
|
|||
|
sms_seq_id++;
|
|||
|
//Console.WriteLine("SMS packed: " + LocationThread.Byte2String(data, 0, data[1] + 2) + "\n\rSMS_SeQ_ID = " + sms_seq_id);
|
|||
|
return data;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|