using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using SafeMobileLib; using System.Threading; using SafeMobileLib.MessageDecoders; namespace MotoRepeater { class SMSReceiveThread { public UInt16 smsPort; private byte[] data = new byte[1024]; private UdpClient udpClient; public SMSReceiveThread(UInt16 port, UdpClient _udpClient) { smsPort = port; SMSConfirm.fillList(); SMSConfirm.initializeTimer(); ; udpClient = _udpClient; } public void handleConnection() { Utils.WriteLine("♥♥♥ SMS Receive Thread Started on port " + smsPort); IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); while (MotoRepeater_GW.isRunning) { try { //Utils.WriteLine("SMS Receive Thread waiting..."); // Blocks until a message returns on this socket from a remote host. Byte[] receivedBytes = udpClient.Receive(ref remoteIpEndPoint); //Console.WriteLine("======================================================="); char[] separator = { '.' }; string[] su = remoteIpEndPoint.Address.ToString().Split(separator); uint radioID = (Convert.ToUInt32(su[1])) * 256 * 256 + (Convert.ToUInt32(su[2])) * 256 + Convert.ToUInt32(su[3]); //EndPoint p= udpClient.Client.LocalEndPoint; string suid = radioID.ToString(); Utils.WriteLine("SMS Thread received data from radio " + radioID); header_T hret = DecodePacket(receivedBytes); if (hret.ack) { //Thread.Sleep(1000); // The client needs an ACK byte extension_header = 0; if (hret.seq_no > 0x1F) extension_header = 1; Byte[] sendBytes = new Byte[5 + extension_header]; sendBytes[0] = 0x00; // len (2B) sendBytes[1] = (byte)(3 + extension_header); sendBytes[2] = 0xBF; // first header (req) sendBytes[3] = 0x00; // addr len sendBytes[4] = (byte)(hret.seq_no & 0x1F); // 2nd header (opt) if (extension_header == 1) { sendBytes[4] += 0x80; //added the extension header info sendBytes[5] = (byte)(hret.seq_no & 0x60); } //Console.WriteLine("SMSReceiveThread ACK sent: " + Utils.Byte2String(sendBytes, 0, sendBytes[1] + 2)); // schedule ack sending after 1 second new Thread(() => { Thread.CurrentThread.IsBackground = true; Thread.Sleep(1000); /* run your code here */ udpClient.Send(sendBytes, sendBytes[1] + 2, remoteIpEndPoint); }).Start(); } if (hret.header != 0x0BF) //regular message received { Utils.WriteLine(String.Format("»»» SMS from radio {0} [{1}]", radioID, hret.message)); //put information on message bus //Byte[] toSendMulticast = Utils.createMulticastMessage(132, suid, receivedBytes); //OnSMSBytesReceived(Int64.Parse(suid), receivedBytes); OnSMSReceived(Int64.Parse(suid), hret.message); //udpMulticast.Send(toSendMulticast, toSendMulticast.Length); } else //ack received { string seq_no = SMSConfirm.getFromConfirmationQueue(hret.seq_no); #if DEBUG Utils.WriteLine("Received ACK with header:" + hret.header + " with seq_id :" + hret.seq_no); Utils.WriteLine("SMSConfirm.getFromConfirmationQueue(hret.seq_no)=" + seq_no); #endif Utils.WriteLine(String.Format("»»» SMS ACK from radio {0}", radioID)); byte[] buf = SafeMobileLib.Utils.Convert_text_For_multicast("#" + seq_no + "#242#1#"); OnSMSAckReceived(buf, seq_no.Equals("0.0") ? hret.seq_no+"" : seq_no); //udpMulticast.Send(buf, buf.Length); } Thread.Sleep(100); } catch (Exception e) { if(MotoRepeater_GW.isRunning) Utils.WriteLine("••• SMS Received Thread is restarting..."); } } } header_T DecodePacket(Byte[] data) { header_T hret = new header_T(); hret.message = ""; int i, j, pdata; pdata = (int)data[0]; pdata <<= 8; pdata |= (int)data[1]; // parse header int header = data[2]; hret.header = data[2]; 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; //Console.Write("Address: "); for (j = 0; j < addrsize; j++) { //Console.Write(data[i + j].ToString("X")); } i += j; // 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++; } } int crc = 0; if ((!hret.cntl) && (hret.pdu_type == 0)) { // the rest is the txt 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); hret.message = s; //Console.WriteLine("Message [" + s + "]"); } return hret; } public delegate void SMSReceived(Int64 radioID, String message); public event SMSReceived OnSMSReceived; public delegate void SMSReceivedBytes(Int64 radioID, byte[] received); public event SMSReceivedBytes OnSMSBytesReceived; public delegate void SMSAckReceived(byte[] received, string seq_no); public event SMSAckReceived OnSMSAckReceived; } }