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"); } 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"); } }//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"); 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("--------------------------------------------------------------------------- "); } } }