SafeDispatch/ServiceGatewaySDR/SDR.cs

1438 lines
71 KiB
C#
Raw Permalink Normal View History

2024-02-22 16:43:59 +00:00

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<String, String> radioIdTolastPositionATMessageDictionary = new Dictionary<String, String>();
public static Dictionary<String, PositionData> RadioIdToLastPosDictionary = new Dictionary<string, PositionData>();
public static object calloutUUIDLock = new object();
public static Dictionary<String, uint> radioISSIWithSeverityToCalloutUUIDDictionary = new Dictionary<string, uint>();
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 = "<xml " + out_str + " />";
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);
}
/// <summary>
/// Sends the received message through TCP witout any formatting
/// </summary>
/// <param name="rawData">String containing raw Data which needs to be sent</param>
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
}
///// <summary>
///// Write a specific message into console
///// </summary>
///// <param name="str">Message which needs to be written into console</param>
//public static void WriteLine(string str)
//{
// WriteLine(str, EventLogEntryType.Information);
//}
/// <summary>
/// Write a specific message into console using the desired color
/// </summary>
/// <param name="str">Message which will be written into console</param>
/// <param name="color">Color with which the message will be written</param>
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;
}
}