using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Net; using System.Net.Sockets; using SafeMobileLib; namespace MotoTrbo_GW { class TallysmanSendThread { //public static IPEndPoint iep; //public static Socket server; private Int32 Port = 0; //private string radioIP; private UdpMulticast udpMulticastBusConnection = null; DBvehiclesManager vehiclesManager; UdpClient udpClient; private String mIP; private Int32 mPort; private static System.Threading.Timer tCheckMissingIds; public TallysmanSendThread(Int32 port, String multicastID, String multicastPort, int TallysmanRequestInterval) { Port = port; mIP = multicastID; mPort = Int32.Parse(multicastPort); vehiclesManager = new DBvehiclesManager(Main.DBServer, Main.DBSchema, Main.DBUser, Main.DBPass, Main.DBPort); //retrive tallysman missing log ids if (TallysmanRequestInterval >= 1) tCheckMissingIds = new Timer(Check4MissingIds, null, new TimeSpan(0, 0, 0), new TimeSpan(0, TallysmanRequestInterval, 0)); } public void resetCheckTimer(int newvalue) { if (newvalue == 0) tCheckMissingIds?.Dispose(); else tCheckMissingIds = new Timer(Check4MissingIds, null, new TimeSpan(0, 0, 0), new TimeSpan(0, newvalue, 0)); } public void handleConnection() { try { udpMulticastBusConnection = new UdpMulticast(mIP, mPort); udpMulticastBusConnection.OnNewDataRecv += new UdpMulticast.newData4Send(udp_OnNewDataReceived); udpMulticastBusConnection.StartListen(Main.LocalIP); } catch (Exception ex) { SafeMobileLib.Utils.WriteLine("TallysmanSendThread exception while joining the multicast group: " + ex.ToString()); } SafeMobileLib.Utils.WriteLine("TallysmanSendThread initialized on port " + Port, ConsoleColor.Yellow); try { udpClient = new UdpClient(); udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, Port)); } catch (Exception ex) { SafeMobileLib.Utils.WriteLine("TallysmanSendThread handleConnection exception while creating udpClient: " + ex.ToString()); } while (true) { /* IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); Byte[] receivedBytes = udpClient.Receive(ref remoteIpEndPoint); 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]); string suid = radioID.ToString(); Byte toreturn = TallysmanReceiveThread.ProcessPacket2(receivedBytes, receivedBytes.Length, radioID.ToString().Trim()); */ Thread.Sleep(100); } #region test ////ping ////Byte[] sendBytes = { 0xFA, //// 0x08, //// 0x04, //// 0x01, //// 0x4D, //// 0xB1, //// 0x04 //// }; ////List myByteArray = new List(); ////myByteArray.Add((byte)(Int32.Parse("FA", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("08", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("09", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("04", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("11", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("05", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("84", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("00", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("02", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("EA", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("5E", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("EA", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("5F", System.Globalization.NumberStyles.HexNumber))); ////Byte[] sendBytes = myByteArray.ToArray(); ////string galeata = ""; ////List myByteArray = new List(); ////myByteArray.Add((byte)(Int32.Parse("FA", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("08", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("0E", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("04", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("11", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("05", System.Globalization.NumberStyles.HexNumber))); ////myByteArray.Add((byte)(Int32.Parse("03", System.Globalization.NumberStyles.HexNumber))); ////double startDate = DateTime.Today.Year * (double)Math.Pow(2, 26) + //// DateTime.Today.Month * (double)Math.Pow(2, 22) + //// DateTime.Today.Day * (double)Math.Pow(2, 17) + //// DateTime.Today.Hour * (double)Math.Pow(2, 12) + //// DateTime.Today.Minute * (double)Math.Pow(2, 6) + //// DateTime.Today.Second; ////string startDateHex = ((Int64)startDate).ToString("X2"); ////foreach (char c in startDateHex) ////{ //// galeata += c; //// if (galeata.Length == 2) //// { //// myByteArray.Add((byte)(Int32.Parse(galeata, System.Globalization.NumberStyles.HexNumber))); //// galeata = ""; //// } ////} ////double stopDate = DateTime.Now.Year * (double)Math.Pow(2, 26) + //// DateTime.Now.Month * (double)Math.Pow(2, 22) + //// DateTime.Now.Day * (double)Math.Pow(2, 17) + //// DateTime.Now.Hour * (double)Math.Pow(2, 12) + //// DateTime.Now.Minute * (double)Math.Pow(2, 6) + //// DateTime.Now.Second; ////string stopDateHex = ((Int64)stopDate).ToString("X2"); ////foreach (char c in stopDateHex) ////{ //// galeata += c; //// if (galeata.Length == 2) //// { //// myByteArray.Add((byte)(Int32.Parse(galeata, System.Globalization.NumberStyles.HexNumber))); //// galeata = ""; //// } ////} ////Byte[] sendBytes = myByteArray.ToArray(); ////Byte[] sendBytes = { //// (byte)(Int32.Parse("FA", System.Globalization.NumberStyles.HexNumber)), // protocol //// 0x08, // version //// 0x06, // length in Bytes -> 6 bytes follow //// 0x04, // message type -> Log Retrieval Request message //// 0x11, // transaction id -> I’ve put a random int, I don’t know it’s ok like this //// 0x05, // request lat, long, speed //// 0x10, // Search Form request S4 log id binar 10000 = dec 16 hex 10 //// 0xEA, //// 0x75, //// 0X01, //// 0x01 // requested log id is 13685 – encoded into BE 58 //// }; //var missing = GetTallysmanMissingLogIDLastDay(); //RequestTallysmanLogsOneByOne(missing); ////Byte[] sendBytes = { //// (byte)(Int32.Parse("FA", System.Globalization.NumberStyles.HexNumber)), // protocol //// 0x08, // version //// 0x08, // length in Bytes -> 6 bytes follow //// 0x04, // message type -> Log Retrieval Request message //// 0x11, // transaction id -> I’ve put a random int, I don’t know it’s ok like this //// 0xFF, // request lat, long, speed //// 0xFF, // request lat, long, speed //// 0x1F, // request lat, long, speed //// 0x81, // Search Form request S4 log id binar 10000 = dec 16 hex 10 //// 0xA6, //// 0x29 // requested log id is 13685 – encoded into BE 58 //// }; ////Byte[] sendBytes = { 0xFA, //// 0x08, //// 0x04, //// 0x01, //// 0x4D, //// 0xB1, //// 0x04 //// }; ////Byte[] sendBytes = { //// (byte)(Int32.Parse("FA", System.Globalization.NumberStyles.HexNumber)), // protocol //// 0x08, // version //// 0x08, // length in Bytes -> 6 bytes follow //// 0x04, // message type -> Log Retrieval Request message //// 0x11, // transaction id -> I’ve put a random int, I don’t know it’s ok like this //// 0x05, // request lat, long, speed //// 0x80, // request lat, long, speed //// 0x08, // request lat, long, speed //// 0x01, // Search Form request S4 log id binar 10000 = dec 16 hex 10 //// 0xF8, //// 0x05 //// }; //bool send = true; //while (true) //{ // //if (send) // //{ // // udpClient.Client.SendTo(sendBytes, new IPEndPoint(IPAddress.Parse(Utils.ID2IP("12", "70")), 4069)); // // SM.Debug("POLL location request sent to radio ID " + "70"); // // Thread.Sleep(10000); // // IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); // // send = false; // //} // //try // //{ // // // Blocks until a message returns on this socket from a remote host. // // SafeMobileLib.Utils.WriteLine("Before read "); // // Byte[] receivedBytes = udpClient.Receive(ref remoteIpEndPoint); // // SafeMobileLib.Utils.WriteLine("After read "); // // 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]); // // string suid = radioID.ToString(); // // SafeMobileLib.Utils.WriteLine("TEST TALLYSMAN Thread received data from radio " + radioID); // // //Utils.printBytesArray(receivedBytes); // // Thread.Sleep(100); // //} // //catch (Exception ex) // //{ // // SafeMobileLib.Utils.WriteLine("Exception: "+ex.ToString()); // //} //} #endregion } void udp_OnNewDataReceived(byte[] data, int dataLen) { try { string str = System.Text.Encoding.ASCII.GetString(data, 0, dataLen); String[] tempArray = str.Trim().Split('#'); if (tempArray.Length > 3) { if (tempArray[3].Equals("154")) { Int64 gwid_recv = Convert.ToInt64((tempArray[4].Split('.'))[0]); if (gwid_recv == Main.GWID) { SafeMobileLib.Utils.WriteLine("Poll request received from multicast bus: " + str.Trim()); string SUID = (tempArray[4].Split('.'))[2]; SendPollRequest(SUID); } } } } catch (Exception ex) { SafeMobileLib.Utils.WriteLine(ex.ToString()); } } public void SendPollRequest(string suid) { try { long radioID = (long)Convert.ToDouble(suid); #region prepare payload //ping Tallysman //copied from Sprite 3.5 //3.5 Immediate Request (0x01) Byte[] sendBytes = { 0xFA, 0x08, 0x04, 0x01, 0x4D, 0xB1, 0x04 }; #endregion sendTallysmanCommand(sendBytes, radioID); } catch { } } public void sendTallysmanCommand(String ID, String _gpio, String _type, int transactionID) { } List logIDS = null; private void Check4MissingIds(Object state) { logIDS = vehiclesManager.getGetTallysmanLogs(Main.TallysmanRequestInterval); //3.8 Log Retrieval Request (0x04) RequestTallysmanLogsOneByOne(GetTallysmanMissingLogIDLastDay(logIDS)); } public List GetTallysmanMissingLogIDLastDay(List LogIds) { //List LogIds = new List(); //LogIds.Add(new TallysmanLostLog { RadioID = 70, LogId = 13665 }); //LogIds.Add(new TallysmanLostLog { RadioID = 70, LogId = 13681 }); //LogIds.Add(new TallysmanLostLog { RadioID = 70, LogId = 13685 }); //LogIds.Add(new TallysmanLostLog { RadioID = 70, LogId = 13695 }); //LogIds.Add(new TallysmanLostLog { RadioID = 70, LogId = 13895 }); List MissingLogID = new List(); var RadioList = LogIds.Select(t => t.RadioID).Distinct().ToList(); foreach (var RadioID in RadioList) { var terminalList = LogIds.Where(t => t.RadioID == RadioID).Select(t => t.LogId).ToList(); for (Int64 i = terminalList.Min(); i < terminalList.Max(); i++) { if (!terminalList.Contains(i)) //logid's to be send MissingLogID.Add(new TallysmanLostLog { RadioID = RadioID, LogId = i }); } //send result to radio id current tagList if (MissingLogID.Count > 0) { // } } return MissingLogID; } public string GetTallysmanUintvarEncoding(int number) { string ret = ""; bool firstByte = true; string result = string.Empty; int i = 0, j = 0; var temp = Convert.ToString(number, 2); i = temp.Length - 1; do { result += temp.Substring(i, 1); i--; j++; if (j % 7 == 0) { result += (firstByte) ? "0" : "1"; firstByte = false; } } while (i >= 0); //complete final byte int nrOfBytes = result.Length / 8; if (nrOfBytes > 0) { if ((result.Length % 8) > 0) { nrOfBytes++; for (int k = result.Length; k < 8 * nrOfBytes - 1; k++) result += "0"; result += "1"; } } //reverse string char[] charArray = result.ToCharArray(); Array.Reverse(charArray); int uintvar = (int)(Convert.ToInt32(new string(charArray), 2)); ret = uintvar.ToString("X2"); return ret; } public void RequestTallysmanLogsOneByOne(List missing) { var RadioList = missing.Select(t => t.RadioID).Distinct().ToList(); foreach (var radioID in RadioList) { string UintvarLogId = ""; List byteArray = new List(); string chunk = ""; var terminalList = missing.Where(t => t.RadioID == radioID).Select(t => t.LogId).ToList(); foreach (var item in terminalList) { UintvarLogId = GetTallysmanUintvarEncoding((int)item); #region prepare payload List sendByteArray = new List(); #region Message Header sendByteArray.Add((byte)(Int32.Parse("FA", System.Globalization.NumberStyles.HexNumber)));//protocol sendByteArray.Add((byte)(Int32.Parse("08", System.Globalization.NumberStyles.HexNumber)));//version #endregion #region Message Length int messageTypeLength = 1; // 0x04 int transactionIdLength = 1; // 0x11 int reportFormLength = 3; // 0xFF 0xFF 0x1D int searchFormLength = 1; // 0x10 int maxResultLength = 1; //0x01 int messageLength = messageTypeLength + transactionIdLength + reportFormLength + searchFormLength + maxResultLength + UintvarLogId.Length / 2; string uintvarMessageLenght = GetTallysmanUintvarEncoding(messageLength); foreach (char c in uintvarMessageLenght) { chunk += c; if (chunk.Length == 2) { sendByteArray.Add((byte)(Int32.Parse(chunk, System.Globalization.NumberStyles.HexNumber))); chunk = ""; } } #endregion #region Message Static elements sendByteArray.Add((byte)(Int32.Parse("04", System.Globalization.NumberStyles.HexNumber)));//message type sendByteArray.Add((byte)(Int32.Parse("11", System.Globalization.NumberStyles.HexNumber)));//transaction id //3 bytes for report form request all sendByteArray.Add((byte)(Int32.Parse("FF", System.Globalization.NumberStyles.HexNumber)));//report form sendByteArray.Add((byte)(Int32.Parse("FF", System.Globalization.NumberStyles.HexNumber)));//report form sendByteArray.Add((byte)(Int32.Parse("1D", System.Globalization.NumberStyles.HexNumber)));//report form //END //search form by logid Indicates that the search includes Search Fields S4 (Log ID) and S5 (Max Result) sendByteArray.Add((byte)(Int32.Parse("30", System.Globalization.NumberStyles.HexNumber))); #endregion #region Parse LogId Add to byte array foreach (char c in UintvarLogId) { chunk += c; if (chunk.Length == 2) { sendByteArray.Add((byte)(Int32.Parse(chunk, System.Globalization.NumberStyles.HexNumber))); chunk = ""; } } #endregion #region Max Result sendByteArray.Add((byte)(Int32.Parse("01", System.Globalization.NumberStyles.HexNumber))); //Max Result = 1 #endregion Byte[] sendBytes = sendByteArray.ToArray(); //send bytearray to radio id SafeMobileLib.Utils.WriteLine($"Send request to Tallysman radio id: {radioID}, log id: {item}", ConsoleColor.DarkMagenta); #endregion sendTallysmanCommand(sendBytes, radioID); } } } public void sendTallysmanCommand(Byte[] sendBytes, long radioID) { udpClient.Client.SendTo(sendBytes, new IPEndPoint(IPAddress.Parse(Utils.ID2IP("12", radioID.ToString())), Port)); Thread.Sleep(1000); IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); try { #region send request // Blocks until a message returns on this socket from a remote host. //SafeMobileLib.Utils.WriteLine("Before read "); Byte[] receivedBytes = udpClient.Receive(ref remoteIpEndPoint); //SafeMobileLib.Utils.WriteLine("After read "); char[] separator = { '.' }; string[] su = remoteIpEndPoint.Address.ToString().Split(separator); uint radioID1 = (Convert.ToUInt32(su[1])) * 256 * 256 + (Convert.ToUInt32(su[2])) * 256 + Convert.ToUInt32(su[3]); string suid = radioID.ToString(); #endregion #region process response //SafeMobileLib.Utils.WriteLine("TEST TALLYSMAN Thread received data from radio " + radioID1); //Utils.printBytesArray(receivedBytes); Byte toreturn = TallysmanReceiveThread.ProcessPacket2(receivedBytes, receivedBytes.Length, radioID.ToString().Trim()); //put information on message bus //string sequenceID = ""; //Byte[] toSendMulticast = Utils.createMulticastMessage(233, suid, receivedBytes, out sequenceID); //udpMulticastBusConnection.Send(toSendMulticast, toSendMulticast.Length); SafeMobileLib.Utils.WriteLine("TallysmanReceiveThread successfully sent data to message bus"); Thread.Sleep(100); #endregion } catch (Exception ex) { SafeMobileLib.Utils.WriteLine("Exception: " + ex.ToString()); } } public void RequestTallysmanLogsBundle(List missing) { var RadioList = missing.Select(t => t.RadioID).Distinct().ToList(); foreach (var radioID in RadioList) { string UintvarLogIdBundle = ""; List byteArray = new List(); string chunk = ""; var terminalList = missing.Where(t => t.RadioID == radioID).Select(t => t.LogId).ToList(); foreach (var item in terminalList) { UintvarLogIdBundle += GetTallysmanUintvarEncoding((int)item); } //prepare bundle message #region send request to tallysman one by one List sendByteArray = new List(); #region Message Header sendByteArray.Add((byte)(Int32.Parse("FA", System.Globalization.NumberStyles.HexNumber)));//protocol sendByteArray.Add((byte)(Int32.Parse("08", System.Globalization.NumberStyles.HexNumber)));//version #endregion #region Message Length int messageTypeLength = 1; // 0x04 int transactionIdLength = 1; // 0x11 int reportFormLength = 3; // 0xFF 0xFF 0x1D int searchFormLength = 2; // 0x84 0x00 Indicates that the search includes Search Fields S10 int nrOfLogIDs = terminalList.Count; string uintvarNrOfLogIDs = GetTallysmanUintvarEncoding(nrOfLogIDs); int messageLength = messageTypeLength + transactionIdLength + reportFormLength + searchFormLength + UintvarLogIdBundle.Length / 2 + uintvarNrOfLogIDs.Length / 2; string uintvarMessageLenght = GetTallysmanUintvarEncoding(messageLength); foreach (char c in uintvarMessageLenght) { chunk += c; if (chunk.Length == 2) { sendByteArray.Add((byte)(Int32.Parse(chunk, System.Globalization.NumberStyles.HexNumber))); chunk = ""; } } #endregion #region Message Static elements sendByteArray.Add((byte)(Int32.Parse("04", System.Globalization.NumberStyles.HexNumber)));//message type sendByteArray.Add((byte)(Int32.Parse("11", System.Globalization.NumberStyles.HexNumber)));//transaction id //3 bytes for report form request all sendByteArray.Add((byte)(Int32.Parse("FF", System.Globalization.NumberStyles.HexNumber)));//report form sendByteArray.Add((byte)(Int32.Parse("FF", System.Globalization.NumberStyles.HexNumber)));//report form sendByteArray.Add((byte)(Int32.Parse("1D", System.Globalization.NumberStyles.HexNumber)));//report form //END sendByteArray.Add((byte)(Int32.Parse("80", System.Globalization.NumberStyles.HexNumber)));//search form by logid sendByteArray.Add((byte)(Int32.Parse("08", System.Globalization.NumberStyles.HexNumber)));//Indicates that the search includes Search Fields S10 #endregion #region Parse uintvarNrOfLogIDs foreach (char c in uintvarNrOfLogIDs) { chunk += c; if (chunk.Length == 2) { sendByteArray.Add((byte)(Int32.Parse(chunk, System.Globalization.NumberStyles.HexNumber))); chunk = ""; } } #endregion #region Parse LogId Add to byte array foreach (char c in UintvarLogIdBundle) { chunk += c; if (chunk.Length == 2) { sendByteArray.Add((byte)(Int32.Parse(chunk, System.Globalization.NumberStyles.HexNumber))); chunk = ""; } } #endregion Byte[] sendBytes = sendByteArray.ToArray(); //send bytearray to radio id SafeMobileLib.Utils.WriteLine($"Send bundle request to Tallysman radio id: {radioID}", ConsoleColor.DarkMagenta); udpClient.Client.SendTo(sendBytes, new IPEndPoint(IPAddress.Parse(Utils.ID2IP("12", radioID.ToString())), Port)); #endregion } } } }