SafeDispatch/Tetra_GW/MainForm.cs
2024-02-22 18:43:59 +02:00

2075 lines
82 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls.UI;
using Telerik.WinControls;
using System.IO.Ports;
using System.Threading;
using System.Collections;
using System.Diagnostics;
using SafeMobileLib;
using Nini.Config;
using System.Threading.Tasks;
using SharedUI;
using System.IO;
namespace Tetra_GW
{
public partial class MainForm : RadForm
{
private volatile String[] ports;
private Hashtable htSU = new Hashtable();
private UdpMulticast udpMulticast;
public Params configParams;
private String lastLat = "", lastLng = "", SUID ="";
private Hashtable portHT = new Hashtable();
private volatile bool _shouldStop = false;
private volatile bool _isConnected = false;
private volatile int counter = 0;
//private bool startKeepAliveThread = false;
private volatile bool keepAlive = false;
private volatile bool needToRegister = false;
private volatile int intRegister = 0;
IConfigSource source;
string radioMesageError = "Fail to communicate with radio";
public MainForm()
{
InitializeComponent();
btConect.Enabled = false;
lbUpdateVAL.Text = "Not available";
lbUpdateVAL.ForeColor = Color.Blue;
configParams = Utils.readConfig();
FindPortsWorker.RunWorkerAsync();
ThemeResolutionService.ApplicationThemeName = "TelerikMetroBlue";
Version v = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
this.Text+= " " + v.ToString();
if (!File.Exists(Utils.configFile))
{
SafeMobileLib.Utils.WriteLine("Config file didn't exist. Creating it...", ConsoleColor.Yellow);
try
{
using (FileStream fs = File.Create(Utils.configFile)) { }
}
catch (Exception)
{
SafeMobileLib.Utils.WriteLine("Application ended!!!! " + Utils.configFile + " could not be created");
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
System.Environment.Exit(0);
}
}
source = new IniConfigSource(Utils.configFile);
//INIT UDP
try
{
udpMulticast = new UdpMulticast(configParams.multParams.mIP, configParams.multParams.mPort);
SafeMobileLib.Utils.WriteLine("Starting udp multicast on ip : " + Utils.localIP, ConsoleColor.Cyan);
udpMulticast.OnNewDataRecv += udpMulticast_OnNewDataRecv;
udpMulticast.StartListen(Utils.localIP);
}
catch (Exception ex)
{
SafeMobileLib.Utils.WriteLine("Location Thread exception while joining the multicast group: " + ex.ToString(), ConsoleColor.Red);
}
}
void udpMulticast_OnNewDataRecv(byte[] data, int dataLen)
{
try
{
string str = System.Text.Encoding.ASCII.GetString(data, 0, dataLen);
String[] tempArray = str.Trim().Split('#');
int gwid_recv = 0;
int radio_gwid_recv = 0;
//SafeMobileLib.Utils.WriteLine("udpMulticast_OnNewDataRecv: " + str, ConsoleColor.Yellow);
if (tempArray.Length > 3)
{
switch (tempArray[3])
{
case "142":
case "143":
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 (tempArray[4].Split('.'))[0]
//configParams.gateParams.ID.ToString()
gwid_recv = Convert.ToInt32((tempArray[4].Split('.'))[0]);
radio_gwid_recv = Convert.ToInt32((tempArray[4].Split('.'))[1]);
//SafeMobileLib.Utils.WriteLine("GW|RGW " + gwid_recv + ":" + radio_gwid_recv + " | "
// + configParams.gateParams.ID + ":" + configParams.gateParams.RADIO_GW_ID, ConsoleColor.Green);
if (gwid_recv == configParams.gateParams.ID && radio_gwid_recv == configParams.gateParams.RADIO_GW_ID)//|| gwid_recv == 0)
{
if (sched_timeGMT <= DateTime.Now.ToUniversalTime().DateTo70Format() + 60)
{
//sms_seq_id = SMSConfirm.addToConfirmationQueue(tempArray[2]);
// Console.WriteLine("SMSSendThread received from multicast bus: " + str.Trim());
/*if (sms_seq_id != -1)
{
SendSMS(tempArray[4], tempArray[5], 1);
SendSMSToRadio(tempArray[4], tempArray[5]);
}
else
{*/
//SendSMS(tempArray[4], tempArray[5], -1);
SendSMSToRadio((tempArray[4].Split('.'))[2], tempArray[5]);
string test = "#242#1#";
String cmdok = "#" + tempArray[2] + 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 sd new channel value
udpMulticast.Send(buf, buf.Length);
//}
}
}
break;
case "154":
gwid_recv = Convert.ToInt32((tempArray[4].Split('.'))[0]);
radio_gwid_recv = Convert.ToInt32((tempArray[4].Split('.'))[1]);
//SafeMobileLib.Utils.WriteLine("GW|RGW " + gwid_recv + ":" + radio_gwid_recv + " | "
// + configParams.gateParams.ID + ":" + configParams.gateParams.RADIO_GW_ID, ConsoleColor.Green);
if (gwid_recv == configParams.gateParams.ID && radio_gwid_recv == configParams.gateParams.RADIO_GW_ID) //|| gwid_recv == 0)
{
//Console.WriteLine("LocationThread received from multicast bus: " + str.Trim());
SUID = (tempArray[4].Split('.'))[2];
SendPOLL((tempArray[4].Split('.'))[2]);
}
break;
}
}
}
catch (Exception ex)
{
SafeMobileLib.Utils.WriteLine(ex.ToString(),ConsoleColor.Red);
}
}
static byte sms_seq_id = 1;
public void SendSMSToRadio(String SUID, String messageBody)
{
//SafeMobileLib.Utils.WriteLine("++++++++++Send SMS to SU " + SUID);
// send sms
try
{
serialPort.ReadExisting();
string line = "AT+CMGS=" + SUID + ",1,0," + (messageBody.Length + 4) * 8;
//Console.WriteLine("line = " + line);
serialPort.Write(line);
System.Threading.Thread.Sleep(500);
//SafeMobileLib.Utils.WriteLine("#### 1 #####");
//SafeMobileLib.Utils.WriteLine(line);
byte[] buf = { 13, (byte)'8', (byte)'2',
(byte)'0', (byte)'4',
(byte)'0', (byte)'1',
(byte)'0', (byte)'1'};
buf[6] = (byte)(sms_seq_id + (byte)'0');
sms_seq_id++;
if (sms_seq_id > 9)
sms_seq_id = 1;
// SafeMobileLib.Utils.WriteLine("#### 2 #####");
serialPort.ReadExisting();
serialPort.Write(buf, 0, 9); // <cr> 82 04 01 01
System.Threading.Thread.Sleep(500);
line = "";
for (int i = 0; i < messageBody.Length; i++)
line += Byte2Str(messageBody[i]);
//SafeMobileLib.Utils.WriteLine("SMS body = " + line);
serialPort.Write(line);
buf[0] = 26;
//SafeMobileLib.Utils.WriteLine("#### 3 #####");
serialPort.ReadExisting();
serialPort.WriteTimeout = 2000;
serialPort.Write(buf, 0, 1); // <ctrl+z>
SafeMobileLib.Utils.WriteLine("»»» SMS [" + messageBody + "] sent to to " + SUID + " [msg id " + sms_seq_id + "]");
}
catch (Exception ex)
{
SafeMobileLib.Utils.WriteLine("SendSMSToRadio Exception:" + ex.ToString(), ConsoleColor.Red);
}
}
public void SendPOLL(String SUID)
{
//SafeMobileLib.Utils.WriteLine("++++++++++Send SMS to SU " + SUID);
// send sms
try
{
serialPort.ReadExisting();
string line = "XZG" + SUID + "R" + "\r\n";
SafeMobileLib.Utils.WriteLine("»»» POLL location request for " + SUID);
//SafeMobileLib.Utils.WriteLine("send line to station = " + line);
serialPort.WriteTimeout = 30000;
serialPort.Write(line);
System.Threading.Thread.Sleep(500);
}
catch (Exception ex)
{
SafeMobileLib.Utils.WriteLine("SendSMSToRadio Exception:" + ex.ToString(), ConsoleColor.Red);
}
}
public void SendPollRequest(Int32 sourceISSI, Int32 destinationISSI)
{
/*
const int OCID_L_V1_IMM_LOC_REQ = 0x05;
// see MR5.11_LIP_tehnical_guide page 18-22
List<byte> responseList = new List<byte>();
// add SDTS-CM-DATA
responseList.Add(0x00);
// source issi
string issi_s = Convert.ToString(sourceISSI, 16);
int issilength_s = 0;
int i_s = 0;
issilength_s = 6 - issi_s.Length;
for (i_s = 1; i_s <= issilength_s; i_s++)
{
issi_s = "0" + issi_s;
}
responseList.Add(Convert.ToByte(issi_s.ToString().Substring(0, 2), 16));
responseList.Add(Convert.ToByte(issi_s.ToString().Substring(2, 2), 16));
responseList.Add(Convert.ToByte(issi_s.ToString().Substring(4, 2), 16));
// destination issi
string issi_d = Convert.ToString(destinationISSI, 16);
int issilength_d = 0;
int i_d = 0;
issilength_d = 6 - issi_d.Length;
for (i_d = 1; i_d <= issilength_d; i_d++)
{
issi_d = "0" + issi_d;
}
responseList.Add(Convert.ToByte(issi_d.ToString().Substring(0, 2), 16));
responseList.Add(Convert.ToByte(issi_d.ToString().Substring(2, 2), 16));
responseList.Add(Convert.ToByte(issi_d.ToString().Substring(4, 2), 16));
// add Protocol Identifier
int iPI = 190
List<byte> request = new List<byte>();
int iGps = 0;
byte[] TxBuf = new byte[100];
TxBuf[2] = 0x00; // SDTS-CM-DATA
Issi2chars(&TxMess.TxBuf[3], m_MyISSI);
Issi2chars(&TxMess.TxBuf[6], m_Dest);
TxMess.TxBuf[9]= (unsigned char)iPI;
TxMess.TxBuf[10]= 0x60; //SDS, SS, Reserved
i_MRef++;
TxMess.TxBuf[11]= i_MRef;
TxMess.TxBuf[12]= 0x00; // Area selection predefined to 0x00
if (iPI == 131) //TL support
{
// TL Length
TxMess.TxBuf[13]= (8*(8+3+6))/256; // TL length in bits
TxMess.TxBuf[14]= (8*(8+3+6))%256; // gpsData + gps header+tl header
TxMess.TxBuf[15]= TL_MSG_TYPE_TL_TRANSFER;
TxMess.TxBuf[16]= 0x40; // Consumed request,REC, CON, STO, - to be supported ?
TxMess.TxBuf[17]= 0x00; // Validity period predefined
TxMess.TxBuf[18]= 0x00; // forward Address
TxMess.TxBuf[19]= 0x00;
TxMess.TxBuf[20]= 0x00;
iGps = 20;
}
else
{
TxMess.TxBuf[13]= 0; // TL length not used
TxMess.TxBuf[14]= 0;
TxMess.TxBuf[15]= TL_MSG_TYPE_UNITDATA;
iGps = 15;
}
// GPS Immediate Location Request refer LRRP Protocol Specification
// see syntax in 5.3.1 and 7.2.1
// see query-info Overview in 5.16 and 7.1.1, 7.1.2
TxMess.TxBuf[++iGps] = 0x80; // application
TxMess.TxBuf[++iGps] = DOCID_L_V1_IMM_LOC_REQ;
TxMess.TxBuf[++iGps] = 0x08; // no of octets
TxMess.TxBuf[++iGps] = TKNICE_REQID_OI;
TxMess.TxBuf[++iGps] = 0x04; // req id size
TxMess.TxBuf[++iGps] = 'A';
TxMess.TxBuf[++iGps] = 'n';
TxMess.TxBuf[++iGps] = 'n';
TxMess.TxBuf[++iGps] = 'e';
TxMess.TxBuf[++iGps] = TKNLQ_RETINFO_TM_END; // query-info start
TxMess.TxBuf[++iGps] = TKNLQ_REQUEST_ALT;
TxMess.msg_len = iGps-1;
// TCP layer length
TxMess.TxBuf[0] = (TxMess.msg_len)/0x100;
TxMess.TxBuf[1] = (TxMess.msg_len)%0x100;
TRACE("length: %i\n", TxMess.msg_len);
*/
}
static string Byte2Str(char c)
{
char[] Byte2Char = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
byte b = (byte)c;
byte hb = b;
hb >>= 4;
hb &= 0x0f;
char hc = Byte2Char[hb];
byte lb = b;
lb &= 0x0f;
char lc = Byte2Char[lb];
string ret = hc.ToString() + lc.ToString();
return ret;
}
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.Visible = true;
this.WindowState = FormWindowState.Normal;
notifyIcon1.Visible = false;
}
private void MainForm_Resize(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
{
this.Visible = false;
notifyIcon1.Visible = true;
}
}
private void FindPortsWorker_DoWork(object sender, DoWorkEventArgs e)
{
Utils.getAvailableSerialPorts(ref portHT);
ports = Utils.getOpenPorts();
}
private void FindPortsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
RadListDataItem[] radCBItems = new RadListDataItem[ports.Length];
for (int i = 0; i < ports.Length; i++)
{
String portName = ports[i];
RadListDataItem item = new RadListDataItem();
// item.Name = portName;
item.Text = portName;
radCBItems[i] = item;
}
if (SerialPort.GetPortNames().Length > 0)
{
radCBPorts.Items.AddRange(radCBItems);
int s = 0;
foreach (RadListDataItem li in radCBPorts.Items)
{
if (portHT.Contains(li.Text))
radCBPorts.SelectedIndex = s;
s++;
}
if (configParams.gateParams.COMPort != null)
{
if (portHT.Contains(configParams.gateParams.COMPort))
{
radCBPorts.Text = configParams.gateParams.COMPort;
}
}
btConect.Enabled = true;
}
else
lbStatusVAL.Text = "No COM port found";
if (configParams.gateParams.COMPort != null)
{
if (portHT.Contains(configParams.gateParams.COMPort))
{
ckAutoconnect.Checked = configParams.gateParams.autoconnect;
if (configParams.gateParams.autoconnect)
btConect.PerformClick();
}
else
{
SafeMobileLib.Utils.WriteLine(String.Format("Port: {0} not available", configParams.gateParams.COMPort));
}
}
}
private async Task<bool> RadioConnectAsync()
{
return await Task.Factory.StartNew<bool>(conn);
}
private bool conn()
{
bool ret = false;
if (!serialPort.IsOpen)
{
try
{
_shouldStop = false;
timer1.Stop();
timer1.Enabled = false;
serialPort.BaudRate = 9600;
//serialPort.BaudRate = 115200;
//serialPort.BaudRate = 38400;
serialPort.PortName = radCBPorts.Text;
SafeMobileLib.Utils.WriteLine("PortName: " + serialPort.PortName);
serialPort.Open();
serialPort.ReadTimeout = 200;
serialPort.WriteTimeout = 1;
serialPort.DataBits = 8;
if (Utils.isTetra) serialPort.Handshake = System.IO.Ports.Handshake.RequestToSend;
else serialPort.Handshake = System.IO.Ports.Handshake.XOnXOff;
serialPort.Parity = System.IO.Ports.Parity.None;
serialPort.StopBits = System.IO.Ports.StopBits.One;
SafeMobileLib.Utils.WriteLine("Serial port connection open.");
this.Invoke((MethodInvoker)delegate
{
lbStatusVAL.Text = "Serial port opened";
lbStatusVAL.ForeColor = Color.Blue;
btConect.Text = "Disconnect";
radCBPorts.Enabled = false;
//this.ControlBox = false;
});
//System.Threading.Timer forcetimer = new System.Threading.Timer(ForceTimer, null, 15000, System.Threading.Timeout.Infinite);
RegisterForSMSandGPS();
ThreadPool.QueueUserWorkItem(state => KeepAlive());
ret = true;
}
catch (System.Exception ex)
{
//radTBStatus.Text = ex.Message;
SafeMobileLib.Utils.WriteLine("Error on connect:" + ex.Message);
}
}
else
{
_shouldStop = true;
_isConnected = false;
serialPort.Close();
SafeMobileLib.Utils.WriteLine("Serial port connection closed.");
this.Invoke((MethodInvoker)delegate
{
radCBPorts.Enabled = true;
lbStatusVAL.Text = "Serial port closed";
lbStatusVAL.ForeColor = Color.Red;
btConect.Text = "Connect";
btConect.Enabled = true;
//this.ControlBox = true;
});
}
//if (!startKeepAliveThread)
//{
// startKeepAliveThread = false;
//}
return true;
}
public static readonly object locker = new object();
public void KeepAlive()
{
while(true)
{
lock (locker)
{
if (!_shouldStop)
{
try
{
string line = "AT\r\n";
if (serialPort.IsOpen)
{
serialPort.WriteTimeout = 500;
serialPort.Write(line);
counter++;
//SafeMobileLib.Utils.WriteLine("Send keep Alive Request");
}
else
{
SafeMobileLib.Utils.WriteLine("Serial port not opened");
//{
// try
// {
// serialPort.Open();
// }
// catch(Exception ex)
// {
this.Invoke((MethodInvoker)delegate
{
lbStatusVAL.ForeColor = Color.Red;
lbStatusVAL.Text = radioMesageError;
btConect.Text = "Connect";
btConect.Enabled = true;
});
needToRegister = true;
keepAlive = false;
_shouldStop = true;
_isConnected = false;
serialPort.Close();
SafeMobileLib.Utils.WriteLine("COM Port not available!", ConsoleColor.Red);
// RestartApp();
// if (!keepAlive && !_shouldStop)
// {
// int count = 0;
// while (count < 40 && !_shouldStop)
// {
// Thread.Sleep(250);
// count++;
// }
// }
// }
}
}
catch
{
this.Invoke((MethodInvoker)delegate
{
lbStatusVAL.ForeColor = Color.Red;
lbStatusVAL.Text = radioMesageError;
btConect.Enabled = true;
});
needToRegister = true;
keepAlive = false;
if (!keepAlive && !_shouldStop)
{
int count = 0;
while (count < 40 && !_shouldStop)
{
Thread.Sleep(250);
count++;
}
}
}
if (_isConnected)
{
//if (needToRegister == false)
//{
//if (keepAlive)
//{
//Console.WriteLine("I'm connected", ConsoleColor.Green);
//}
//else
//{
// counter++;
//}
//}
}
else
{
counter++;
}
if (counter == 2)
{
counter = 0;
this.Invoke((MethodInvoker)delegate
{
lbStatusVAL.ForeColor = Color.Red;
lbStatusVAL.Text = radioMesageError;
btConect.Enabled = true;
});
needToRegister = true;
keepAlive = false;
if (!keepAlive && !_shouldStop)
{
int count = 0;
while (count < 40 && !_shouldStop)
{
Thread.Sleep(250);
count++;
}
}
//conn();
//conn();
}
}
if (!_shouldStop)
{
int count = 0;
while (count < 40 && !_shouldStop)
{
Thread.Sleep(250);
count++;
}
}
if (_shouldStop)
break;
//Thread.Sleep(10000);
}
}
}
private async void btConect_Click(object sender, EventArgs e)
{
btConect.Enabled = false;
btConect.Enabled = await RadioConnectAsync();
}
void RegisterForSMSandGPS()
{
lock (locker)
{
if (Utils.isTetra)
{
try
{
intRegister = 0;
SafeMobileLib.Utils.WriteLine("Send AT with 3 seconds time sleep");
string line = "AT\r\n";
serialPort.WriteTimeout = 500;
serialPort.Write(line);
Thread.Sleep(1000);
serialPort.Write(line);
Thread.Sleep(1000);
serialPort.Write(line);
Thread.Sleep(1000);
if (Utils.Mode.ToUpper().Equals("TMO"))
{
line = "AT+CREG=1\r\n";
SafeMobileLib.Utils.WriteLine("Register in TMO with command: " + line, ConsoleColor.Cyan);
serialPort.Write(line);
Thread.Sleep(1000);
}
line = "AT+CMGS=0,1,0,8\r\n";
SafeMobileLib.Utils.WriteLine("Register for GPS with command: " + line + "83", ConsoleColor.Cyan);
serialPort.Write(line);
Thread.Sleep(1000);
byte[] buf = { (byte)'8', (byte)'3', 26 };
serialPort.Write(buf, 0, 3); // CR 83 CTRL+Z
Thread.Sleep(1000);
line = "AT+CMGS=0,1,0,8\r\n";
SafeMobileLib.Utils.WriteLine("Register for SMS with command: " + line + "82", ConsoleColor.Cyan);
serialPort.Write(line);
Thread.Sleep(1000);
buf[1] = (byte)'2';
serialPort.Write(buf, 0, 3); // CR 82 CTRL+Z
Thread.Sleep(1000);
//fortare Doru Gheorghiu
//ConfirmSMS("101", 0, 0);
//serialPort.DiscardOutBuffer();
}
catch (Exception ex)
{
this.Invoke((MethodInvoker)delegate
{
lbStatusVAL.ForeColor = Color.Red;
lbStatusVAL.Text = radioMesageError;
btConect.Enabled = true;
});
needToRegister = true;
SafeMobileLib.Utils.WriteLine("RegisterForSMSandGPS Exception:" + ex.Message);
}
}
else
{
try
{
//SM.Debug("Send Enable RS232");
serialPort.WriteTimeout = 2000;
string line = "";
SafeMobileLib.Utils.WriteLine("Send Enable RS232");
line = "XOY\r\n";
serialPort.Write(line);
Thread.Sleep(1000);
SafeMobileLib.Utils.WriteLine("Finish registering", ConsoleColor.Green);
try
{
this.Invoke((MethodInvoker)delegate { lbUpdateVAL.Text = DateTime.Now.ToString(); });
}
catch { SafeMobileLib.Utils.WriteLine("Failed to update timestamp in UI", ConsoleColor.Red); }
}
catch (Exception ex)
{
SafeMobileLib.Utils.WriteLine("RegisterForGPS Exception:" + ex.Message, ConsoleColor.Red);
}
}
}
}
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//this.Invoke(new EventHandler(CheckMessage));
CheckMessage(null,null);
}
String msg = "";
next_msg nm;
private void CheckMessage(object s, EventArgs e)
{
lock (locker)
{
if (needToRegister)
{
needToRegister = false;
RegisterForSMSandGPS();
}
}
counter = 0;
this.Invoke((MethodInvoker)delegate
{
lbStatusVAL.ForeColor = Color.Green;
lbStatusVAL.Text = "Communication with radio established";
});
_isConnected = true;
_shouldStop = false;
//SafeMobileLib.Utils.WriteLine("Step1 on Recived");
if (serialPort.IsOpen)
{
Byte[] dataRead = new Byte[serialPort.BytesToRead];
try
{
serialPort.Read(dataRead, 0, (int)dataRead.Length);
//SafeMobileLib.Utils.WriteLine("After Step1 on Recived");
foreach (Byte b in dataRead)
{
if ((b != 10) && (b != 13))
{
msg += (char)b;
}
else
{
if (msg.Length > 0)
SafeMobileLib.Utils.WriteLine("Received message from serial port: " + msg);
if (Utils.isTetra)
{
// parse a location report
if (nm.parse && msg.Length > 2)
{
nm.parse = false;
ParseReport(msg, nm);
}
// see if it is a cmt message
if (msg.Contains("CMT:"))
{
//Console.WriteLine("-------------------------------");
//Console.WriteLine("The message contains CMT, parsing it: " + msg);
nm.parse = true;
ParseCMT(msg);
}
if (msg.Contains("CME") && (msg.Contains("667")))
{
System.Threading.Timer tCheckSTATUS = new System.Threading.Timer(ExecuteDisc, null, 500, System.Threading.Timeout.Infinite);
}
//if (needToRegister)
//{
// needToRegister = false;
// RegisterForSMSandGPS();
//}
if (msg.Contains("CMGS"))
{
intRegister++;
if (intRegister == 2)
{
keepAlive = true;
SafeMobileLib.Utils.WriteLine("Finish registering", ConsoleColor.Green);
try
{
this.Invoke((MethodInvoker)delegate { lbUpdateVAL.Text = DateTime.Now.ToString(); });
}
catch { SafeMobileLib.Utils.WriteLine("Failed to update timestamp in UI", ConsoleColor.Red); }
}
}
}
else
{
if (msg.Length > 2)
{
ParseBarret(msg, SUID);
}
}
msg = "";
}
}
}
catch (System.Exception ex)
{
SafeMobileLib.Utils.WriteLine("error while reading from serial port: " + ex.StackTrace, ConsoleColor.Red);
}
}
}
private void ForceTimer(Object state)
{
System.Threading.Timer tCheckSTATUS = new System.Threading.Timer(ExecuteDisc, null, 300, System.Threading.Timeout.Infinite);
SafeMobileLib.Utils.WriteLine("Force Timer");
}
private void ExecuteDisc(Object state)
{
/* btConect.PerformClick();
System.Threading.Timer tCheckSTATUS = new System.Threading.Timer(ExecuteConnect, null, 3000, System.Threading.Timeout.Infinite);
Console.WriteLine("Force disconect");*/
/*serialPort.Close();
serialPort.Dispose();
serialPort.BaudRate = 9600;
serialPort.PortName = radCBPorts.Text;
Console.WriteLine("PortName: " + serialPort.PortName);
serialPort.Open();
serialPort.ReadTimeout = 200;
serialPort.DataBits = 8;
serialPort.Handshake = System.IO.Ports.Handshake.RequestToSend;
serialPort.Parity = System.IO.Ports.Parity.None;
serialPort.StopBits = System.IO.Ports.StopBits.One;
string line = "AT\r\n";
try
{
//string line = "AT\r\n";
serialPort.WriteTimeout = 1000;
serialPort.Write(line);
Thread.Sleep(1000);
serialPort.Write(line);
Thread.Sleep(1000);
serialPort.Write(line);
Thread.Sleep(1000);
}
catch (Exception ex)
{
Console.WriteLine("Error ex:"+ex.ToString());
}
try
{
SM.Debug("Register for GPS");
line = "AT+CMGS=0,1,0,8\r\n";
//serialPort.WriteTimeout = 2000;
serialPort.Write(line);
Thread.Sleep(1000);
byte[] buf = { (byte)'8', (byte)'3', 26 };
serialPort.Write(buf, 0, 3); // CR 83 CTRL+Z
Thread.Sleep(1000);
SM.Debug("Register for SMS");
line = "AT+CMGS=0,1,0,8\r\n";
serialPort.Write(line);
Thread.Sleep(1000);
buf[1] = (byte)'2';
serialPort.Write(buf, 0, 3); // CR 82 CTRL+Z
Thread.Sleep(1000);
line = "AT+CMGS=0,1,0,8\r\n";
serialPort.Write(line);
Thread.Sleep(1000);
}
catch (Exception ex)
{
Console.WriteLine("Error2:"+ex.ToString());
}*/
try
{
// get old process and wait UP TO 5 secs then give up!
Process oldProcess = Process.GetCurrentProcess();
oldProcess.WaitForExit(5000);
System.Diagnostics.Process.Start(Application.ExecutablePath);
Application.Exit();
}
catch (Exception ex)
{
SafeMobileLib.Utils.WriteLine(ex.ToString());
// the process did not exist - probably already closed!
}
//System.Threading.Timer forcetimer = new System.Threading.Timer(ForceTimer, null, 15000, System.Threading.Timeout.Infinite);
//RegisterForSMSandGPS();
//btConect.PerformClick();
//Console.WriteLine("Retry registration"+serialPort.ToString()+"Serial port":serialPort.);
//RegisterForSMSandGPS();
}
private void ExecuteConnect(Object state)
{
btConect.PerformClick();
SafeMobileLib.Utils.WriteLine("Force Connect");
}
float ProcessGPSLat(String latitude, String lat_dir)
{
try
{
long LAT, LAT2;
char LAT3;
long llat, grade, zec;
char[] param = new char[50];
String[] latList;
float flat;
param = lat_dir.ToCharArray();
if (param[0] != 'N' && param[0] != 'S')
return 0;
//Console.WriteLine("Latitude " + latitude + " dir " + lat_dir);
latList = latitude.Split('.');
LAT = Convert.ToInt32(latList[0]);
if (latList[1].Length > 4)
latList[1] = latList[1].Remove(4);
LAT2 = Convert.ToInt32(latList[1]);
LAT3 = param[0];
// process the lat and lng for display
grade = (LAT / 100L);
zec = (LAT % 100L) * 1000L + LAT2; // get MMMMM*1000, from MM.mmmmm by MM*1000+mmm (0-59999)
zec = (zec * 100L) / 60L; // translate MMMMM*1000 to DD * 100 * 1000 (0-99998)
grade = grade * 100000 + zec; // translate all to DDddddd
llat = grade;
flat = (float)llat / 100000;
if (param[0] == 'S')
flat = -flat;
if (flat < -90 || flat > 90)
{
SafeMobileLib.Utils.WriteLine(string.Format("[warning \"overflow lat\": flat={0} llat={1}]",
flat, llat));
return 0;
}
return flat;
}
catch (Exception ee)
{
SafeMobileLib.Utils.WriteLine("Error in ProcessGPSLat" + ee.ToString(), ConsoleColor.Red);
return 0;
}
}
float ProcessGPSLong(String longitude, String lng_dir)
{
try
{
long LNG, LNG2;
char LNG3;
long llng, grade, zec;
char[] param = new char[50];
String[] lngList;
float flong;
param = lng_dir.ToCharArray();
if (param[0] != 'E' && param[0] != 'W')
return 0;
lngList = longitude.Split('.');
LNG = Convert.ToInt32(lngList[0]);
if (lngList[1].Length > 4)
lngList[1] = lngList[1].Remove(4);
LNG2 = Convert.ToInt32(lngList[1]);
LNG3 = param[0];
grade = LNG / 100; // get DD (0-90)
zec = (LNG % 100L) * 1000L + LNG2; // get MMMMM*1000, from MM.mmmmm by MM*1000+mmm (0-59999)
zec = (zec * 100L) / 60L; // translate MMMMM*1000 to DD * 100 * 1000 (0-99998)
grade = grade * 100000 + zec; // translate all to DDddddd
llng = grade;
flong = (float)llng / 100000;
if (param[0] == 'W')
flong = -flong;
if (flong < -180 || flong > 180)
{
SafeMobileLib.Utils.WriteLine(string.Format("[warning \"overflow lng\": flng={0} llng={1}]",
flong, llng));
return 0;
}
return flong;
}
catch (Exception ee)
{
SafeMobileLib.Utils.WriteLine("Error in ProcessGPSLong" + ee.ToString(), ConsoleColor.Red);
return 0;
}
}
void ParseBarret(String msg,String suid)
{
try
{
htCell_t ht = new htCell_t();
ht.suid = suid;
String latstr = "";
String directLAT = "N";
String lngstr = "";
String directLNG = "E";
SafeMobileLib.Utils.WriteLine("Message is:X" + msg + "X");
if (msg.Length > 20)
{
latstr = msg.Substring(1, 9);
directLAT = msg[10].ToString();
lngstr = msg.Substring(12, 9);
directLNG = msg[21].ToString();
}
ht.lat = ProcessGPSLat(latstr, directLAT).ToString();//lat.ToString();
ht.lng = ProcessGPSLong(lngstr, directLNG).ToString();
ht.spd = "0";
ht.location_time = DateTime.UtcNow;
insertXML(ht);
}
catch (Exception ex)
{
SafeMobileLib.Utils.WriteLine("Error on parse location on barret:" + ex.ToString(), ConsoleColor.Red);
}
}
void ParseCMT(string msg)
{
char[] separators = { ' ', ',' };
string[] vals = msg.Split(separators);
/*
for (i = 0; i < vals.Length; i++)
Console.WriteLine(i.ToString() + ": " + vals[i]);
*/
nm.src_SUID = int.Parse(vals[1]);
nm.msg_len = int.Parse(vals[3]);
nm.parse = true;
nm.suid_type = int.Parse(vals[2]);
nm.data_type = DataType.SDS_TYPE_4;
try
{
nm.data_type = (DataType)Enum.Parse(typeof(DataType), vals[4]);
}
catch (Exception) { }
if(nm.suid_type == 1 && nm.data_type == DataType.STATUS_MESSAGE)
{
emergencyAlarm(nm.src_SUID+"");
}
}
void ParseReport(string msg, next_msg nm)
{
// ellipse-3d (lat, long, angle, semi-major, semi-minor, altitude, altitude-acc?)
if ((msg.Length / 2) == (nm.msg_len / 8))
{
string suid = nm.src_SUID.ToString();
int i = 0;
byte b = GetNextByte(msg, ref i);
//Console.WriteLine("b = " + b);
switch (b)
{
case (byte)0x83:
parseLocation(msg, suid);
break;
case (byte)0x82:
ParseSMS(msg, suid, nm.msg_len / 8 - 4);
break;
//there is no protocol identifier 0x00 - Alarms arrive using the GPS protocol identifier
/*
case (byte)0x00:
emergencyAlarm(GetNextByte(msg, ref i), suid, lastLat, lastLng);
break;
*/
default:
SafeMobileLib.Utils.WriteLine("Warning: This is not a location protocol 0x83, ignore");
break;
}
}
else
{
SafeMobileLib.Utils.WriteLine("ParseReport: length does not match " + msg.Length + "/2 vs " + nm.msg_len + "/8");
}
}
private void SU_ChangeState(string name, bool state)
{
UpdateSUStatus(name, state);
}
public void UpdateSUStatus(string suid, bool status)
{
Byte[] receivedBytes = { 0x00, 0x00, 0x31 };
if (status) receivedBytes[2] = 0x30;
//db.updateStatus(suid, 1, 0);
// else receivedBytes = {0x30}; false defautl
Byte[] toSendMulticast = Utils.createMulticastMessage(130, suid, receivedBytes);
udpMulticast.Send(toSendMulticast, toSendMulticast.Length);
SafeMobileLib.Utils.WriteLine("ARS thread successfully sent data to message bus");
string seqID = "0.0";
//build string
string fullSource = "";
try
{
fullSource = configParams.gateParams.ID.ToString() + "#" + configParams.gateParams.IP.ToString() + "#" + suid;
}
catch (Exception ex)
{
fullSource = configParams.gateParams.ID.ToString() + "#192.168.10.60#" + suid;
SafeMobileLib.Utils.WriteLine("Error on parse IP:" + ex.ToString());
}
string test = "#139#" + fullSource + "#";
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
SafeMobileLib.Utils.WriteLine("Sending to MessageBus: " + cmdok);
udpMulticast.Send(buf, buf.Length);
try
{
this.Invoke((MethodInvoker)delegate { lbUpdateVAL.Text = DateTime.Now.ToString(); });
}
catch { SafeMobileLib.Utils.WriteLine("Failed to update timestamp in UI", ConsoleColor.Red); }
Thread.Sleep(100);
}
private void parseLocation(String message, String suid)
{
htCell_t ht = new htCell_t();
ht.suid = suid;
//ht.spd = "0";
bool parsed_req_id = false, parsed_elipse = false, parsed_time = false, parse_spd = false, parse_periodic = false;
int i = 12;
if ((htSU[suid] != null) && (!((htCell_t)htSU[suid]).state))
{
((htCell_t)htSU[suid]).state = true;
SU_ChangeState(suid, true);
}
else if (htSU[suid] == null)
{
ht.state = true;
htSU.Add(suid, ht);
SU_ChangeState(suid, true);
}
while (i < msg.Length)
{
byte b = GetNextByte(msg, ref i);
if (b == (byte)Report_Messages_Tokens_ENUM.request_id && !parsed_req_id)
{
b = GetNextByte(msg, ref i);
DisplayReqId(b);
parsed_req_id = true;
if (b == (byte)Request_Identifier.Periodic_report) parse_periodic = true;
// ARS ON OFF and emerg
Boolean getoutfast = false;
if (b == (byte)Request_Identifier.SU_is_powered_ON)
{
if (htSU[suid] != null) ((htCell_t)htSU[suid]).state = true;
else
{
ht.state = true;
htSU.Add(suid, ht);
}
SU_ChangeState(suid, true);
getoutfast = true;
}
else if (b == (byte)Request_Identifier.SU_is_powered_OFF)
{
if (htSU[suid] != null) ((htCell_t)htSU[suid]).state = false;
SU_ChangeState(suid, false);
getoutfast = true;
}
//SU_ChangeState(ht.suid, false);
else if (b == (byte)Request_Identifier.Emergency_condition_detected)
{
emergencyAlarm(ht.suid);
//ht.activity_time = DateTime.Now;
//ht.changeState(true);
getoutfast = true;
}
if (getoutfast)
{
//Write_htSU(suid, ht);
return;
}
continue;
}
//BACK TO GPS STATE
if ((b == (byte)Report_Messages_Tokens_ENUM.info_time ||
b == (byte)Report_Messages_Tokens_ENUM.info_time1
) && !parsed_time
)
{
SafeMobileLib.Utils.WriteLine(Report_Messages_Tokens_ENUM.info_time + " (" + b.ToString("X") + ")");
Byte[] time = new byte[5];
time[0] = GetNextByte(msg, ref i);
time[1] = GetNextByte(msg, ref i);
time[2] = GetNextByte(msg, ref i);
time[3] = GetNextByte(msg, ref i);
time[4] = GetNextByte(msg, ref i);
ht.location_time = ProcessTime(time, 0, 5);
parsed_time = true;
continue;
}
if ((b == (byte)Report_Messages_Tokens_ENUM.ellipse_2d ||
b == (byte)Report_Messages_Tokens_ENUM.ellipse_2d1 ||
b == (byte)Report_Messages_Tokens_ENUM.ellipse_3d ||
b == (byte)Report_Messages_Tokens_ENUM.ellipse_3d1 ||
b == (byte)Report_Messages_Tokens_ENUM.ellipse_3d2 ||
b == (byte)Report_Messages_Tokens_ENUM.ellipse_3d3 ||
b == (byte)Report_Messages_Tokens_ENUM.point_2d
) && !parsed_elipse
)
{
SafeMobileLib.Utils.WriteLine("Ellipse (" + b.ToString("X") + "):");
Byte[] data = new byte[4];
data[0] = GetNextByte(msg, ref i);
data[1] = GetNextByte(msg, ref i);
data[2] = GetNextByte(msg, ref i);
data[3] = GetNextByte(msg, ref i);
double lat = ProcessLat(data, 0, 4);
ht.lat = lat.ToString();
lastLat = lat.ToString();
data[0] = GetNextByte(msg, ref i);
data[1] = GetNextByte(msg, ref i);
data[2] = GetNextByte(msg, ref i);
data[3] = GetNextByte(msg, ref i);
double lng = ProcessLng(data, 0, 4);
ht.lng = lng.ToString();
lastLng = lng.ToString();
SafeMobileLib.Utils.WriteLine("\tLat = " + lat);
SafeMobileLib.Utils.WriteLine("\tLng = " + lng);
parsed_elipse = true;
continue;
}
if (b == (byte)Report_Messages_Tokens_ENUM.speed_hor_int && !parse_spd)
{
Console.Write(Report_Messages_Tokens_ENUM.speed_hor_int + "(" + b.ToString("X") + "): ");
int aux = (int)GetNextByte(msg, ref i);
aux &= 0xff;
int spd = 0;
while ((aux & 0x80) != 0)
{
spd |= (aux ^ 0x80);
spd <<= 7;
aux = GetNextByte(msg, ref i);
aux &= 0xff;
}
spd |= aux;
spd = (int) (spd * 3.6);
SafeMobileLib.Utils.WriteLine("speed :" + spd);
ht.spd = spd.ToString();
parse_spd = true;
continue;
}
}
if (parsed_time && parsed_elipse)
insertXML(ht);
else if (parse_periodic)
{
ht.lat = "0";
ht.lng = "0";
ht.spd = "0";
ht.location_time = DateTime.UtcNow;
insertXML(ht);
}
}
void DisplayReqId(byte b)
{
switch (b)
{
case (byte)Request_Identifier.SU_is_powered_ON: SafeMobileLib.Utils.WriteLine(Request_Identifier.SU_is_powered_ON.ToString()); break;
case (byte)Request_Identifier.SU_is_powered_OFF: SafeMobileLib.Utils.WriteLine(Request_Identifier.SU_is_powered_OFF.ToString()); break;
case (byte)Request_Identifier.Emergency_condition_detected: SafeMobileLib.Utils.WriteLine(Request_Identifier.Emergency_condition_detected.ToString()); break;
case (byte)Request_Identifier.PTT_condition_detected: SafeMobileLib.Utils.WriteLine(Request_Identifier.PTT_condition_detected.ToString()); break;
case (byte)Request_Identifier.Status: SafeMobileLib.Utils.WriteLine(Request_Identifier.Status.ToString()); break;
case (byte)Request_Identifier.Transmit_Inhibit_Mode_ON: SafeMobileLib.Utils.WriteLine(Request_Identifier.Transmit_Inhibit_Mode_ON.ToString()); break;
case (byte)Request_Identifier.Transmit_Inhibit_Mode_OFF: SafeMobileLib.Utils.WriteLine(Request_Identifier.Transmit_Inhibit_Mode_OFF.ToString()); break;
case (byte)Request_Identifier.System_access: SafeMobileLib.Utils.WriteLine(Request_Identifier.System_access.ToString()); break;
case (byte)Request_Identifier.DMO_ON: SafeMobileLib.Utils.WriteLine(Request_Identifier.DMO_ON.ToString()); break;
case (byte)Request_Identifier.Enter_service: SafeMobileLib.Utils.WriteLine(Request_Identifier.Enter_service.ToString()); break;
case (byte)Request_Identifier.Leave_service: SafeMobileLib.Utils.WriteLine(Request_Identifier.Leave_service.ToString()); break;
case (byte)Request_Identifier.Cell_reselection: SafeMobileLib.Utils.WriteLine(Request_Identifier.Cell_reselection.ToString()); break;
case (byte)Request_Identifier.Low_battery: SafeMobileLib.Utils.WriteLine(Request_Identifier.Low_battery.ToString()); break;
case (byte)Request_Identifier.SU_connected_Digital_Car_Kit: SafeMobileLib.Utils.WriteLine(Request_Identifier.SU_connected_Digital_Car_Kit.ToString()); break;
case (byte)Request_Identifier.SU_disconnected_Digital_Car_Kit: SafeMobileLib.Utils.WriteLine(Request_Identifier.SU_disconnected_Digital_Car_Kit.ToString()); break;
case (byte)Request_Identifier.Loss_of_coverage: SafeMobileLib.Utils.WriteLine(Request_Identifier.Loss_of_coverage.ToString()); break;
case (byte)Request_Identifier.Recovery_of_coverage: SafeMobileLib.Utils.WriteLine(Request_Identifier.Recovery_of_coverage.ToString()); break;
case (byte)Request_Identifier.SU_movement_by_amount: SafeMobileLib.Utils.WriteLine(Request_Identifier.SU_movement_by_amount.ToString()); break;
case (byte)Request_Identifier.Predefined_text_message: SafeMobileLib.Utils.WriteLine(Request_Identifier.Predefined_text_message.ToString()); break;
case (byte)Request_Identifier.Periodic_report: SafeMobileLib.Utils.WriteLine(Request_Identifier.Periodic_report.ToString()); break;
default: SafeMobileLib.Utils.WriteLine("Unknown Request: 0x" + b.ToString("X")); break;
}
}
DateTime ProcessTime(Byte[] data, int startIndex, int len)
{
// (yyyy*2^26) + (MM*2^22) + (DD*2^17) + (hh*2^12) + (mm*2^6) + ss
Byte B1 = data[startIndex];
Byte B2 = data[startIndex + 1];
Byte B3 = data[startIndex + 2];
Byte B4 = data[startIndex + 3];
Byte B5 = data[startIndex + 4];
int hh, mm, ss, YY, MM, DD;
ss = B5 & 0x3F; // remove first 2b
mm = B4 & 0x0F;
mm <<= 2;
mm |= ((B5 >> 6) & 0x03);
hh = B3 & 0x01;
hh <<= 4;
hh |= ((B4 & 0xf0) >> 4);
DD = B3 & 0x3E;
DD >>= 1;
MM = B2 & 0x03;
MM <<= 2;
MM |= ((B3 >> 6) & 0x03);
YY = B1;
YY <<= 6;
YY |= ((B2 >> 2) & 0x3F);
SafeMobileLib.Utils.WriteLine("\tGPSTime : " + YY + "/" + MM + "/" + DD + " " + hh + ":" + mm + ":" + ss);
return new DateTime(YY, MM, DD, hh, mm, ss, DateTimeKind.Utc);
}
double ProcessLat(Byte[] data, int startIndex, int len)
{
bool sign = false;
if ((data[0] & 0x80) != 0)
{
sign = true;
}
ulong l = (ulong)data[startIndex];
if (sign)
l ^= 0x80; // remove the sign
l <<= 8;
l |= (ulong)data[startIndex + 1];
l <<= 8;
l |= (ulong)data[startIndex + 2];
l <<= 8;
l |= (ulong)data[startIndex + 3];
//Console.WriteLine("lat ulong=0x" + l.ToString("X"));
double ld = (double)l;
ld *= 90;
ld /= 1024;
ld /= 1024;
ld /= 1024;
ld /= 2;
if (sign)
ld *= -1;
return ld;
}
double ProcessLng(Byte[] data, int startIndex, int len)
{
bool sign = false;
if ((data[startIndex] & 0x80) != 0)
{
sign = true;
}
ulong l = (ulong)data[startIndex];
if (sign)
l ^= 0x80; // remove the sign
l <<= 8;
l |= (ulong)data[startIndex + 1];
l <<= 8;
l |= (ulong)data[startIndex + 2];
l <<= 8;
l |= (ulong)data[startIndex + 3];
//Console.WriteLine("lng ulong=0x" + l.ToString("X"));
double ld = (double)l;
ld *= 360;
ld /= 1024;
ld /= 1024;
ld /= 1024;
ld /= 4;
if (sign)
{
ld = 180 - ld;
ld *= -1;
}
return ld;
}
private void emergencyAlarm(String suid)
{
SafeMobileLib.Utils.WriteLine("Emergency alarm received, inserting into db");
try
{
SafeMobileLib.Utils.WriteLine("Received emergency from radio id: " + suid);
string seqID = "0.0";
string toSend = "#138#" + suid + "#";
String cmdok = "#" + seqID + toSend;
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);
//put on multicast bus
SafeMobileLib.Utils.WriteLine("Emergency alarm sent on multicast bus: " + cmdok);
udpMulticast.Send(buf, buf.Length);
try
{
this.Invoke((MethodInvoker)delegate { lbUpdateVAL.Text = DateTime.Now.ToString(); });
}
catch { SafeMobileLib.Utils.WriteLine("Failed to update timestamp in UI", ConsoleColor.Red); }
if (htSU[suid] != null)
{
// ((htCell_t)htSU[suid]).activity_time = DateTime.Now;
//((htCell_t)htSU[suid]).changeState(true);
}
}
catch (Exception e)
{
SafeMobileLib.Utils.WriteLine("emergencyAlarm Exception: " + e.ToString(), ConsoleColor.Red);
}
//}
}
void ParseSMS(string msg, string suid, int len)
{
//SafeMobileLib.Utils.WriteLine("SMS len=" + len);
int i = 2;
byte type = GetNextByte(msg, ref i);
//SafeMobileLib.Utils.WriteLine("Type:" + type);
switch (type)
{
case 0x06:
case 0x04:// this is a SMS message
i = 8;
Byte[] receivedBytes = new Byte[len + 4];
receivedBytes[0] = (Byte)((len + 2) / 256);
receivedBytes[1] = (Byte)((len + 2) % 256);
receivedBytes[2] = 0x00;
receivedBytes[3] = 0x00;
Char[] cs = new Char[150];
for (int k = 0; k < len; k++)
{
byte b = GetNextByte(msg, ref i);
cs[k] = (char)b;
receivedBytes[k + 4] = b;
}
string s = new string(cs, 0, len);
//string key = suid + " | " + DateTime.Now;
SafeMobileLib.Utils.WriteLine("The SMS is [" + s + "]");
// confirm sms
ConfirmSMS(suid, (byte)msg[4], (byte)msg[5]);
if (htSU[suid] != null)
{
//((htCell_t)htSU[suid]).activity_time = DateTime.Now;
//((htCell_t)htSU[suid]).changeState(true);
}
String sms = s;
// remove first 24 characters if is fug
if(s.Length > 24 && Utils.isFug)
sms = s.Substring(24).Trim();
// send message on message bus
SendSMSOnMessageBus(Int64.Parse(suid),sms);
/*
Byte[] toSendMulticast = Utils.createMulticastMessage(132, suid, receivedBytes);
udpMulticast.Send(toSendMulticast, toSendMulticast.Length);
SU_ChangeState(suid, true);
*/
try
{
this.Invoke((MethodInvoker)delegate { lbUpdateVAL.Text = DateTime.Now.ToString(); });
}
catch { SafeMobileLib.Utils.WriteLine("Failed to update timestamp in UI", ConsoleColor.Red); }
break;
case 0x10: // this is a sms confirmation
byte ack = GetNextByte(msg, ref i);
if (ack == 0)
{
byte id = GetNextByte(msg, ref i);
SafeMobileLib.Utils.WriteLine("Received confirmation for message with ID = " + id);
}
else
{
SafeMobileLib.Utils.WriteLine("No acknowledge received for sent message.");
}
if (htSU[suid] != null)
{
//((htCell_t)htSU[suid]).activity_time = DateTime.Now;
//((htCell_t)htSU[suid]).changeState(true);
}
break;
default:
SafeMobileLib.Utils.WriteLine("Error: ParseSMS: Unknown message type");
break;
}
}
public void SendSMSOnMessageBus(Int64 radioID, string message)
{
string msg = "#" + (int)MessageBusCmds.SMSReceived + "#" + radioID + "#" + message + "#hyt#";
SendOnMsgBuss(msg);
SU_ChangeState(radioID+"", true);
}
/// <summary>
/// Send a string on the message bus. The string will be converted into a byte array before
/// beeing sent
/// </summary>
/// <param name="commandMsg">The message which needs to be sent on the message bus</param>
public void SendOnMsgBuss(string commandMsg)
{
String seqID = "1." + (Utils.GetSecondsLocalFromDT(DateTime.Now)) + DateTime.Now.Millisecond.ToString();
byte[] buf = SafeMobileLib.Utils.Convert_text_For_multicast("#" + seqID + commandMsg);
SendOnMessageBus(buf, buf.Length);
}
/// <summary>
/// Send a byte array of a specific length on the message bus
/// </summary>
/// <param name="data">Data which needs to be sent on the message bus</param>
/// <param name="length">Data which needs to be sent on the message bus</param>
private void SendOnMessageBus(byte[] message, int length)
{
if (udpMulticast != null)
{
udpMulticast.Send(message, length);
SafeMobileLib.Utils.WriteLine(String.Format("+++ MB [{0}] ", ConvertBytesToString(message)), ConsoleColor.White);
}
else
{
SM.Debug("••• Could not send on MB, it is null");
}
}
public static string ConvertBytesToString(Byte[] receivedBytes)
{
string response = "";
for (int i = 0; i < receivedBytes.Length; i++)
{
response = String.Format("{0}{1}", response, (char)receivedBytes[i]);
}
return response;
}
// takes 2chars from the string, and returns creates a byte from them
// (hex to byte)
byte GetNextByte(string msg, ref int i)
{
if (i >= msg.Length)
return 0;
byte high_nibble = bVal(msg[i]);
byte low_nibble = bVal(msg[i + 1]);
byte ret = high_nibble;
ret <<= 4;
ret |= low_nibble;
i += 2;
return ret;
}
// char -> byte value
byte bVal(char c)
{
byte ret;
if (c >= '0' && c <= '9')
ret = (byte)(c - '0');
else
{
ret = (byte)(c - 'A');
ret += 10;
}
return ret;
}
void ConfirmSMS(string suid, byte hb, byte lb)
{
int i;
try
{
serialPort.DiscardOutBuffer();
SafeMobileLib.Utils.WriteLine("Confirming SMS");
string line = "AT+CMGS=" + suid + ",1,0,32";
serialPort.Write(line); // AT+CMGS=suid,1,0,len (len of buf+header in bits)
SafeMobileLib.Utils.WriteLine(line);
byte[] buf = { 13, (byte)'8', (byte)'2',
(byte)'1', (byte)'0',
(byte)'0', (byte)'0',
(byte)'0', (byte)'0'}; // dummy fill (2B) for msg id
buf[7] = hb;
buf[8] = lb;
serialPort.Write(buf, 0, 9); // <cr> 82 10 00 id <ctrl+z>
buf[0] = 26;
serialPort.Write(buf, 0, 1); // <ctrl+z>
string saux = "";
for (i = 1; i < 9; i++)
{
char c = (char)buf[i];
saux += c;
if (i % 2 == 0)
saux += " ";
}
SafeMobileLib.Utils.WriteLine(saux + "\r\nEND");
}
catch (Exception ex)
{
SafeMobileLib.Utils.WriteLine("ConfirmSMS Exception:" + ex.Message, ConsoleColor.Red);
}
}
uint DateTo70Format(DateTime time)
{
long nOfSeconds;
System.DateTime dt70 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
TimeSpan span = time - dt70;
nOfSeconds = (long)span.TotalSeconds;
return ((uint)nOfSeconds);
}
public void insertXML(htCell_t cell)
{
String xml = ""; // this is the xml message that will be uploaded into the DB
xml = "id=\"100001\" mode=\"GPRS\" Hw_Type=\"NAVL\" subscriber=\"" + cell.suid;
xml += "\" time=\"" + DateTo70Format(cell.location_time).ToString() + "\" latitude=\"" + cell.lat + "\" longitude=\"" + cell.lng;
xml += "\" speed=\"" + cell.spd + "\" dgr=\"" + "0";
xml += "\" ai1=\"" + "0" + "\" ai2=\"" + "0";
xml += "\" ai3=\"" + "0" + "\" ai4=\"" + "0";
xml += "\" ai5=\"" + "0" + "\" ai6=\"" + "0";
xml += "\" ai7=\"" + "0" + "\" ai8=\"" + "0";
xml += "\" di=\"" + "0" + "\" do=\"" + "0" + "\"";
if (xml.Length > 0)
{
xml = "<rsp " + xml + "></rsp>";
}
if (cell.spd == null)
cell.spd = "0";
try
{
String[] toSendString = new String[4];
toSendString[0] = DateTo70Format(cell.location_time).ToString();
toSendString[1] = cell.spd.ToString();
toSendString[2] = cell.lat.ToString();
toSendString[3] = cell.lng.ToString();
SafeMobileLib.Utils.WriteLine(String.Format("»»» Position [{0:0.0000},{1:0.0000}] from {2} [{3} kmh]", Math.Round(Double.Parse(cell.lat), 4),
Math.Round(Double.Parse(cell.lng), 4), cell.suid, cell.spd));
Byte[] toSendMulticast = Utils.createLocationMessage(131, cell.suid, toSendString);
udpMulticast.Send(toSendMulticast, toSendMulticast.Length);
//SafeMobileLib.Utils.WriteLine("Send #131 location data: " + xml);
try
{
this.Invoke((MethodInvoker)delegate { lbUpdateVAL.Text = DateTime.Now.ToString(); });
}
catch { SafeMobileLib.Utils.WriteLine("Failed to update timestamp in UI", ConsoleColor.Red); }
}
catch (Exception e)
{
SafeMobileLib.Utils.WriteLine("error on send #131 location data \n" + e.ToString(), ConsoleColor.Red);
}
}
private void MainForm_Shown(object sender, EventArgs e)
{
ThemeResolutionService.ApplicationThemeName = "TelerikMetroBlue";
}
private void timer1_Tick(object sender, EventArgs e)
{
// btConect.PerformClick();
serialPort.BaudRate = 9600;
//serialPort.BaudRate = 115200;
//serialPort.BaudRate = 38400;
serialPort.PortName = radCBPorts.Text;
SafeMobileLib.Utils.WriteLine("PortName: " + serialPort.PortName);
serialPort.Open();
serialPort.ReadTimeout = 200;
serialPort.WriteTimeout = 1;
serialPort.DataBits = 8;
if (Utils.isTetra) serialPort.Handshake = System.IO.Ports.Handshake.RequestToSend;
else serialPort.Handshake = System.IO.Ports.Handshake.XOnXOff;
serialPort.Parity = System.IO.Ports.Parity.None;
serialPort.StopBits = System.IO.Ports.StopBits.One;
SafeMobileLib.Utils.WriteLine("Serial port connection open.");
//radCBPorts.Enabled = false;
RegisterForSMSandGPS();
timer1.Stop();
timer1.Enabled = false;
}
private void RestartTimer_Tick(object sender, EventArgs e)
{
Process oldProcess = Process.GetCurrentProcess();
oldProcess.WaitForExit(5000);
System.Diagnostics.Process.Start(Application.ExecutablePath);
Application.Exit();
}
private void ckAutoconnect_ToggleStateChanged(object sender, StateChangedEventArgs args)
{
if (source.Configs["Gateway"] == null)
source.Configs.Add("Gateway");
source.Configs["Gateway"].Set("autoconnect", ckAutoconnect.Checked);
source.Save();
}
private void radCBPorts_SelectedIndexChanged(object sender, Telerik.WinControls.UI.Data.PositionChangedEventArgs e)
{
if (radCBPorts.SelectedItem != null)
{
if (source.Configs["Gateway"] == null)
source.Configs.Add("Gateway");
source.Configs["Gateway"].Set("COMPort", radCBPorts.SelectedItem.Text);
source.Save();
}
}
private void RestartApp()
{
try
{
Process oldProcess = Process.GetCurrentProcess();
oldProcess.WaitForExit(5000);
System.Diagnostics.Process.Start(Application.ExecutablePath, "-c");
Application.Exit();
//Process curentProcess = Process.GetCurrentProcess();
//Process[] ProcessDispatchList = Process.GetProcessesByName("Tetra_GW");
//Process ProcessDispName = null;
//try
//{
// if (ProcessDispatchList.Length > 0)
// {
// if (ProcessDispatchList[0] != null) ProcessDispName = ProcessDispatchList[0];
// }
//}
//catch (Exception ex)
//{
// SafeMobileLib.Utils.WriteLine("Error on get proccess by name" + ex.ToString());
//}
//Process ProcessDispatch = Process.GetCurrentProcess();
////ok i will put 650 Mega to include more stuff with hisotry and geofence
//if (ProcessDispName != null)
//{
// //Utils.WriteLine("CurentProcess:" + curentProcess.WorkingSet64 + " ProccessDispName:" + ProcessDispName.WorkingSet64, ConsoleColor.Green);
// //Utils.WriteLine("rResatr ameem value:" + MainForm2.RestartMEM, ConsoleColor.Green);
// Process oldProcess = Process.GetCurrentProcess();
// oldProcess.WaitForExit(8000);
// System.Diagnostics.Process.Start(System.Windows.Forms.Application.ExecutablePath, "");
// oldProcess.Kill();
// System.Windows.Forms.Application.Exit();
//}
}
catch (Exception ex)
{
SM.Debug("Error on restart thread:" + ex.ToString());
}
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
keepAlive = false;
_shouldStop = true;
_isConnected = false;
if (serialPort.IsOpen)
{
e.Cancel = true; //cancel the fom closing
Thread CloseDown = new Thread(new ThreadStart(CloseSerialOnExit)); //close port in new thread to avoid hang
CloseDown.Start(); //close port in new thread to avoid hang
}
//Thread.Sleep(200);
//if (serialPort.IsOpen) serialPort.Dispose();
//Process oldProcess = Process.GetCurrentProcess();
//oldProcess.WaitForExit(5000);
//Application.Exit();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private void CloseSerialOnExit()
{
try
{
serialPort.Close(); //close the serial port
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message); //catch any serial port closing error messages
}
this.Invoke(new EventHandler(NowClose)); //now close back in the main thread
}
private void NowClose(object sender, EventArgs e)
{
this.Close(); //now close the form
}
#region UPDATE
/// <summary>
/// Check for new version release on SafeMobile Portal
/// The check is done by comparing Current Assembly Version with the one
/// written in a xml file on the portal.
/// </summary>
private void CheckForUpdate()
{
App appType = App.GW_TETRA;
AutoUpdate au = new AutoUpdate(appType) { IsDevelop = Utils.isDevelop };
au.OnNewVersionAvailable += delegate (string version)
{
notifyIcon1.Text = "New version available";
notifyIcon1.ShowBalloonTip(2500, $"{App.GetAppName(appType)} version {version} available",
$"Press to download and install the latest version of {App.GetAppName(appType)}.", ToolTipIcon.Info);
notifyIcon1.BalloonTipClicked += delegate (object sender, EventArgs e)
{
if (notifyIcon1.Text.Equals("New version available"))
{
UpdateForm uf = new UpdateForm(appType, true) { IsDevelop = Utils.isDevelop };
uf.Show();
}
};
};
// call method to check for new updated
au.CheckUpdate();
}
#endregion
private void CloseApp()
{
MainForm_FormClosing(null, null);
Process oldProcess = Process.GetCurrentProcess();
oldProcess.Kill();
Application.Exit();
}
/// <summary>
/// Get an int value from the configuration file. The desired value is identifiec by
/// the key and the header under which is placed is pointed by the header. Also a default
/// value can be set in case the value doesn't exist and needs to be created before
/// beeing returned
/// </summary>
/// <param name="header">Header unde which the desired config parameter is placed</param>
/// <param name="key">The Key that designates the desired config parameter</param>
/// <param name="defaultValue">A default value that will be used and returned in case the
/// config file doesn't have a value for the parameter</param>
/// <returns>Parameter value from the config file, or the default value in case it doesn't
/// exist</returns>
private Int32 GetInt32Value(String header, String key, Int32 defaultValue)
{
if (!source.Configs[header].Contains(key))
source.Configs[header].Set(key, defaultValue);
return source.Configs[header].GetInt(key);
}
private void MainForm_Load(object sender, EventArgs e)
{
ContextMenu contextMenu = new ContextMenu();
contextMenu.MenuItems.Add("Check for updates...", (s, e2) => {
UpdateForm uf = new UpdateForm(App.GW_TETRA, true) { IsDevelop = Utils.isDevelop };
uf.Show();
});
contextMenu.MenuItems.Add("Exit", (s, e2) => CloseApp());
notifyIcon1.ContextMenu = contextMenu;
// check for a new version if available
if (Utils.autoupdate)
CheckForUpdate();
}
/// <summary>
/// Get a string value from the configuration file. The desired value is identifiec by
/// the key and the header under which is placed is pointed by the header. Also a default
/// value can be set in case the value doesn't exist and needs to be created before
/// beeing returned
/// </summary>
/// <param name="header">Header unde which the desired config parameter is placed</param>
/// <param name="key">The Key that designates the desired config parameter</param>
/// <param name="defaultValue">A default value that will be used and returned in case the
/// config file doesn't have a value for the parameter</param>
/// <returns>Parameter value from the config file, or the default value in case it doesn't
/// exist</returns>
private String GetStringValue(String header, String key, String defaultValue)
{
if (!source.Configs[header].Contains(key))
source.Configs[header].Set(key, defaultValue);
return source.Configs[header].GetString(key);
}
/// <summary>
/// Get a boolean value from the configuration file. The desired value is identifiec by
/// the key and the header under which is placed is pointed by the header. Also a default
/// value can be set in case the value doesn't exist and needs to be created before
/// beeing returned
/// </summary>
/// <param name="header">Header unde which the desired config parameter is placed</param>
/// <param name="key">The Key that designates the desired config parameter</param>
/// <param name="defaultValue">A default value that will be used and returned in case the
/// config file doesn't have a value for the parameter</param>
/// <returns>Parameter value from the config file, or the default value in case it doesn't
/// exist</returns>
private Boolean GetBooleanValue(String header, String key, Boolean defaultValue)
{
if (!source.Configs[header].Contains(key))
source.Configs[header].Set(key, defaultValue);
return source.Configs[header].GetBoolean(key);
}
}
}