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); // 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); // 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 responseList = new List(); // 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 request = new List(); 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 RadioConnectAsync() { return await Task.Factory.StartNew(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); } /// /// Send a string on the message bus. The string will be converted into a byte array before /// beeing sent /// /// The message which needs to be sent on the message bus 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); } /// /// Send a byte array of a specific length on the message bus /// /// Data which needs to be sent on the message bus /// Data which needs to be sent on the message bus 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); // 82 10 00 id buf[0] = 26; serialPort.Write(buf, 0, 1); // 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 = ""; } 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 /// /// 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. /// 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(); } /// /// 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 /// /// Header unde which the desired config parameter is placed /// The Key that designates the desired config parameter /// A default value that will be used and returned in case the /// config file doesn't have a value for the parameter /// Parameter value from the config file, or the default value in case it doesn't /// exist 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(); } /// /// 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 /// /// Header unde which the desired config parameter is placed /// The Key that designates the desired config parameter /// A default value that will be used and returned in case the /// config file doesn't have a value for the parameter /// Parameter value from the config file, or the default value in case it doesn't /// exist 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); } /// /// 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 /// /// Header unde which the desired config parameter is placed /// The Key that designates the desired config parameter /// A default value that will be used and returned in case the /// config file doesn't have a value for the parameter /// Parameter value from the config file, or the default value in case it doesn't /// exist 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); } } }