using SafeMobileLib; using SDRGatewayService.Enums; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SDRGatewayService { class SDR { public static bool DEBUG = false; private bool running = false; private TcpClient tcpClient = null; private Thread listenThread = null; private NetworkStream stream = null; private Int64 ISSI; private String pass; private string IP; private int port; public static int SMSprotocolID = 130; private bool isStoreAndForward = true; private System.Threading.Timer tCheckConnection; private DateTime lastEntry; public static object dictionaryLock = new object(); public static Dictionary radioIdTolastPositionATMessageDictionary = new Dictionary(); public static Dictionary RadioIdToLastPosDictionary = new Dictionary(); public static object calloutUUIDLock = new object(); public static Dictionary radioISSIWithSeverityToCalloutUUIDDictionary = new Dictionary(); private DBvehiclesManager dbVehManager; public SDR_STATUS _registered = SDR_STATUS.NoConnection; public SDR_STATUS registered { get { return _registered; } set { _registered = value; RegStatusChanged("RegStatusProp"); } } public event PropertyChangedEventHandler PropertyChanged; protected void RegStatusChanged(string name) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { PropertyChangedEventArgs e = new PropertyChangedEventArgs(name); handler(this, e); } } public SDR() { ISSI = ConfigHelper.SdrIssi; pass = ConfigHelper.SdrPass; IP = ConfigHelper.SdrIp; port = ConfigHelper.SdrPort; Utils.WriteEventLog(Program.COMPANY, "SDR Constructor START: ISSI = " + ISSI + " pass= " + pass + " IP= " + IP + " port= " + port, EventLogEntryType.Information, (int)EventId.EVENT_SDR); try { lock (dictionaryLock) { dbVehManager = new DBvehiclesManager(ConfigHelper.DBip, ConfigHelper.DBSchema, ConfigHelper.DBUser, ConfigHelper.DBPassword, ConfigHelper.DBPort); RadioIdToLastPosDictionary = dbVehManager.getImeiLastPosDictionary(true); Utils.WriteEventLog(Program.COMPANY, "Received " + RadioIdToLastPosDictionary.Count + " units", EventLogEntryType.Information, (int)EventId.EVENT_SDR); StringBuilder sb = new StringBuilder(); foreach (var item in RadioIdToLastPosDictionary) { sb.AppendFormat("{0:#############} |||| {1}", item.Key, Environment.NewLine); //Utils.WriteEventLog(Program.COMPANY, String.Format("{0:#############} |||| ", item.Key), EventLogEntryType.Information, (int)EventId.EVENT_SDR); } string result = sb.ToString().TrimEnd();//when converting to string we also want to trim the redundant new line at the very end Utils.WriteEventLog(Program.COMPANY, result, EventLogEntryType.Information, (int)EventId.EVENT_SDR); } } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "Unable to get assigned units : " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_SDR); } } public void setStoreAndForwardOption(bool isStoreAndForward) { this.isStoreAndForward = isStoreAndForward; } public void Start() { running = true; if (listenThread != null && listenThread.IsAlive) return; lastEntry = DateTime.Now; tCheckConnection = new System.Threading.Timer(CheckConnection, null, new TimeSpan(0, 0, 15), new TimeSpan(0, 1, 0)); listenThread = new Thread(new ThreadStart(HandleConnection)); listenThread.IsBackground = true; listenThread.Start(); } public void Stop(SDR_STATUS status) { if (registered != status) registered = status; running = false; Utils.WriteEventLog(Program.COMPANY, "Stop SDR", EventLogEntryType.Warning, (int)EventId.EVENT_SDR); try { if (stream != null) { stream.Close(); } stream = null; } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "Stop SDR... Dispose 1: " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_SDR); }; try { if (tcpClient != null) { tcpClient.EndConnect(null); tcpClient.Close(); } tcpClient = null; } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "Stop SDR... Dispose 2: " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_SDR); }; if (tCheckConnection != null) tCheckConnection.Dispose(); if (registered != SDR_STATUS.Disconnected) registered = SDR_STATUS.Disconnected; } private void CheckConnection(Object state) { try { Utils.WriteEventLog(Program.COMPANY, "Testing connection Current:" + DateTime.Now + " lastentry:" + lastEntry, EventLogEntryType.Warning, (int)EventId.EVENT_SDR); if ((DateTime.Now.Subtract(lastEntry)).TotalSeconds > ConfigHelper.SdrTimeout) { //if we dont receive anything in the last 10mins reset connection Utils.WriteEventLog(Program.COMPANY, "Step 1", EventLogEntryType.Warning, (int)EventId.EVENT_SDR); Stop(SDR_STATUS.NoConnection); Utils.WriteEventLog(Program.COMPANY, "Step 2", EventLogEntryType.Warning, (int)EventId.EVENT_SDR); Thread.Sleep(1000); Utils.WriteEventLog(Program.COMPANY, "Step 3", EventLogEntryType.Warning, (int)EventId.EVENT_SDR); Start(); Utils.WriteEventLog(Program.COMPANY, "Expired.Restart", EventLogEntryType.Warning, (int)EventId.EVENT_SDR); } } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "Check connection error: " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_SDR); } } //write data private bool Write(byte[] data, int len) { bool resp = false; try { if (tcpClient != null && tcpClient.Connected && stream != null && stream.CanWrite) { stream.Write(data, 0, len); resp = true; } } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "Write on TCP Exception: " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_SDR); stream = null; tcpClient = null; if (registered != SDR_STATUS.Disconnected) registered = SDR_STATUS.Disconnected; } return resp; } //deleg for reading data (threaded while true) connection and maintain inside private void HandleConnection() { try { while (running) { //reconnect if (stream == null && running) { ConnectAndMaintain(); } try { //read available data from SDR!!! //byte[] data = SDR_Parse(out data_len, out rec_issi); //Process(data, data_len, rec_issi); if (stream != null && running) LIPreader(); } catch (IOException ex) { if (running) { Utils.WriteEventLog(Program.COMPANY, "HandleConnection error: " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_SDR); if (registered != SDR_STATUS.Disconnected) registered = SDR_STATUS.Disconnected; stream = null; tcpClient = null; } } } } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "HandleConnection error2: " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_SDR); } finally { if (stream != null) stream.Close(); if (tcpClient != null) if (tcpClient.Connected) tcpClient.Close(); } if (registered != SDR_STATUS.NoConnection) registered = SDR.SDR_STATUS.NoConnection; } #region LIP public void LIPreader() { try { byte[] data = new byte[1025]; string asciiData = ""; int iToRead = 0; int i = 0; //wait and read incoming data try { iToRead = stream.Read(data, 0, data.Length); } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "LIPreader error: " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_LIP); stream = null; tcpClient = null; if (registered != SDR_STATUS.Disconnected) registered = SDR_STATUS.Disconnected; } if (iToRead == 0) { Utils.WriteEventLog(Program.COMPANY, "RX 0 lenght data. Connection droped!!!", EventLogEntryType.Warning, (int)EventId.EVENT_LIP); stream = null; tcpClient = null; if (registered != SDR_STATUS.Disconnected) registered = SDR_STATUS.Disconnected; if (DEBUG) { SDR.Print(data, iToRead, true); } return; } //convert each byte into hex value. while (i < iToRead) { if (Convert.ToString(data[i], 16).ToString().Length < 2) { asciiData = asciiData + "0" + Convert.ToString(data[i], 16); } else { asciiData = asciiData + Convert.ToString(data[i], 16); } i = i + 1; } //Console.WriteLine("Ascii Data: " + asciiData); //message decoder and display section LIPSDR lipsdr = new LIPSDR(); lipsdr.sdsDecoder(asciiData); if (lipsdr.reply == "Address Registered") { if (registered != SDR_STATUS.Connected) { registered = SDR_STATUS.Connected; return; } } if (registered != SDR_STATUS.Connected) return; //if (DEBUG) if (true) { } string imei = lipsdr.sourceaddress ?? ""; Utils.WriteEventLog(Program.COMPANY, "SDR Received data from " + imei, EventLogEntryType.Information, (int)EventId.EVENT_LIP); // continue only if unit is assigned to this gateway or if the size of dictionary is 0 (connection with database was not allowed) if (RadioIdToLastPosDictionary.Count == 0 || RadioIdToLastPosDictionary.ContainsKey(imei)) { //SMS if (lipsdr.PIvalue == "130" || lipsdr.PIvalue == "195") { //Utils.WriteLine("PI VALUE ISSSS : " + lipsdr.PIvalue, ConsoleColor.Yellow); //Utils.WriteLine("ASCII : " + asciiData, ConsoleColor.Red); //IF SMS(not null) this must be added if (lipsdr.User_data != null) { if (lipsdr.User_data != "") { msgCell cell = new msgCell(); cell.msg = MSG_TYPE.SMS; cell.IMEI = lipsdr.sourceaddress; cell.sms = lipsdr.User_data; Utils.WriteEventLog(Program.COMPANY, "MSG RECEIVED : " + lipsdr.User_data, EventLogEntryType.Warning, (int)EventId.EVENT_LIP); Program.smsINQueue.PostItem(cell); } } //send ACK back // sending a report back int sourISSI = int.Parse(lipsdr.destinationaddress); int DestISSI = int.Parse(lipsdr.sourceaddress); byte[] REPORT_ACK = {0x00, 0x0f, 0x00, (byte)(((UInt32)sourISSI&0xff0000)>>16), // source ISSI (byte)(((UInt32)sourISSI&0x00ff00)>>8), (byte)(((UInt32)sourISSI&0x0000ff)), (byte)(((UInt32)DestISSI&0x00ff0000)>>16), // destination ISSI (byte)(((UInt32)DestISSI&0x0000ff00)>>8), (byte)(((UInt32)DestISSI&0x000000ff)), (byte)(byte.Parse(lipsdr.PIvalue)),// 0xc0, // protocol 0x60, // flags 0x00, // message reference 0x00, // area slection 0x00, 0x10, // TL length (bits) 0x01, // PDU type = Report 0x00 // Delivery status = ACK }; REPORT_ACK[11] = byte.Parse(lipsdr.messageReference); ; // msg_id if (stream != null) stream.Write(REPORT_ACK, 0, 0x0f + 2); } else if (lipsdr.PIvalue != "10") ;//Utils.WriteLine("PI VALUE IS " + lipsdr.PIvalue, ConsoleColor.Magenta); #region PIVALUE 10 if (lipsdr.PIvalue == "10") { LIP lip = new LIP(); lip.decoder(lipsdr.User_data); Utils.WriteEventLog(Program.COMPANY, "╕╕╕ LIP raw data : " + lipsdr.User_data, EventLogEntryType.Information, (int)EventId.EVENT_LIP); //Console.WriteLine("MESSAGE REFERENCE " + lip.locationMessageReference); int len = (int.Parse(lipsdr.TLlength_include_SDTS_TL_PDU_field) / 4) - 1; //Console.WriteLine("User Data len: " + len ); MSG_TYPE type = lipsdr.GetMSGtype(lipsdr.User_data, len); msgCell cell = new msgCell(); //IMEI subscriber if (lipsdr.sourceaddress != "") cell.IMEI = lipsdr.sourceaddress; else Utils.WriteEventLog(Program.COMPANY, "subscriber == null", EventLogEntryType.Warning, (int)EventId.EVENT_LIP); switch (type) { case MSG_TYPE.ARS_ON: { Utils.WriteEventLog(Program.COMPANY, "Adding ARS_ON from " + cell.IMEI, EventLogEntryType.Information, (int)EventId.EVENT_LIP); cell.msg = MSG_TYPE.ARS; cell.ars = 1; Program.eventQueue.PostItem(cell); break; } case MSG_TYPE.ARS_OFF: { Utils.WriteEventLog(Program.COMPANY, "Adding ARS_OFF from " + cell.IMEI, EventLogEntryType.Information, (int)EventId.EVENT_LIP); cell.msg = MSG_TYPE.ARS; cell.ars = 0; Program.eventQueue.PostItem(cell); break; } case MSG_TYPE.Emergency: { Utils.WriteEventLog(Program.COMPANY, "Adding Emergency from " + cell.IMEI, EventLogEntryType.Information, (int)EventId.EVENT_LIP); cell.msg = MSG_TYPE.Emergency; Program.eventQueue.PostItem(cell); break; } case MSG_TYPE.GPS: { Utils.WriteEventLog(Program.COMPANY, "Adding LIP message to GPS queue. ", EventLogEntryType.Information, (int)EventId.EVENT_LIP); //LAT latitude if (lip.latitude != "") cell.lat = lip.latitude; else Utils.WriteEventLog(Program.COMPANY, "latitude == null", EventLogEntryType.Warning, (int)EventId.EVENT_LIP); //LNG if (lip.longitude != "") cell.lng = lip.longitude; else Utils.WriteEventLog(Program.COMPANY, "longitude == null", EventLogEntryType.Warning, (int)EventId.EVENT_LIP); if (lip.timePositionHour == null || lip.timePositionHour == "") { lip.timePositionHour = DateTime.UtcNow.Hour.ToString(); } if (lip.timePositionMinute == null || lip.timePositionMinute == "") { lip.timePositionMinute = DateTime.UtcNow.Minute.ToString(); } if (lip.timePositionSecond == null || lip.timePositionSecond == "") { lip.timePositionSecond = DateTime.UtcNow.Second.ToString(); } //Utils.WriteEventLog(Program.COMPANY, $"{lip.timePositionHour}:{lip.timePositionMinute}:{lip.timePositionSecond}", EventLogEntryType.Information, (int)EventId.EVENT_LIP); //time DateTime time = new DateTime((int)DateTime.UtcNow.Year, (int)DateTime.UtcNow.Month, (int)DateTime.UtcNow.Day, (int)Convert.ToInt32(lip.timePositionHour), (int)Convert.ToInt32(lip.timePositionMinute), (int)Convert.ToInt32(lip.timePositionSecond)); if (time != null) cell.time = time; else Utils.WriteEventLog(Program.COMPANY, "time == null", EventLogEntryType.Warning, (int)EventId.EVENT_LIP); //speed speed double spd = 0; //Utils.WriteEventLog(Program.COMPANY, "Horizontal speed : " + lip.horizontalVelocity, EventLogEntryType.Information, (int)EventId.EVENT_LIP); if (lip.horizontalVelocity.Contains("Horizontal speed is unknown")) { // Console.WriteLine("Horizontal speed is unknown"); lip.horizontalVelocity = "0"; } if (lip.horizontalVelocity.Contains("km/h")) { lip.horizontalVelocity = lip.horizontalVelocity.Replace("km/h", ""); //Console.WriteLine("After replace km/h: " + lip.horizontalVelocity); } if (!double.TryParse(lip.horizontalVelocity, out spd)) { //Console.WriteLine("!ulong.TryParse(lip.horizontalVelocity, out spd) " + lip.horizontalVelocity); lip.horizontalVelocity = "0"; } //this is for knots //ulong spd = (ulong)(ulong.Parse( lip.horizontalVelocity) * 1.85325); spd = double.Parse(lip.horizontalVelocity); try { spd = (ulong)Math.Round((double)spd); } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "Error on rounding speed: " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_LIP); } Utils.WriteEventLog(Program.COMPANY, "Horizontal speed : " + spd, EventLogEntryType.Information, (int)EventId.EVENT_LIP); try { cell.spd = spd + ""; } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "Error: " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_LIP); }; // convert the position error to the enum value LIP.PositionError positionError = LIP.PositionError.GetPositionError(lip.positionErrorBinaryValue); Utils.WriteEventLog(Program.COMPANY, "Position Error is: " + positionError.ToHumanString() + "[" + lip.positionErrorBinaryValue + "]", EventLogEntryType.Warning, (int)EventId.EVENT_LIP); Boolean isGPSErrorValid = true; if (positionError.value <= ConfigHelper.SDR_PositionErrorTolerance.value) isGPSErrorValid = true; else isGPSErrorValid = false; #region INDOOR POSITION - QUERY INFO NOT ATTAINABLE lock (dictionaryLock) { // add last position to an empty message if not available if (!radioIdTolastPositionATMessageDictionary.ContainsKey(cell.IMEI)) radioIdTolastPositionATMessageDictionary.Add(cell.IMEI, ""); // get last position message from the hashtable String lastPositionATMessage = radioIdTolastPositionATMessageDictionary[cell.IMEI]; // last position message is equal with current one (QUERY INFO NOT ATTAINABLE) if (lastPositionATMessage.Equals(lip.binary)) { Utils.WriteEventLog(Program.COMPANY, "Query info not attainable", EventLogEntryType.Warning, (int)EventId.EVENT_LIP); cell.lat = "0.0"; cell.lng = "0.0"; cell.time = DateTime.UtcNow; cell.spd = "0"; } // update last position at message to the last received one radioIdTolastPositionATMessageDictionary[cell.IMEI] = lip.binary; } #endregion //poll response if (Convert.ToInt32(lip.reasonForSendingBinaryValue, 2) == 32) { cell.msg = MSG_TYPE.GPSpoll; cell.poll = 1; Utils.WriteEventLog(Program.COMPANY, String.Format("»»» Poll res [{0:0.0000},{1:0.0000}] from {2}", Math.Round(Double.Parse(cell.lat), 4), Math.Round(Double.Parse(cell.lng), 4), cell.IMEI), EventLogEntryType.Information, (int)EventId.EVENT_LIP); } else { cell.msg = MSG_TYPE.GPS; cell.poll = 0; } if (!isGPSErrorValid) { Utils.WriteEventLog(Program.COMPANY, String.Format("»»» Position is not valid [{0:0.0000},{1:0.0000}] from {2} [{3} kmh]", Math.Round(Double.Parse(cell.lat), 4), Math.Round(Double.Parse(cell.lng), 4), cell.IMEI, cell.spd), EventLogEntryType.Information, (int)EventId.EVENT_LIP); } else Utils.WriteEventLog(Program.COMPANY, String.Format("»»» Position is [{0:0.0000},{1:0.0000}] from {2} [{3} kmh]", Math.Round(Double.Parse(cell.lat), 4), Math.Round(Double.Parse(cell.lng), 4), cell.IMEI, cell.spd), EventLogEntryType.Information, (int)EventId.EVENT_LIP); Program.gpsQueue.PostItem(cell); break; } } //mark message time lastEntry = DateTime.Now; } #endregion } else Utils.WriteEventLog(Program.COMPANY, $"Received position from unit not assigned with imei {imei}", EventLogEntryType.Warning, (int)EventId.EVENT_LIP); } catch (IOException ex) { Utils.WriteEventLog(Program.COMPANY, "SDR IO read error: " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_LIP); } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "SDR read error: " + ex.ToString(), EventLogEntryType.Error, (int)EventId.EVENT_LIP); } } #endregion #region lrrp public void Process(byte[] data, uint data_len, long rec_issi) { if (data == null) { Utils.WriteEventLog(Program.COMPANY, "SDR data == null", EventLogEntryType.Error, (int)EventId.EVENT_LRRP); return; } //switch GPS_type if (ConfigHelper.GpsType == "LIP") { Parser p = new Parser(); string out_str = p.ProcessCommand(data, data_len); string xml = ""; System.Xml.XmlDocument doc = null; System.Xml.XmlNode element = null; if (out_str != "") { xml = ""; doc = new System.Xml.XmlDocument(); doc.LoadXml(xml); element = doc.SelectSingleNode("xml"); string value = element.Attributes["id"].Value; } if (doc != null) { Utils.WriteEventLog(Program.COMPANY, "Adding LIP message to GPS queue", EventLogEntryType.Information, (int)EventId.EVENT_LRRP); msgCell cell = new msgCell(); //IMEI subscriber if (element.Attributes["subscriber"].Value != null) cell.IMEI = element.Attributes["subscriber"].Value; else Utils.WriteEventLog(Program.COMPANY, "subscriber == null", EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); //LAT latitude if (element.Attributes["latitude"].Value != null) cell.lat = element.Attributes["latitude"].Value; else Utils.WriteEventLog(Program.COMPANY, "latitude == null", EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); //LNG if (element.Attributes["longitude"].Value != null) cell.lng = element.Attributes["longitude"].Value; else Utils.WriteEventLog(Program.COMPANY, "longitude == null", EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); //time if (element.Attributes["time"].Value != null) cell.time70 = uint.Parse(element.Attributes["time"].Value); else Utils.WriteEventLog(Program.COMPANY, "time == null", EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); //speed speed if (element.Attributes["speed"].Value != null) { cell.spd = element.Attributes["speed"].Value; Double speed = 0; if ((Double.TryParse(cell.spd, out speed)) && (speed > 250)) { cell.spd = "0"; cell.lat = "0"; cell.lng = "0"; } } else Utils.WriteEventLog(Program.COMPANY, "speed == null", EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); //poll response cell.poll = 0; Utils.WriteEventLog(Program.COMPANY, String.Format("»»» Position [{0:0.0000},{1:0.0000}] from {2}", Math.Round(Double.Parse(cell.lat), 4), Math.Round(Double.Parse(cell.lng), 4), cell.IMEI), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); Program.gpsQueue.PostItem(cell); } else { Utils.WriteEventLog(Program.COMPANY, "LIP message == null", EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); } Thread.Sleep(100); }// else LRRP else { Parse_LRRP p_lrrp = new Parse_LRRP(); MOTO.GPS_POS gps_pos = p_lrrp.ProcessCommand(data, data_len); if (gps_pos != null) { Utils.WriteEventLog(Program.COMPANY, "Adding LRRP message to GPS queue", EventLogEntryType.Information, (int)EventId.EVENT_LRRP); msgCell cell = new msgCell(); //IMEI cell.IMEI = rec_issi.ToString(); //LAT cell.lat = ((gps_pos.pos.direction_lat == 'N') ? "" : "-") + gps_pos.pos.degrees_lat.ToString() + "." + (gps_pos.pos.minutes_lat + gps_pos.pos.fraction_lat).ToString(); //LNG cell.lng = ((gps_pos.pos.direction_lng == 'E') ? "" : "-") + gps_pos.pos.degrees_lng.ToString() + "." + (gps_pos.pos.minutes_lng + gps_pos.pos.fraction_lng).ToString(); //time cell.time = new DateTime(); cell.time = new DateTime(gps_pos.time.year, gps_pos.time.month, gps_pos.time.day, gps_pos.time.hour, gps_pos.time.minute, gps_pos.time.second); //speed cell.spd = "0"; //poll response cell.poll = 0; Utils.WriteEventLog(Program.COMPANY, String.Format("»»» Position [{0:0.0000},{1:0.0000}] from {2}", Math.Round(Double.Parse(cell.lat), 4), Math.Round(Double.Parse(cell.lng), 4), cell.IMEI), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); Program.gpsQueue.PostItem(cell); } else { Utils.WriteEventLog(Program.COMPANY, "LRRP message == null", EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); } } } public byte[] SDR_Parse(out uint data_len, out long issi) { int cm_len = 0; int cm_type = -1; int i, val; byte[] data = null; byte[] buf = new byte[1024]; int len; issi = 0; data_len = 0; len = stream.Read(buf, 0, 2); if (len == 0) { Utils.WriteEventLog(Program.COMPANY, String.Format("error: broken pipe {0}\n", len), EventLogEntryType.Error, (int)EventId.EVENT_LRRP); return null; } if (len != 2) { Utils.WriteEventLog(Program.COMPANY, String.Format("error: reading len {0}\n", len), EventLogEntryType.Error, (int)EventId.EVENT_LRRP); return null; } cm_len = (byte)buf[0]; cm_len <<= 8; cm_len |= (byte)buf[1]; Utils.WriteEventLog(Program.COMPANY, String.Format("CM Length={0}\n", cm_len), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); //!! implement the interrupted TCP/IP message int bread = stream.Read(buf, 0, cm_len); if (DEBUG) { Utils.WriteEventLog(Program.COMPANY, String.Format("#############################################") + Environment.NewLine + String.Format("RX: cm_len: " + cm_len + " bread:" + bread), EventLogEntryType.Information, (int)EventId.EVENT_PING); SDR.Print(buf, bread, true); } if (bread != cm_len) { Utils.WriteEventLog(Program.COMPANY, "ERROR: cm_len:" + cm_len + " != bread:" + bread, EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); return null; } cm_type = buf[0]; Utils.WriteEventLog(Program.COMPANY, String.Format("CM Type[{0}]: ", cm_type), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); switch (cm_type) { case 0x00: // ----------------------------------------------------------------------- CM DATA Utils.WriteEventLog(Program.COMPANY, String.Format("(CM_DATA)\n") + Environment.NewLine + String.Format("Source Addr={0} {1} {2}\n", buf[1], buf[2], buf[3]) + Environment.NewLine + String.Format("Destin Addr={0} {1} {2}\n", buf[4], buf[5], buf[6]) + Environment.NewLine + String.Format("Protocol ID=0x{0}\n", buf[7] & 0x00ff) + Environment.NewLine + String.Format("CM flags={0}\n", buf[8]) + Environment.NewLine + String.Format("Msg reference={0}\n", buf[9]) + Environment.NewLine + String.Format("Area={0}\n", buf[10]), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); // compute decimal issi long c1 = (byte)buf[1]; long c2 = (byte)buf[2]; long c3 = (byte)buf[3]; //Console.Write("c1=%ld c2=%ld c3=%ld\r\n", c1, c2, c3); c3 += c1 << 16; //Console.Write("c1=%ld c2=%ld c3=%ld\r\n", c1, c2, c3); c3 += c2 << 8; //Console.Write("c1=%ld c2=%ld c3=%ld\r\n", c1, c2, c3); issi = c3; //*issi = buf[1]<<16 + buf[2]<<7 + buf[3]; uint tl_len; // = buf[11]; tl_len = (((uint)buf[11] & 0x00FF) << 8); //tl_len <<= 8; tl_len += ((uint)buf[12] & 0x00FF); Utils.WriteEventLog(Program.COMPANY, String.Format("TL Length (bits)=0x{0:X}\n", tl_len), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); int tl_type = buf[13]; Utils.WriteEventLog(Program.COMPANY, String.Format("TL Type[0x{0:X}]: ", tl_type), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); switch (tl_type) { case 0x00: // DATA Utils.WriteEventLog(Program.COMPANY, "TL-Data: " + Environment.NewLine + String.Format("Headers: {0:X} {1:X} {2:X} {3:X} {4:X}\n", buf[14], buf[15], buf[16], buf[17], buf[18]) + Environment.NewLine + "Data: \n", EventLogEntryType.Information, (int)EventId.EVENT_LRRP); i = 0; data_len = tl_len / 8 - 6; data = new byte[data_len]; while (i < tl_len / 8 - 6) // get rid of the len+headers (1+5B) { Utils.WriteEventLog(Program.COMPANY, String.Format("{0:X}({1},{2}) ", buf[19 + i], i, tl_len), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); // return payload data[i] = buf[19 + i]; i++; } // print text message Utils.WriteEventLog(Program.COMPANY, String.Format("Text Messsage:\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); i = 0; while (i < tl_len / 8 - 6) // get rid of the len+headers (1+5B) { Utils.WriteEventLog(Program.COMPANY, String.Format("%c", buf[19 + i]), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); i++; } // sending a report back byte[] REPORT_ACK = {0x00, 0x0f, 0x00, buf[4], buf[5], buf[6], // source ISSI buf[1], buf[2], buf[3], // dest ISSI 0xc0, // protocol 0x60, // flags 0x00, // message reference 0x00, // area slection 0x00, 0x10, // TL length (bits) 0x01, // PDU type = Report 0x00 // Delivery status = ACK }; REPORT_ACK[11] = buf[9]; // msg_id stream.Write(REPORT_ACK, 0, 0x0f + 2); //Console.Write("\r\n send ok !!! \r\n");fflush(stdout); break; case 0x03: // SHORT_REPORT Utils.WriteEventLog(Program.COMPANY, "Shrot", EventLogEntryType.Information, (int)EventId.EVENT_LRRP); break; case 0x01: // REPORT Utils.WriteEventLog(Program.COMPANY, "Report: \n", EventLogEntryType.Information, (int)EventId.EVENT_LRRP); val = buf[14]; // this contains the report value i = 0; while (i < tl_len / 8 - 1) // get rid of the len (1B) { Utils.WriteEventLog(Program.COMPANY, String.Format("{0:X} ", buf[i + 14]), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); i++; } break; } break; case 0x04: // ----------------------------------------------------------------------- CM BROADCAST //Utils.WriteEventLog(Program.COMPANY, String.Format("(CM_BROADCAST)\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); StringBuilder sb = new StringBuilder(); for (i = 0; i < cm_len - 1; i++) sb.AppendFormat(String.Format(buf[i + 1] + " ")); string result = sb.ToString().TrimEnd();//when converting to string we also want to trim the redundant new line at the very end Utils.WriteEventLog(Program.COMPANY, String.Format("(CM_BROADCAST)\n") + result, EventLogEntryType.Information, (int)EventId.EVENT_SDR); break; case 0x02: // ----------------------------------------------------------------------- CM REGISTER request Utils.WriteEventLog(Program.COMPANY, String.Format("(CM_REGISTER_REQ)\n") + Environment.NewLine + String.Format("Error: CM REGISTER REQUEST \n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); break; case 0x01: // ----------------------------------------------------------------------- CM REPORT response Utils.WriteEventLog(Program.COMPANY, String.Format("(CM_REPORT_RESP)\n") + Environment.NewLine + String.Format("Source Addr={0:X} {1:X} {2:X}\n", buf[1], buf[2], buf[3]) + Environment.NewLine + String.Format("Destin Addr={0:X} {1:X} {2:X}\n", buf[4], buf[5], buf[6]) + Environment.NewLine + String.Format("Protocol ID={0:X}\n", buf[7]) + Environment.NewLine + String.Format("Msg reference={0:X}\n", buf[8]), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); val = buf[9]; Utils.WriteEventLog(Program.COMPANY, String.Format("Delivery status[0x{0:X}]:\n", val), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); switch (val) { case 0x40: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_OVERLOAD\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x41: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_SERVICE_DISABLED\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x42: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_SERV_TEMP_NOT_AVAIL\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x44: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_DEST_NOT_AUTH_FOR_SDS\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x45: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_UNKNOWN_DEST\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x47: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_GROUP_ADDR\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x4a: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_NOT_REACHABLE\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x4b: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_NOT_REGISTERED\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x4c: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERT_DEST_QUEUE_FULL\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x4d: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_MSG_TOO_LONG\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x4e: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_DEST_NOT_SUPPORT_PDU\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x4f: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_DEST_NOT_CONNECTED\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x50: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_PROT_NOT_SUPP\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x53: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_DEST_NOT_ACC_SDS\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x56: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_DEST_PROHIBITED\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x58: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_UNKOWN_SUBSCRIBER\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x5a: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_DEST_NOT_REACHABLE\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x8d: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_TEXT_ERROR\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; case 0x8e: { Utils.WriteEventLog(Program.COMPANY, String.Format(" DELIVERY_CORRUPT_INFO\n"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); } break; } break; case 0x03: // ----------------------------------------------------------------------- CM REGISTER response Utils.WriteEventLog(Program.COMPANY, String.Format("(CM_REGISTER)\n") + Environment.NewLine + String.Format("Pass No={0:X} {1:X} {2:X} {3:X}\n", buf[1], buf[2], buf[3], buf[4]) + Environment.NewLine + String.Format("ISSI={0:X} {1:X} {2:X}\n", buf[5], buf[6], buf[7]) + Environment.NewLine + String.Format("Registration type={0:X}\n", buf[8]), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); val = buf[9]; Utils.WriteEventLog(Program.COMPANY, String.Format("Registration status[0x{0:X}]: ", val), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); Console.ForegroundColor = ConsoleColor.Green; switch (val) { case 0x00: Utils.WriteEventLog(Program.COMPANY, String.Format("Address Registered"), EventLogEntryType.Information, (int)EventId.EVENT_LRRP); { if (registered != SDR_STATUS.Connected) registered = SDR_STATUS.Connected; break; } case 0x01: Utils.WriteEventLog(Program.COMPANY, String.Format("Duplicate Address"), EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); break; case 0x02: Utils.WriteEventLog(Program.COMPANY, String.Format("Invalid Address"), EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); break; case 0x03: Utils.WriteEventLog(Program.COMPANY, String.Format("Registration Not Available"), EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); break; case 0x04: Utils.WriteEventLog(Program.COMPANY, String.Format("Invalid Pass Number"), EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); break; default: Utils.WriteEventLog(Program.COMPANY, String.Format("Registration: Unknown Code"), EventLogEntryType.Warning, (int)EventId.EVENT_LRRP); break; } break; } // end switch return data; } #endregion #region Connect and send msg private string displayedMessage = "Connecting to SDR"; public void ConnectAndMaintain() { try { if (tcpClient == null) { Utils.WriteEventLog(Program.COMPANY, displayedMessage, EventLogEntryType.Information, (int)EventId.EVENT_SDR); displayedMessage = "Reconnecting to SDR"; try { tcpClient = new TcpClient(IP, port); } catch (Exception ex) { if (!ex.ToString().Contains("failed because the connected party did not properly respond")) WriteLine("Exception " + ex.ToString(), EventLogEntryType.Error); else { Utils.WriteEventLog(Program.COMPANY, "Unable to connect to SDR", EventLogEntryType.Error, (int)EventId.EVENT_SDR); } } //Thread.Sleep(1000); } if (stream == null && tcpClient != null) { stream = tcpClient.GetStream(); } Thread.Sleep(500); //send connect message if (registered != SDR_STATUS.Connected) { if (stream != null) { //tcpClient.Write(new byte[11] { 0x00, 0x09 , 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,0x05,0x00}, 11); Utils.WriteEventLog(Program.COMPANY, "Starting SDR Connection", EventLogEntryType.Information, (int)EventId.EVENT_SDR); byte[] data = SDR.GenConnectMSG_ISSI(ISSI, pass); SDR.Print(data, data.Length, false); //send data bool resp = Write(data, data.Length); if (resp) Utils.WriteEventLog(Program.COMPANY, "Connection data sent to SDR!!! Waiting for response!!! ", EventLogEntryType.Information, (int)EventId.EVENT_SDR); else Utils.WriteEventLog(Program.COMPANY, "ERROR sending data to SDR", EventLogEntryType.Error, (int)EventId.EVENT_SDR); } } else Utils.WriteEventLog(Program.COMPANY, "Connected and waiting for data... ", EventLogEntryType.Information, (int)EventId.EVENT_SDR); } catch (Exception ex) { //Console.WriteLine("ERROR in ConnectAndMaintain"); if (!ex.ToString().Contains("failed because the connected party did not properly respond")) WriteLine("Exception in ConnectAndMaintain: " + Environment.NewLine + ex.ToString(), EventLogEntryType.Error); if (registered != SDR_STATUS.Disconnected) { registered = SDR_STATUS.Disconnected; } stream = null; tcpClient = null; } finally { Thread.Sleep(100); } } public static byte[] GenConnectMSG_ISSI(Int64 ISSI, String pass)// in case of LRRP pass=IP { byte[] ret = new byte[9]; String[] split = pass.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries); ret[0] = (byte)CM_MSG_TYPE.CM_REGISTER_REQ; //msg type /* ret[1] = (byte)(((UInt32)split[0] & 0xff000000) >> 24); //pass ret[2] = (byte)(((UInt32)pass & 0x00ff0000) >> 16); //pass ret[3] = (byte)(((UInt32)pass & 0x0000ff00) >> 8); //pass ret[4] = (byte)(((UInt32)pass & 0x000000ff)); //pass */ ret[1] = (byte)(Int32.Parse(split[0])); //pass ret[2] = (byte)(Int32.Parse(split[1])); //pass ret[3] = (byte)(Int32.Parse(split[2])); //pass ret[4] = (byte)(Int32.Parse(split[3])); //pass ret[5] = (byte)(((UInt32)ISSI & 0x00ff0000) >> 16); //ISSI ret[6] = (byte)(((UInt32)ISSI & 0x0000ff00) >> 8); //ISSI ret[7] = (byte)(((UInt32)ISSI & 0x000000ff)); //ISSI ret[8] = 0x00; //reserved return addMsgLength(ret); } public static byte cm_msg_id = 0; public static byte[] SDR_CMD_SendMsg(UInt32 sourISSI, UInt32 DestISSI, byte[] buf, int buflen) { if (cm_msg_id > 0xfe) cm_msg_id = 0; cm_msg_id += 1; byte[] MSG = {0x00, 0x00, // CM length = to be computed 0x00, //CM_DATA (byte)(((UInt32)sourISSI&0xff0000)>>16), // source ISSI (byte)(((UInt32)sourISSI&0x00ff00)>>8), (byte)(((UInt32)sourISSI&0x0000ff)), (byte)(((UInt32)DestISSI&0x00ff0000)>>16), // destination ISSI (byte)(((UInt32)DestISSI&0x0000ff00)>>8), (byte)(((UInt32)DestISSI&0x000000ff)), 0x82,//0xC0, //CM_PROTOCOL, // protocol 0x60, // flags cm_msg_id, // message reference 0x00, // area selection 0x00, 0x00, // TL length (bits) = to be completed 0x00, // PDU type = TL-DATA 0x80, // TL flags 0x00, // validity period 0x00, 0x00, 0x00, // forward address // TL data = to be sent separately }; // compute the CM length in bytes MSG[0] = (byte)(((0x13 + buflen) & 0xff00) >> 8); MSG[1] = (byte)((0x13 + buflen) & 0x00ff); // complete the TL length in bits MSG[13] = (byte)((((buflen + 6) * 8) & 0xff00) >> 8); MSG[14] = (byte)(((buflen + 6) * 8) & 0x00ff); byte[] temp = new byte[0x13 + 2 + buflen]; int i; StringBuilder sb = new StringBuilder(); StringBuilder sb2 = new StringBuilder(); //Utils.WriteEventLog(Program.COMPANY, "SDR-CM-DATA:\nHeaders:", EventLogEntryType.Information, (int)EventId.EVENT_SDR); for (i = 0; i < 0x13 + 2; i++) { //Utils.WriteEventLog(Program.COMPANY, String.Format("0X{0:X} ", MSG[i]), EventLogEntryType.Information, (int)EventId.EVENT_SDR);\ temp[i] = MSG[i]; sb.AppendFormat(String.Format("0X{0:X} ", MSG[i])); } string result = sb.ToString().TrimEnd();//when converting to string we also want to trim the redundant new line at the very end Utils.WriteEventLog(Program.COMPANY, "SDR-CM-DATA:\nHeaders:" + result, EventLogEntryType.Information, (int)EventId.EVENT_SDR); //Utils.WriteEventLog(Program.COMPANY, String.Format("\nnTL-Data:"), EventLogEntryType.Information, (int)EventId.EVENT_SDR); for (i = 0; i < buflen; i++) { //Utils.WriteEventLog(Program.COMPANY, String.Format("0X{0:X} ", buf[i]), EventLogEntryType.Information, (int)EventId.EVENT_SDR);\ temp[0x13 + 2 + i] = buf[i]; sb2.AppendFormat(String.Format("0X{0:X} ", buf[i])); } string result2 = sb2.ToString().TrimEnd();//when converting to string we also want to trim the redundant new line at the very end Utils.WriteEventLog(Program.COMPANY, String.Format("\nnTL-Data:") + result2, EventLogEntryType.Information, (int)EventId.EVENT_SDR); return temp; } public void SendCallOutMessage(Int32 DestISSI, byte[] msg) { SDR.Print(msg, msg.Length, false); //send data bool resp = Write(msg, msg.Length); if (resp) { Utils.WriteEventLog(Program.COMPANY, String.Format("»»» Call OUT to {0} [{1}]", DestISSI, BitConverter.ToString(msg)), EventLogEntryType.Information, (int)EventId.EVENT_CALLOUT); } else Utils.WriteEventLog(Program.COMPANY, String.Format("»»» Call OUT not sent to {0} [{1}]", DestISSI, BitConverter.ToString(msg)), EventLogEntryType.Warning, (int)EventId.EVENT_CALLOUT); } public void SendCallOut(UInt32 destISSI, UInt16 callOutSeverity, string geoName) { UInt32 sourceISSI = (UInt32)ConfigHelper.SdrIssi; UInt32 tgNumber = 10010001; //need to get the Radio TalkGroup uint tgCtrl = (uint)TGctrl.TGChangeUserInter; if (cm_msg_id > 0xfe) cm_msg_id = 0; cm_msg_id += 1; uint calloutUUID = ++LIPSDR.callOutNumber; //if (ddlTgCtrl.SelectedText == TGctrl.TGChangeOnAlert.ToString()) // tgCtrl = (uint)TGctrl.TGChangeOnAlert; string calloutKey = getCalloutKey(destISSI, callOutSeverity); lock (calloutUUIDLock) { // remove previous callout with the same severity to the same radio issi if (radioISSIWithSeverityToCalloutUUIDDictionary.ContainsKey(calloutKey)) { uint previousCalloutUUID = radioISSIWithSeverityToCalloutUUIDDictionary[calloutKey]; // send callout clear for previous callout // to decide radioISSIWithSeverityToCalloutUUIDDictionary.Remove(calloutKey); } // store the callout uuid for this radio issi with this severity radioISSIWithSeverityToCalloutUUIDDictionary.Add(calloutKey, calloutUUID); } byte[] result = CallOutClass.SendCallOut(true, (uint)CallOutFunction.Alert, calloutUUID, callOutSeverity, tgCtrl, tgNumber, ref cm_msg_id, sourceISSI, destISSI, geoName); //LIPSDR.printBytesArray(result); Utils.WriteEventLog(Program.COMPANY, String.Format("Encrypted CallOut length: " + result.Length), EventLogEntryType.Information, (int)EventId.EVENT_CALLOUT); //send data bool resp = Write((byte[])result, (int)result.Length); if (resp) { Utils.WriteEventLog(Program.COMPANY,String.Format("»»» Call out to {0} [{1}]", destISSI, callOutSeverity) + Environment.NewLine + String.Format("»»» TM to {0} [{1}]", destISSI, callOutSeverity), EventLogEntryType.Information, (int)EventId.EVENT_CALLOUT); } else Utils.WriteEventLog(Program.COMPANY, String.Format("φφφ TM not sent to {0} [{1}]", destISSI, callOutSeverity), EventLogEntryType.Warning, (int)EventId.EVENT_CALLOUT); SDR.Print(result, result.Length, false); Utils.WriteEventLog(Program.COMPANY, LIPSDR.callOutNumber.ToString(), EventLogEntryType.Information, (int)EventId.EVENT_CALLOUT); } public void SendCallOutStop(UInt32 destISSI, UInt16 callOutSeverity) { UInt32 sourceISSI = (UInt32)ConfigHelper.SdrIssi; string geoName = ""; uint? calloutUUID = GetCalloutUUIDForISSI(destISSI, callOutSeverity); if (calloutUUID == null) { Utils.WriteEventLog(Program.COMPANY, $"No callout to clear for issi {destISSI} with severity {callOutSeverity}", EventLogEntryType.Warning, (int)EventId.EVENT_CALLOUT); return; } byte[] result = CallOutClass.SendCallOut(true, (uint)CallOutFunction.Clear, (uint)calloutUUID, 0, (uint)TGctrl.TGControlNotUsed, 0, ref cm_msg_id, sourceISSI, destISSI, geoName); //LIPSDR.printBytesArray(result); Utils.WriteEventLog(Program.COMPANY, "Encrypted CallOut length: " + result.Length, EventLogEntryType.Information, (int)EventId.EVENT_CALLOUT); //send data bool resp = Write((byte[])result, (int)result.Length); SDR.Print(result, result.Length, false); Utils.WriteEventLog(Program.COMPANY, LIPSDR.callOutNumber.ToString(), EventLogEntryType.Information, (int)EventId.EVENT_CALLOUT); } private uint? GetCalloutUUIDForISSI(UInt32 destISSI, UInt16 callOutSeverity) { uint? result = null; string calloutKey = getCalloutKey(destISSI, callOutSeverity); lock (calloutUUIDLock) { // remove previous callout with the same severity to the same radio issi if (radioISSIWithSeverityToCalloutUUIDDictionary.ContainsKey(calloutKey)) result = radioISSIWithSeverityToCalloutUUIDDictionary[calloutKey]; } return result; } private string getCalloutKey(UInt32 destISSI, UInt16 callOutSeverity) { return destISSI + "_" + callOutSeverity; } public void SEND_SMS(UInt32 DestISSI, string msg) { Utils.WriteEventLog(Program.COMPANY, "SEND SMS: " + msg, EventLogEntryType.Information, (int)EventId.EVENT_SMS); string tmp_str = msg + " "; if (cm_msg_id > 0xfe) cm_msg_id = 0; cm_msg_id += 1; //byte[] data = SDR.SDR_CMD_SendMsg(ISSI, DestISSI, Encoding.UTF8.GetBytes(msg), Encoding.UTF8.GetBytes(msg).Length); byte[] data = LIPSDR.Stds_Cm_Message_header_sdsEncoder(ISSI, DestISSI, SMSprotocolID, cm_msg_id, tmp_str); Utils.WriteEventLog(Program.COMPANY, "Encrypted SMS length: " + data.Length, EventLogEntryType.Information, (int)EventId.EVENT_SMS); //send data bool resp = Write(data, data.Length); if (resp) { Utils.WriteEventLog(Program.COMPANY, "»»» TM to " + DestISSI + " [" + msg + "]", EventLogEntryType.Information, (int)EventId.EVENT_SMS); } else Utils.WriteEventLog(Program.COMPANY, String.Format("φφφ TM not sent to {0} [{1}]", DestISSI, msg), EventLogEntryType.Error, (int)EventId.EVENT_SMS); SDR.Print(data, data.Length, false); } public void SendSMS_4_Test(Int64 radioID, Int64 gatewayID, Int64 gatewayRadioID, string message, int type) { byte[] data = new byte[] { }; if (type == 20) data = LIPSDR.Stds_Cm_Message_header_sdsEncoder((uint)ISSI, (uint)radioID, SMSprotocolID, cm_msg_id++ % 0xFE, message); else if (type == 00) data = LIPSDR.Stds_Cm_Message_header_sdsEncoder_SF((uint)ISSI, (uint)radioID, 0xC0, cm_msg_id++ % 0xFE, message, false, false); else if (type == 10) data = LIPSDR.Stds_Cm_Message_header_sdsEncoder_SF((uint)ISSI, (uint)radioID, 0xC0, cm_msg_id++ % 0xFE, message, true, false); else if (type == 11) data = LIPSDR.Stds_Cm_Message_header_sdsEncoder_SF((uint)ISSI, (uint)radioID, 0xC0, cm_msg_id++ % 0xFE, message, true, true); else if (type == 01) data = LIPSDR.Stds_Cm_Message_header_sdsEncoder_SF((uint)ISSI, (uint)radioID, 0xC0, cm_msg_id++ % 0xFE, message, false, true); bool resp = Write(data, data.Length); if (resp) Utils.WriteEventLog(Program.COMPANY, String.Format("»»» TM to {0} [{1}]", radioID, message), EventLogEntryType.Information, (int)EventId.EVENT_SMS); else Utils.WriteEventLog(Program.COMPANY, String.Format("φφφ TM not sent to {0} [{1}]", radioID, message), EventLogEntryType.Warning, (int)EventId.EVENT_SMS); SDR.Print(data, data.Length, false); } public void Send_Imed_Loc_req(UInt32 DestISSI, bool isLong, string seqNumber) { byte[] data; data = LIPSDR.Stds_POLL_header_sdsEncoder(ISSI, DestISSI, 10, cm_msg_id++ % 0xFE); //send data bool resp = Write(data, data.Length); if (resp) { Utils.WriteEventLog(Program.COMPANY, "»»» Poll req to " + DestISSI, EventLogEntryType.Information, (int)EventId.EVENT_SDR); } //Console.WriteLine("»»» Poll request to " + DestISSI); else Utils.WriteEventLog(Program.COMPANY, String.Format("φφφ Poll req to {0}", DestISSI), EventLogEntryType.Warning, (int)EventId.EVENT_SDR); SDR.Print(data, data.Length, false); } /// /// Sends the received message through TCP witout any formatting /// /// String containing raw Data which needs to be sent public void Send_RAW_Data(UInt32 DestISSI, String rawData) { Utils.WriteEventLog(Program.COMPANY, String.Format("TO SEND RAW DATA : " + rawData), EventLogEntryType.Information, (int)EventId.EVENT_SDR); byte[] data = new byte[rawData.Length / 2]; for (int i = 0; i < rawData.Length / 2; i++) { data[i] = Convert.ToByte(rawData.Substring(i * 2, 2), 16); } //byte[] data = System.Text.Encoding.UTF8.GetBytes(rawData); bool resp = Write(data, data.Length); if (resp) { Utils.WriteEventLog(Program.COMPANY, "»»» Raw Data to " + DestISSI, EventLogEntryType.Information, (int)EventId.EVENT_SDR); SDR.Print(data, data.Length, false); } else Utils.WriteEventLog(Program.COMPANY, String.Format("φφφ Raw req to {0}", DestISSI), EventLogEntryType.Error, (int)EventId.EVENT_SDR); } #endregion //aux #region AUX public static byte[] addMsgLength(byte[] data) { byte[] retData = new byte[data.Length + 2]; byte[] len = BitConverter.GetBytes(data.Length); retData[0] = len[1]; retData[1] = len[0]; for (int i = 0; i < data.Length; i++) { retData[2 + i] = data[i]; } return retData; } public static void Print(byte[] data, int length, bool inOut) { //Console.Clear(); //Console.WriteLine("--------------------------------------------------------------------------- " + length); //Utils.WriteEventLog(Program.COMPANY, String.Format("Data (" + ((inOut) ? "RECEIVED" : "SENT") + "): "), EventLogEntryType.Information, (int)EventId.EVENT_SDR); StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) { if ((i % 8) == 0) sb.AppendFormat(String.Format(" 0x" + data[i].ToString("X2"))); //Utils.WriteEventLog(Program.COMPANY, String.Format(" 0x" + data[i].ToString("X2")), EventLogEntryType.Information, (int)EventId.EVENT_SDR); } //Console.WriteLine("--------------------------------------------------------------------------- "); string result = sb.ToString().TrimEnd();//when converting to string we also want to trim the redundant new line at the very end Utils.WriteEventLog(Program.COMPANY, String.Format("Data (" + ((inOut) ? "RECEIVED" : "SENT") + "): ") + Environment.NewLine + result + Environment.NewLine + "#############################################", EventLogEntryType.Information, (int)EventId.EVENT_SDR); } #endregion public enum SDR_STATUS { Connected = 0x00, Disconnected = 0x01, Connecting = 0x02, NoConnection = 0x03, Disconnecting = 0x04 } ///// ///// Write a specific message into console ///// ///// Message which needs to be written into console //public static void WriteLine(string str) //{ // WriteLine(str, EventLogEntryType.Information); //} /// /// Write a specific message into console using the desired color /// /// Message which will be written into console /// Color with which the message will be written public static void WriteLine(string str, EventLogEntryType type) { Utils.WriteEventLog(Program.COMPANY, String.Format("[### {0:H:mm:ss} ###] ", DateTime.Now) + Environment.NewLine + String.Format("{0}\n", str), type, (int)EventId.EVENT_SDR); } // EVENTS public delegate void EventToDisplayOnUIDEl(string msg); public delegate void OnSDRStoppedDEl(); public event OnSDRStoppedDEl OnSDRStopped; } }