SafeNet/MotoRepeater_SOC/LocationThread.cs
2021-02-24 13:50:23 +02:00

1010 lines
48 KiB
C#

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 SafeNetLib;
using SN_Server.ServerMSGS;
namespace MotoRepeater_SOC
{
class LocationThread
{
public int port;
//public MotoTRBOGW parent;
public static Hashtable ht_location_hash;
public static Hashtable ht_pendingMsg;
private byte[] data = new byte[1024];
private static UdpClient udpClient;
private Int32 reqID_send = 0x01;
private string reqID;
private Int32 reqID_recv;
// -------------------------------------------------------------------
// Main
// -------------------------------------------------------------------
public LocationThread(int _port)
{
port = _port;
Random rnd1 = new Random();
reqID_send = (byte)rnd1.Next(0xffffff);
}
private bool start_read = true;
private IAsyncResult currentAsyncResult;
private bool startAsyncRead()
{
EndPoint reponseEndPoint = new IPEndPoint(0, 0);
try
{
if (udpClient == null)
{
udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, port));
Console.WriteLine("ReBinding location udpClient port:" + port);
}
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
Thread.Sleep(100);
// Blocks until a message returns on this socket from a remote host.
currentAsyncResult = udpClient.Client.BeginReceiveFrom(data, 0, data.Length,
SocketFlags.None, ref reponseEndPoint,
new AsyncCallback(AsyncRead),
(object)this);
Thread.Sleep(300);
Console.WriteLine("AsyncRead started for Location thread on port:" + port);
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "startAsyncRead(): exception " + ex.ToString());
}
return true;
}
public void HandleConnection()
{
Utils.ConsWrite(DebugMSG_Type.GPS, "GPS listen started on port:" + port);
ht_location_hash = new Hashtable();
ht_pendingMsg = new Hashtable();
//TestPacket();
//return;
start_read = false;
Console.WriteLine("step 1");
startAsyncRead();
Console.WriteLine("step 2");
DateTime lastHashVerify = DateTime.Now;
while (true)
{
try
{
MotoTRBOcmdMsg msg = SN_Queues.locationQueue.GetItem(100);
if (msg != null)
{
Console.WriteLine("Processing command");
Console.WriteLine("SN_Queues.locationQueue.Count:" + SN_Queues.locationQueue.Count);
ProcessCommand(msg); //this will update the m_seqID and m_time
ht_pendingMsg.Add(msg.m_seqID, msg);
start_read = true;
msg = null;
Console.WriteLine("Processing end");
}
//is now answer within 30 secconds resend
if(ht_pendingMsg.Count>0)
if ((DateTime.Now.Ticks - lastHashVerify.Ticks) > 30 * 1000 * 10000)
{
LOGS.LOG("Debug: LOCK1");
lock (ht_pendingMsg.SyncRoot)
{
try
{
Hashtable tmp = new Hashtable();
Utils.ConsWrite(DebugMSG_Type.GPS, "GPS answers check at :" + DateTime.Now);
foreach (DictionaryEntry de in ht_pendingMsg)
{
MotoTRBOcmdMsg m = (MotoTRBOcmdMsg)de.Value;
//if not send remove from pendingMsg and add back to location Queue
if (DateTime.Now.Ticks - m.m_time.Ticks > 180 * 1000 * 10000)
if (m.m_cmd == (int)MotoTRBOcmd.SET_REPORT_INTERVAL) //put back in queue ONLY LRRP set requests
{
LOGS.LOG("PUT back in ht_pendingMsg :" + m.m_suid);
Utils.ConsWrite(DebugMSG_Type.GPS, "PUT back in ht_pendingMsg :" + m.m_suid);
SN_Queues.locationQueue.PostItem(m);
}
else
tmp.Add(m.m_seqID, m);
else
tmp.Add(m.m_seqID, m);
}
ht_pendingMsg = tmp;
lastHashVerify = DateTime.Now;
}
catch (Exception e)
{
LOGS.LOG("Error: cannot reset pending messages HashTable"+e.ToString());
}
}//release lock
LOGS.LOG("Debug: UN-LOCK1");
}
if (start_read)
{
start_read = false;
startAsyncRead();
}
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "Erorr in HandleConnection");
Utils.ConsWrite(DebugMSG_Type.always, ex.ToString());
}
} // end while (true)
}
void AsyncRead(IAsyncResult result)
{
EndPoint remoteEndPoint = new IPEndPoint(0, 0);
try
{
if (udpClient == null)
{
Console.WriteLine("!!!!!! udpClient == null !!!!!!!!!");
start_read = true;
return;
}
int bytesRead = udpClient.Client.EndReceiveFrom(result, ref remoteEndPoint);
if (bytesRead > 1)
{
Console.WriteLine("\n--------------------");
Console.WriteLine("AsyncRead endded processing data!!!");
Console.WriteLine("GPS Received: " + Byte2String(data, 0, bytesRead));
start_read = true;
DecodePacket(data, (IPEndPoint)remoteEndPoint);
}
}
catch (System.ArgumentException ae)
{
Utils.ConsWrite(DebugMSG_Type.GPS, "AsyncRead !!!!!! result != currentAsyncResult !!!!!!!!!");
}
catch (ObjectDisposedException ode)
{
Utils.ConsWrite(DebugMSG_Type.GPS, "AsyncRead !!!!!! obj disposed !!!!!!!!!");
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "Error AsyncRead :/n" + ex.ToString());
}
finally
{
start_read = true;
}
}
public void DecodePacket(Byte[] data, IPEndPoint RemoteIpEndPoint)
{
LOGS.LOG("...............begin decode....................");
Console.WriteLine("...............................................");
Console.WriteLine("...............begin decode....................");
Console.WriteLine("...............................................");
int i = 0, pdata;
htCell_t cell = new htCell_t();
cell.lat = "";
cell.lng = "";
cell.di = "0";
cell.location_time = DateTime.MinValue;
cell.activity_time = DateTime.MinValue;
cell.triggered = false;
string suid;
if (RemoteIpEndPoint != null)
{
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]);
suid = radioID.ToString();
}
else
{
//LOGS.WriteLine("Unknown SUID !!");
suid = "101";
//return;
}
Console.WriteLine("-------- Decode Packet ------------ From: " + suid);
cell.suid = suid;
switch (data[0])
{
// -----------------------------------------------------------------------------------------------------------------------
case (byte)Document_Identifiers_ENUM.Triggered_Location_Stop_Answer_NoCDT:
case (byte)Document_Identifiers_ENUM.Triggered_Location_Answer_NoCDT:
pdata = (int)data[1];
string result="";
//Console.WriteLine("Length =" + pdata + "(0x" + pdata.ToString("X") + ")");
for (i = 2; i < data[1] + 2; i++)
{
switch (data[i])
{
case (byte)Common_Element_Tokens_ENUM.request_id:
//Console.WriteLine(Common_Element_Tokens_ENUM.request_id + ": " + Byte2String(data, i + 1, 5));
//Console.WriteLine(data[i + 5]);
byte[] bytes = { data[i + 5], data[i + 4], data[i + 3], data[i + 2] };
reqID = Byte2String(data, i + 1, 5);
reqID_recv = BitConverter.ToInt32(bytes, 0);
Console.WriteLine("Request ID:" + reqID);
LOGS.LOG("Request ID:" + reqID);
i += 5;
break;
case (byte)Report_Messages_Tokens_ENUM.result:
case (byte)Report_Messages_Tokens_ENUM.result2:
//Console.WriteLine("Result: " + Byte2String(data, i + 1, 1));
if (data[i + 1] != 0)
{
Utils.ConsWrite(DebugMSG_Type.GPS, "Error = " + ProcessError(data[i + 1]));
result = ProcessError(data[i + 1]);
}
//Console.WriteLine("OpaqueData: " + Byte2String(data, i + 2, data[1] - i));
i = data[1] + 1; // exit
break;
case (byte)Report_Messages_Tokens_ENUM.result1:
//Console.WriteLine("Result: OK");
result = "OK";
break;
/*
case (byte)Report_Messages_Tokens_ENUM.SU_IPv4:
string suid = ProcessSU_ID(data, i + 1).ToString();
cell.suid = suid;
i += 4;
//Console.Write("SUIDc: " + suid + " ### ");
break;
*/
}
}
//LOGS.LOG("Debug: LOCK3");
//remove message from pending
RemoveMSGfromPending(cell.suid, reqID_recv);
LOGS.LOG("Debug: UN-LOCK3");
if(data[0] == (byte)Document_Identifiers_ENUM.Triggered_Location_Stop_Answer_NoCDT)
LOGS.LOG( cell.suid + " Triggered_Location_Stop_Answer_NoCDT \t regID:" + reqID + " \t result:" + result);
else
LOGS.LOG( cell.suid + " Triggered_Location_Answer_NoCDT \t regID:" + reqID + " \t result:" + result);
break;
// -----------------------------------------------------------------------------------------------------------------------
case (byte)Document_Identifiers_ENUM.Triggered_Location_Report_NoCDT:
case (byte)Document_Identifiers_ENUM.Immediate_Location_Report_NoCDT:
{
if (data[0] == (byte)Document_Identifiers_ENUM.Triggered_Location_Report_NoCDT)
{
Console.WriteLine(Document_Identifiers_ENUM.Triggered_Location_Report_NoCDT);
LOGS.LOG(cell.suid + " Triggered_Location_Report_NoCDT ");
}
else
{
Console.WriteLine(Document_Identifiers_ENUM.Immediate_Location_Report_NoCDT);
LOGS.LOG(cell.suid + " Immediate_Location_Report_NoCDT ");
}
if (data[0] == (byte)Document_Identifiers_ENUM.Triggered_Location_Report_NoCDT)
{
cell.triggered = true;
}
else
{
//Utils.ConsWrite(DebugMSG_Type.DEV, "Got request id:" + cell.requestID);
}
pdata = (int)data[1];
Boolean parsingError = false;
byte parsErrorBYte = (byte)Result_Codes_ENUM.SYNTAX_ERROR;
DateTime gps_time = DateTime.MinValue;
for (i = 2; i < data[1] + 2; i++)
{
switch (data[i])
{
case (byte)Common_Element_Tokens_ENUM.request_id:
//Console.WriteLine(Common_Element_Tokens_ENUM.request_id + ": " + Byte2String(data, i + 1, 5));
//Console.WriteLine(data[i + 5]);
byte[] bytes = { data[i + 5], data[i + 4], data[i + 3], data[i + 2] };
string reqID1 = Byte2String(data, i + 1, 5);
reqID_recv = BitConverter.ToInt32(bytes, 0);
Console.WriteLine("Request ID:" + reqID1);
LOGS.LOG("Request ID:" + reqID1);
i += 5;
break;
case (byte)Report_Messages_Tokens_ENUM.point_2d:
cell.lat = ProcessLat(data, i + 1, 4).ToString();
cell.lng = ProcessLng(data, i + 1 + 4, 4).ToString();
cell.d_lat = ProcessLat(data, i + 1, 4);
cell.d_lng = ProcessLng(data, i + 1 + 4, 4);
if (gps_time == DateTime.MinValue)
cell.location_time = DateTime.Now.ToUniversalTime();
/*
Console.WriteLine("Point_2d: " + data[i].ToString("X"));
Console.WriteLine("Lat: " + Byte2String(data, i + 1, 4) + " =" + cell.lat);
Console.WriteLine("Lng: " + Byte2String(data, i + 1 + 4, 4) + " =" + cell.lng);
*/
i += 8;
break;
case (byte)Report_Messages_Tokens_ENUM.point_3d:
Console.WriteLine("### Point 3d ###");
cell.lat = ProcessLat(data, i + 1, 4).ToString();
cell.lng = ProcessLng(data, i + 1 + 4, 4).ToString();
cell.d_lat = ProcessLat(data, i + 1, 4);
cell.d_lng = ProcessLng(data, i + 1 + 4, 4);
if (gps_time == DateTime.MinValue)
cell.location_time = DateTime.Now.ToUniversalTime();
i += 11;
break;
case (byte)Report_Messages_Tokens_ENUM.circle_2d:
cell.lat = ProcessLat(data, i + 1, 4).ToString();
cell.lng = ProcessLng(data, i + 1 + 4, 4).ToString();
cell.d_lat = ProcessLat(data, i + 1, 4);
cell.d_lng = ProcessLng(data, i + 1 + 4, 4);
if (gps_time == DateTime.MinValue)
cell.location_time = DateTime.Now.ToUniversalTime();
cell.radius = ProcessUFloat2B(data, i + 1 + 8);
/*
Console.WriteLine("Circle_2d: " + data[i].ToString("X"));
Console.WriteLine("Lat: " + Byte2String(data, i + 1, 4) + " =" + cell.lat);
Console.WriteLine("Lng: " + Byte2String(data, i + 1 + 4, 4) + " =" + cell.lng);
Console.WriteLine("Rad: " + Byte2String(data, i + 1 + 8, 2) + " =" + cell.radius);
*/
i += 10;
break;
case (byte)Report_Messages_Tokens_ENUM.circle_3d:
case (byte)Report_Messages_Tokens_ENUM.circle_3d1:
cell.lat = ProcessLat(data, i + 1, 4).ToString();
cell.lng = ProcessLng(data, i + 1 + 4, 4).ToString();
cell.d_lat = ProcessLat(data, i + 1, 4);
cell.d_lng = ProcessLng(data, i + 1 + 4, 4);
if (gps_time == DateTime.MinValue)
cell.location_time = DateTime.Now.ToUniversalTime();
cell.radius = ProcessUFloat2B(data, i + 1 + 8);
/*
Console.WriteLine("Circle_3d: " + data[i].ToString("X"));
Console.WriteLine("Lat: " + Byte2String(data, i + 1, 4) + " =" + cell.lat);
Console.WriteLine("Lng: " + Byte2String(data, i + 1 + 4, 4) + " =" + cell.lng);
Console.WriteLine("Rad: " + Byte2String(data, i + 1 + 8, 2) + " =" + cell.radius);
Console.WriteLine("Alt: " + Byte2String(data, i + 1 + 10, 2));
Console.WriteLine("Ala: " + Byte2String(data, i + 1 + 12, 2));
*/
if (!cell.triggered) Console.WriteLine("Lat: " + Byte2String(data, i + 1, 4) + " =" + cell.lat);
if (!cell.triggered) Console.WriteLine("Lng: " + Byte2String(data, i + 1 + 4, 4) + " =" + cell.lng);
i += 14;
break;
case (byte)Report_Messages_Tokens_ENUM.speed_vrt:
//Console.WriteLine("Speed VRT: " + Byte2String(data, i + 1, 2));
i += 2;
break;
case (byte)Report_Messages_Tokens_ENUM.speed_hor:
cell.spd = (ProcessUFloat2B(data, i + 1) * 3.6).ToString();
LOGS.LOG("GOT unit<" + cell.suid + "> speed:" + cell.spd);
//Console.WriteLine(Report_Messages_Tokens_ENUM.speed_hor + ": " + Byte2String(data, i + 1, 2) + " =" + cell.spd);
i += 2;
break;
case (byte)Report_Messages_Tokens_ENUM.info_time:
case (byte)Report_Messages_Tokens_ENUM.info_time1:
gps_time = ProcessTime(data, i + 1, 5);
//Console.WriteLine(Report_Messages_Tokens_ENUM.info_time + ": " + Byte2String(data, i + 1, 5) + " =" + gps_time);
i += 5;
Console.WriteLine("Time from unit<"+suid+"> :" + gps_time.ToString());
LOGS.LOG("Time from unit<" + suid + "> :" + gps_time.ToString());
break;
/*
case (byte)Report_Messages_Tokens_ENUM.SU_IPv4:
string suid = ProcessSU_ID(data, i + 1).ToString();
cell.suid = suid;
//Utils.ConsWrite(DebugMSG_Type.GPS, "SUID: " + suid + " ### ");
if (!cell.triggered) Utils.ConsWrite(DebugMSG_Type.DEV, "SUID: " + suid + " ### ");
i += 4;
break;
*/
// RESULTS
case (byte)Report_Messages_Tokens_ENUM.result:
case (byte)Report_Messages_Tokens_ENUM.result2:
//Console.WriteLine("Result: " + Byte2String(data, i + 1, 1));
if (data[i + 1] != 0)
{
parsErrorBYte = data[i + 1];
Utils.ConsWrite(DebugMSG_Type.GPS, "Error = " + ProcessError(data[i + 1]));
LOGS.LOG(cell.suid + " Error = " + ProcessError(data[i + 1]));
if (!cell.triggered) Utils.ConsWrite(DebugMSG_Type.DEV, "Error = " + ProcessError(data[i + 1]));
parsingError = true;
}
//Console.WriteLine("OpaqueData: " + Byte2String(data, i + 2, data[1] - i));
i = data[1] + 1; // exit
break;
case (byte)Report_Messages_Tokens_ENUM.result1:
//Console.WriteLine("Result: OK");
break;
case (byte)Report_Messages_Tokens_ENUM.direction_hor:
i += 1;
break;
default:
Utils.ConsWrite(DebugMSG_Type.GPS, "Unknown: 0x" + data[i].ToString("X"));
break;
}
}
if (gps_time == DateTime.MinValue)
Utils.ConsWrite(DebugMSG_Type.GPS, "GPS gps_time == DateTime.MinValue");
else if (!parsingError ||
((parsErrorBYte == (byte)Result_Codes_ENUM.QUERY_INFO_NOT_ATTAINABLE) && (!cell.triggered)))
{
//Utils.ConsWrite(DebugMSG_Type.DEV, "Got location from" + cell.suid);
cell.location_time = DateTime.UtcNow;
try
{
if (cell.triggered)//if location is "triggered" then proceed as usual
{
//Utils.ConsWrite(DebugMSG_Type.DEV, "Got triggered location from" + cell.suid);
if (ht_location_hash.ContainsKey(cell.suid))
{
if (gps_time != ((DateTime)ht_location_hash[cell.suid]))
{
//Console.WriteLine("SUID:" + cell.suid + "GPS time != last GPS time... Adding it to DB!!!");
cell.location_time = gps_time;
SN_Queues.DBQueueLocation.PostItem(cell);
ht_location_hash.Remove(cell.suid);
ht_location_hash.Add(cell.suid, gps_time);
LOGS.LOG( cell.suid+" Trig GPS<lat:" + cell.lat + "><lng:" + cell.lng + ">");
}
else
{
Utils.ConsWrite(DebugMSG_Type.GPS, "SUID:" + cell.suid + " GPS time already in DB ...time:" + gps_time);
}
}//if (location_hash.ContainsKey(cell.suid))
else
{
Utils.ConsWrite(DebugMSG_Type.GPS, "SUID:" + cell.suid + " First GPS adding it to DB!!!");
cell.location_time = gps_time;
SN_Queues.DBQueueLocation.PostItem(cell);
ht_location_hash.Add(cell.suid, gps_time);
LOGS.LOG( cell.suid + " Trig GPS<lat:" + cell.lat + "><lng:" + cell.lng + ">");
}
}//if (cell.triggered)
else
{
Utils.ConsWrite(DebugMSG_Type.DEV, "Got poll location from:" + cell.suid);
Utils.ConsWrite(DebugMSG_Type.DEV, "int requestID:" + reqID_recv);
try
{
lock (SM_GPS.ht_POLL_List.SyncRoot)
{
foreach (DictionaryEntry item in SM_GPS.ht_POLL_List)
{
if (((SM_POLLmsg)item.Value).suid == cell.suid)
{
((SM_POLLmsg)item.Value).response = cell.location_time;
((SM_POLLmsg)item.Value).lat = cell.lat;
((SM_POLLmsg)item.Value).lng = cell.lng;
((SM_POLLmsg)item.Value).speed = cell.spd;
//SN_Queues.DBQueueLocation.PostItem(cell);
int suDBid = MotoRepeater_GW.unitList.GetDBid(cell.suid);
if (suDBid != 0)
{
GPS gps =QueueManagerThread.converCell2GPS(cell, suDBid);
((SM_POLLmsg)item.Value).gps = gps;
SM_GPS.recvPOLLQueue.PostItem((SM_POLLmsg)item.Value);
LOGS.LOG(cell.suid + "Poll GPS<lat:" + cell.lat + "><lng:" + cell.lng + ">");
break;
}
}
}
}
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "ERROR processing poll msg suid:" + cell.suid);
}
}
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, ex.ToString());
}
}
}
break;
// -----------------------------------------------------------------------------------------------------------------------
default:
Utils.ConsWrite(DebugMSG_Type.GPS, "UNDEFINED 0x" + data[0].ToString("X"));
break;
}
LOGS.LOG("...............end decode....................");
Console.WriteLine(".............................................");
Console.WriteLine("...............end decode....................");
Console.WriteLine(".............................................");
}
void ProcessCommand(MotoTRBOcmdMsg p_msg)
{
try
{
reqID_send++;
if (reqID_send == Int32.MaxValue)
reqID_send = 1;
int reqID_send_assigned = 0;
/*
Random rnd1 = new Random();
if (!Int32.TryParse(p_msg.m_suid, out reqID_send_assigned))
{
reqID_send_assigned = reqID_send;
}
*/
reqID_send_assigned = reqID_send;
p_msg.m_seqID = reqID_send_assigned;
p_msg.m_time = DateTime.Now;
if (p_msg.m_cmd == (byte)MotoTRBOcmd.SET_REPORT_INTERVAL)
{
//send stop trigger
//SendTriggeredLocationSTOP(p_msg.m_suid, reqID_send_assigned);
//Thread.Sleep(1000);
//send trigger
SendTriggeredLocationRequest(p_msg.m_suid, Convert.ToUInt32(p_msg.m_payload), reqID_send_assigned);
}
if (p_msg.m_cmd == (byte)MotoTRBOcmd.SEND_POLL)
{
SendPollLocationRequest(p_msg.m_suid, reqID_send);
Utils.ConsWrite(DebugMSG_Type.GPS, "Poll request sent for unit:" + p_msg.m_suid);
//Utils.ConsWrite(DebugMSG_Type.DEV, "Poll request sent for unit:" + p_msg.m_suid);
lock (SM_GPS.ht_POLL_List.SyncRoot)
{
foreach (DictionaryEntry item in SM_GPS.ht_POLL_List)
{
try
{
if (((SM_POLLmsg)item.Value).suid == p_msg.m_suid && ((SM_POLLmsg)item.Value).DBid.ToString() == p_msg.m_payload)
{
((SM_POLLmsg)item.Value).sent = DateTime.Now.ToUniversalTime();
((SM_POLLmsg)item.Value).requestID = reqID_send;
Utils.ConsWrite(DebugMSG_Type.DEV, "Poll request found in MotoTRBOGW.ht_POLL_List for unit:" + p_msg.m_suid);
Utils.ConsWrite(DebugMSG_Type.DEV, "reqID_send:" + reqID_send);
SM_GPS.sentPOLLQueue.PostItem((SM_POLLmsg)item.Value);
break;
}
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "ERROR in foreach (DictionaryEntry item in SN_Queues.ht_POLL_List):");
Utils.ConsWrite(DebugMSG_Type.always, ex.Message);
}
}
}
}
}
catch (Exception e)
{
Utils.ConsWrite(DebugMSG_Type.always, "Could not send Location Request to unit");
Utils.ConsWrite(DebugMSG_Type.always, e.Message);
}
}
public void SendTriggeredLocationRequest(string SUID, uint p_reportSec,Int32 reqID)
{
//get reqid bytes
byte[] intBytes = BitConverter.GetBytes(reqID);
if (BitConverter.IsLittleEndian)
Array.Reverse(intBytes);
Byte[] sendBytes = { (byte)Document_Identifiers_ENUM.Triggered_Location_Request_NoCDT,
0x0B, // length in Bytes
(byte)Common_Element_Tokens_ENUM.request_id,
0x04, intBytes[0], intBytes[1], intBytes[2], intBytes[3],
0x51,
(byte)Query_Request_Messages_Tokens_ENUM.request_speed_hor,
(byte)Query_Request_Messages_Tokens_ENUM.periodic_trigger,
(byte)Query_Request_Messages_Tokens_ENUM.interval,
0x00, 0x00 //(byte)report_time// in seconds
};
LOGS.LOG(SUID + " Triggered_Location_Request_NoCDT \t reqID:" + Byte2String(sendBytes, 3, 5) + " \t report: " + p_reportSec);
try
{
//UdpClient udpClient1 = new UdpClient(MotoTRBO_GW.cfg.locPort);
//udpClient.Connect(MotoTRBO_GW.cfg.ctrlIP, MotoTRBO_GW.cfg.locPort);
int report_time = (int)p_reportSec;
// Sends a message to the host to which you have connected.
if (report_time < 0x80)
sendBytes[12] = (byte)report_time;
else
{
sendBytes[1] += 1; // adjust length
int process = report_time; // MSB
process >>= 7;
process &= 0x007F;
process |= 0x0080;
sendBytes[12] = (byte)process;
sendBytes[13] = (byte)(report_time & 0x007F); //LSB
}
if (udpClient == null)
{
udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, port));
Console.WriteLine("ReBinding location udpClient port:" + port);
}
Print(sendBytes, sendBytes.Length, false);
udpClient.Send(sendBytes, sendBytes.Length, new IPEndPoint(IPAddress.Parse((new RadioID2IP("12", SUID)).GetIP()), port));
Utils.ConsWrite(DebugMSG_Type.GPS, "Triggered location request sent to radio ID " + SUID + " with IP" + IPAddress.Parse((new RadioID2IP("12", SUID)).GetIP()));
udpClient.Close();
udpClient = null;
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "Location Thread SendTriggeredLocationRequest exception: " + ex.ToString());
}
}
public void SendPollLocationRequest(string SUID, Int32 reqID)
{
//get reqid bytes
byte[] intBytes = BitConverter.GetBytes(reqID);
if (BitConverter.IsLittleEndian)
Array.Reverse(intBytes);
Byte[] sendBytes = { (byte)Document_Identifiers_ENUM.Immediate_Location_Request_NoCDT,
0x08, // length in Bytes
(byte)Common_Element_Tokens_ENUM.request_id,
0x04, intBytes[0], intBytes[1], intBytes[2], intBytes[3],
0x51,
(byte)Query_Request_Messages_Tokens_ENUM.request_speed_hor
};
try
{
if (udpClient == null)
{
udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, port));
Console.WriteLine("ReBinding location udpClient port:" + port);
}
//UdpClient udpClient = new UdpClient(MotoTRBO_GW.cfg.locPort);
//udpClient.Connect(MotoTRBO_GW.cfg.ctrlIP, MotoTRBO_GW.cfg.locPort);
//Print(sendBytes, sendBytes.Length, false);
udpClient.Send(sendBytes, sendBytes.Length, new IPEndPoint(IPAddress.Parse((new RadioID2IP("12", SUID)).GetIP()), port));
//udpClient.Send(sendBytes, new IPEndPoint(IPAddress.Parse(MotoTRBO_GW.cfg.ctrlIP), MotoTRBO_GW.cfg.locPort));
Utils.ConsWrite(DebugMSG_Type.GPS, "One time location request sent to radio ID " + SUID + " reqID:" + Byte2String(sendBytes, 3, 5));
LOGS.LOG("Polled ID " + SUID);
udpClient.Close();
udpClient = null;
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "Location Thread SendTriggeredLocationRequest exception: " + ex.ToString());
}
}
public void SendTriggeredLocationSTOP(string SUID, Int32 reqID)
{
//get reqid bytes
byte[] intBytes = BitConverter.GetBytes(reqID);
if (BitConverter.IsLittleEndian)
Array.Reverse(intBytes);
byte[] arr_radioID = Utils.ID2ByteARR("12", SUID);
Byte[] sendBytes = { (byte)Document_Identifiers_ENUM.Triggered_Location_Stop_Request_NoCDT,
0x0B, // length in Bytes
(byte)Common_Element_Tokens_ENUM.request_id,
0x04, intBytes[0], intBytes[1], intBytes[2], intBytes[3]
};
LOGS.LOG(SUID + " Triggered_Location_Stop_Request_NoCDT \t reqID:" + Byte2String(sendBytes, 3, 5));
try
{
if (udpClient == null)
{
udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, port));
Console.WriteLine("ReBinding location udpClient port:" + port);
}
//UdpClient udpClient = new UdpClient(port);
//udpClient.Connect(MotoTRBO_GW.cfg.ctrlIP, MotoTRBO_GW.cfg.locPort);
//Print(sendBytes, sendBytes.Length, false);
udpClient.Send(sendBytes, sendBytes.Length, new IPEndPoint(IPAddress.Parse((new RadioID2IP("12", SUID)).GetIP()), port));
//udpClient.Send(sendBytes, new IPEndPoint(IPAddress.Parse(MotoTRBO_GW.cfg.ctrlIP), MotoTRBO_GW.cfg.locPort));
Utils.ConsWrite(DebugMSG_Type.GPS, "SendTriggeredLocationSTOP" + SUID);
LOGS.LOG("SendTriggeredLocationSTOP " + SUID + " reqID:" + Byte2String(sendBytes, 3, 5));
udpClient.Close();
udpClient = null;
}
catch (Exception ex)
{
Utils.ConsWrite(DebugMSG_Type.always, "Location Thread SendTriggeredLocationSTOP exception: " + ex.ToString());
}
}
// -------------------------------------------------------------------
// Aux functions
// -------------------------------------------------------------------
static public string Byte2String(byte[] data)
{
string sdata = "";
int i;
for (i = 0; i < data.Length; i++)
{
int ii;
ii = (int)data[i];
sdata += "0x" + ii.ToString("X") + " ";
}
return sdata;
}
static public string Byte2String(byte[] data, int startIndex, int len)
{
string sdata = "";
int i;
if (startIndex > data.Length)
return "";
for (i = startIndex; i < startIndex + len && i < data.Length; i++)
{
int ii;
ii = (int)data[i];
sdata += "0x" + ii.ToString("X") + " ";
}
return sdata;
}
static string ProcessError(Byte err)
{
switch (err)
{
case (byte)Result_Codes_ENUM.SUCCESS: return "" + Result_Codes_ENUM.SUCCESS;
case (byte)Result_Codes_ENUM.UNSUPPORTED_VERSION: return "" + Result_Codes_ENUM.UNSUPPORTED_VERSION;
case (byte)Result_Codes_ENUM.SYNTAX_ERROR: return "" + Result_Codes_ENUM.SYNTAX_ERROR;
case (byte)Result_Codes_ENUM.PROTOCOL_ELEMENT_NOT_SUPPORTED: return "" + Result_Codes_ENUM.PROTOCOL_ELEMENT_NOT_SUPPORTED;
case (byte)Result_Codes_ENUM.PROTOCOL_ELEMENT_VALUE_OUT_OF_RANGE: return "" + Result_Codes_ENUM.PROTOCOL_ELEMENT_VALUE_OUT_OF_RANGE;
case (byte)Result_Codes_ENUM.QUERY_INFO_NOT_ATTAINABLE: return "" + Result_Codes_ENUM.QUERY_INFO_NOT_ATTAINABLE;
case (byte)Result_Codes_ENUM.NO_SUCH_REQUEST: return "" + Result_Codes_ENUM.NO_SUCH_REQUEST;
case (byte)Result_Codes_ENUM.DUPLICATE_REQUEST_ID: return "" + Result_Codes_ENUM.DUPLICATE_REQUEST_ID;
}
return "Unknown err";
}
static public double ProcessUFloat2B(Byte[] data, int startIndex)
{
int aux = data[startIndex];
aux &= 0xff;
int int_part = 0;
int i=0;
// get the int part
while ((aux & 0x80) != 0)
{
//Console.Write("<" + aux.ToString("X") + ">");
int_part |= (aux ^ 0x80);
int_part <<= 7;
i++;
aux = data[startIndex+i];
aux &= 0xff;
//Console.Write("[" + int_part.ToString("X") + "]");
}
//Console.Write("<" + aux.ToString("X") + ">");
int_part |= aux;
//Console.Write("[" + int_part.ToString("X") + "]");
// ignore the float part
i++;
while ((data[startIndex + i] & 0x80) != 0)
{
//Console.Write("<" + data[startIndex + i] + ">");
i++;
}
return (double)int_part;
}
static DateTime ProcessTime(Byte[] data, int startIndex, int len)
{
// (yyyy*2^26) + (MM*2^22) + (DD*2^17) + (hh*2^12) + (mm*2^6) + ss
Byte B1 = data[startIndex];
Byte B2 = data[startIndex + 1];
Byte B3 = data[startIndex + 2];
Byte B4 = data[startIndex + 3];
Byte B5 = data[startIndex + 4];
int hh, mm, ss, YY, MM, DD;
ss = B5 & 0x3F; // remove first 2b
mm = B4 & 0x0F;
mm <<= 2;
mm |= ((B5 >> 6) & 0x03);
hh = B3 & 0x01;
hh <<= 4;
hh |= ((B4 & 0xf0) >> 4);
DD = B3 & 0x3E;
DD >>= 1;
MM = B2 & 0x03;
MM <<= 2;
MM |= ((B3 >> 6) & 0x03);
YY = B1;
YY <<= 6;
YY |= ((B2 >> 2) & 0x3F);
//Console.WriteLine("YY=" + YY.ToString("X"));
//Console.WriteLine("MM=" + MM.ToString("X"));
//Console.WriteLine("DD=" + DD.ToString("X"));
//Console.WriteLine("hh=" + hh.ToString("X"));
//Console.WriteLine("mm=" + mm.ToString("X"));
//Console.WriteLine("ss=" + ss.ToString("X"));
//Utils.ConsWrite(DebugMSG_Type.GPS, "GPSTime : " + YY + "/" + MM + "/" + DD + " " + hh + ":" + mm + ":" + ss);
return new DateTime(YY, MM, DD, hh, mm, ss, DateTimeKind.Utc);
}
static double ProcessLat(Byte[] data, int startIndex, int len)
{
bool sign = false;
if ((data[startIndex] & 0x80) != 0)
{
sign = true;
}
ulong l = (ulong)data[startIndex];
if (sign)
l ^= 0x80; // remove the sign
l <<= 8;
l |= (ulong)data[startIndex + 1];
l <<= 8;
l |= (ulong)data[startIndex + 2];
l <<= 8;
l |= (ulong)data[startIndex + 3];
//Console.WriteLine("lat ulong=0x" + l.ToString("X"));
double ld = (double)l;
ld *= 90;
ld /= 1024;
ld /= 1024;
ld /= 1024;
ld /= 2;
if (sign)
ld *= -1;
return ld;
}
static double ProcessLng(Byte[] data, int startIndex, int len)
{
bool sign = false;
if ((data[startIndex] & 0x80) != 0)
{
sign = true;
}
//Console.WriteLine("data[]=" + data[startIndex].ToString("X") + " sign=" + sign);
ulong l = (ulong)data[startIndex];
if (sign)
l ^= 0x80; // remove the sign
l <<= 8;
l |= (ulong)data[startIndex + 1];
l <<= 8;
l |= (ulong)data[startIndex + 2];
l <<= 8;
l |= (ulong)data[startIndex + 3];
//Console.WriteLine("lng ulong=0x" + l.ToString("X"));
double ld = (double)l;
ld *= 360;
ld /= 1024;
ld /= 1024;
ld /= 1024;
ld /= 4;
if (sign)
{
ld = 180 - ld;
ld *= -1;
}
return ld;
}
private int ProcessSU_ID(Byte[] data, int startIndex)
{
Byte B1 = data[startIndex];
Byte B2 = data[startIndex + 1];
Byte B3 = data[startIndex + 2];
Byte B4 = data[startIndex + 3];
int radioID = B4 + B3 * 256 + B2 * 256 * 256;
return radioID;
}
private void RemoveMSGfromPending(string suid, int reqID_recv)
{
lock (ht_pendingMsg.SyncRoot)
{
try
{
if (ht_pendingMsg.ContainsKey(reqID_recv))
{
//LOGS.LOG(MotoTRBO_GW.cfg.gw_id + cell.suid + " removing from pending \t regID:" + reqID);
ht_pendingMsg.Remove(reqID_recv);
LOGS.LOG("REMOVING ht_pendingMsg :" + suid);
Utils.ConsWrite(DebugMSG_Type.GPS, "REMOVING ht_pendingMsg:" + suid);
}
}
catch (Exception e)
{
LOGS.LOG("Error: cannot delete pending messages HashTable" + e.ToString());
}
}
}
private static void Print(byte[] data, int length, bool inOut)
{
//Console.Clear();
Console.WriteLine("--------------------------------------------------------------------------- " + length);
Console.Write("Data (" + ((inOut) ? "RECEIVED" : "SENT") + "): ");
for (int i = 0; i < length; i++)
Console.Write(" 0x" + data[i].ToString("X2"));
Console.WriteLine("");
Console.WriteLine("--------------------------------------------------------------------------- ");
}
}
}