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