SafeDispatch/MotoTrbo_GW/TallysmanSendThread.cs
2024-02-22 18:43:59 +02:00

571 lines
28 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}
}
}