SafeDispatch/MotoTrbo_GW/TallysmanSendThread.cs

571 lines
28 KiB
C#
Raw Normal View History

2024-02-22 16:43:59 +00:00
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<byte> myByteArray = new List<byte>();
////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<byte> myByteArray = new List<byte>();
////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 -> Ive put a random int, I dont know its 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 -> Ive put a random int, I dont know its 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 -> Ive put a random int, I dont know its 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<TallysmanLostLog> logIDS = null;
private void Check4MissingIds(Object state)
{
logIDS = vehiclesManager.getGetTallysmanLogs(Main.TallysmanRequestInterval);
//3.8 Log Retrieval Request (0x04)
RequestTallysmanLogsOneByOne(GetTallysmanMissingLogIDLastDay(logIDS));
}
public List<TallysmanLostLog> GetTallysmanMissingLogIDLastDay(List<TallysmanLostLog> LogIds)
{
//List<TallysmanLostLog> LogIds = new List<TallysmanLostLog>();
//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<TallysmanLostLog> MissingLogID = new List<TallysmanLostLog>();
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<TallysmanLostLog> missing)
{
var RadioList = missing.Select(t => t.RadioID).Distinct().ToList();
foreach (var radioID in RadioList)
{
string UintvarLogId = "";
List<byte> byteArray = new List<byte>();
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<byte> sendByteArray = new List<byte>();
#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<TallysmanLostLog> missing)
{
var RadioList = missing.Select(t => t.RadioID).Distinct().ToList();
foreach (var radioID in RadioList)
{
string UintvarLogIdBundle = "";
List<byte> byteArray = new List<byte>();
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<byte> sendByteArray = new List<byte>();
#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
}
}
}
}