423 lines
14 KiB
C#
423 lines
14 KiB
C#
|
using System;
|
|||
|
using SafeMobileLib;
|
|||
|
using System.ServiceProcess;
|
|||
|
using SocketIOComponent;
|
|||
|
|
|||
|
namespace AppServer
|
|||
|
{
|
|||
|
public class MainClass
|
|||
|
{
|
|||
|
|
|||
|
public MulticastListener mListener;
|
|||
|
private RecordingsServer rServer;
|
|||
|
private MainForm parent;
|
|||
|
|
|||
|
private String PostrgreSDService = "PostgreSD";
|
|||
|
private String TCPServerService = "TCPClientService";
|
|||
|
private String TCPClientService = "TCPServerService";
|
|||
|
DBsettingsManager dbSettingsManager;
|
|||
|
public static bool isGPSCheckboxChecked = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Listens and sends request on Soket.IO
|
|||
|
/// </summary>
|
|||
|
private SocketIOClass _socketIOClass = null;
|
|||
|
|
|||
|
public MainClass(MainForm _parent)
|
|||
|
{
|
|||
|
// start the postgreSD service just to be sure it is up and running
|
|||
|
if (GetStatus(PostrgreSDService) == ServiceStatus.STOPPED || GetStatus(PostrgreSDService) == ServiceStatus.STOPPING
|
|||
|
|| GetStatus(PostrgreSDService) == ServiceStatus.PAUSED || GetStatus(PostrgreSDService) == ServiceStatus.STATUS_CHANGING)
|
|||
|
ServiceControlUtils.startService(PostrgreSDService);
|
|||
|
|
|||
|
|
|||
|
// start the TCPServerService service just to be sure it is up and running
|
|||
|
if (GetStatus(TCPServerService) == ServiceStatus.STOPPED || GetStatus(TCPServerService) == ServiceStatus.STOPPING
|
|||
|
|| GetStatus(TCPServerService) == ServiceStatus.PAUSED || GetStatus(TCPServerService) == ServiceStatus.STATUS_CHANGING)
|
|||
|
ServiceControlUtils.startService(TCPServerService);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// start the TCPClientService service just to be sure it is up and running
|
|||
|
if (GetStatus(TCPClientService) == ServiceStatus.STOPPED || GetStatus(TCPClientService) == ServiceStatus.STOPPING
|
|||
|
|| GetStatus(TCPClientService) == ServiceStatus.PAUSED || GetStatus(TCPClientService) == ServiceStatus.STATUS_CHANGING)
|
|||
|
ServiceControlUtils.startService(TCPClientService);
|
|||
|
|
|||
|
|
|||
|
string test = Environment.GetEnvironmentVariable("PGPASSWORD");
|
|||
|
if (test == null)
|
|||
|
{
|
|||
|
SM.Debug("Setting Postgress Enviroment password!!!");
|
|||
|
Environment.SetEnvironmentVariable("PGPASSWORD", "wizdemo26", EnvironmentVariableTarget.Machine);
|
|||
|
}
|
|||
|
|
|||
|
rServer = new RecordingsServer();
|
|||
|
parent = _parent;
|
|||
|
}
|
|||
|
|
|||
|
private static bool listenerAdded = false;
|
|||
|
public void Start()
|
|||
|
{
|
|||
|
Utils.WriteLine("START", ConsoleColor.DarkCyan);
|
|||
|
|
|||
|
if (!listenerAdded)
|
|||
|
{
|
|||
|
mListener = new MulticastListener(Program.cfg.msgBusIP, Program.cfg.msgBusPort, parent);
|
|||
|
mListener.OnRefreshHashRequest += mListener_OnRefreshHashRequest;
|
|||
|
mListener.OnDatabaseDown += MListener_OnDatabaseDown;
|
|||
|
mListener.OnEmergencyAckReceived += MListener_OnEmergencyAckReceived;
|
|||
|
mListener.OnPollRequestReceived += MListener_OnPollRequestReceived;
|
|||
|
listenerAdded = true;
|
|||
|
}
|
|||
|
mListener?.Start();
|
|||
|
|
|||
|
// Instantiate socketIOClass only if is null
|
|||
|
// to prevent multiple socket io classes in case of Appserver restart
|
|||
|
|
|||
|
// If Linx version, start listening on Socket.IO
|
|||
|
// Check if socket.IO server and port are saved in database
|
|||
|
dbSettingsManager = new DBsettingsManager(Program.cfg.DB_IP, Program.cfg.DB_schema, Program.cfg.DB_user, Program.cfg.DB_passwd, Program.cfg.DB_port);
|
|||
|
string linxServerIP = dbSettingsManager.getSettingValue(0, "lanLinxServer"); // sipServerIP
|
|||
|
string webServicePort = dbSettingsManager.getSettingValue(0, "lanSigPort"); //webServicePort
|
|||
|
|
|||
|
string uri = $"ws://{linxServerIP}:{webServicePort}";
|
|||
|
if ((_socketIOClass != null && _socketIOClass.Uri != uri) || _socketIOClass == null)
|
|||
|
{
|
|||
|
Utils.WriteLine($"SocketIO on {linxServerIP}:{webServicePort}", ConsoleColor.DarkCyan);
|
|||
|
if (!string.IsNullOrEmpty(linxServerIP) && !string.IsNullOrEmpty(webServicePort))
|
|||
|
{
|
|||
|
System.Net.IPAddress linxIP = null;
|
|||
|
int socketIoPort = -1;
|
|||
|
if (System.Net.IPAddress.TryParse(linxServerIP, out linxIP) && int.TryParse(webServicePort, out socketIoPort))
|
|||
|
{
|
|||
|
_socketIOClass?.Disconect();
|
|||
|
_socketIOClass = new SocketIOClass(uri);
|
|||
|
_socketIOClass.ArsReceived += ArsReceivedOnSocketIO;
|
|||
|
_socketIOClass.GpsReceived += GpsReceivedOnSocketIO;
|
|||
|
_socketIOClass.PollReceived += PollResponseReceivedOnSocketIO;
|
|||
|
_socketIOClass.EmergencyReceived += EmergencyReceivedOnSocketIO;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#region SocketIO class event handlers
|
|||
|
|
|||
|
private void GpsReceivedOnSocketIO(object sender, GpsReceivedEventArgs e)
|
|||
|
{
|
|||
|
if (e.Gps == null || e.Gps.UserID == null)
|
|||
|
return;
|
|||
|
|
|||
|
string radioID = "0";
|
|||
|
if (MulticastListener.MobileVehicleList.ContainsKey(e.Gps.UserID))
|
|||
|
radioID = (String)MulticastListener.MobileVehicleList[e.Gps.UserID];
|
|||
|
|
|||
|
|
|||
|
Utils.WriteLine($"GpsReceivedOnSocketIO - imei:{radioID}|sip:{e.Gps.SipID} [{e.Gps.Lat:0.0000},{e.Gps.Lng:0.0000}]", ConsoleColor.DarkGreen);
|
|||
|
|
|||
|
// add location parameters to an array
|
|||
|
String[] toSendString = new String[4];
|
|||
|
toSendString[0] = e.Gps.UnitTime / 1000 + "";
|
|||
|
toSendString[1] = e.Gps.SpeedKmh + "";
|
|||
|
toSendString[2] = e.Gps.Lat + "";
|
|||
|
toSendString[3] = e.Gps.Lng + "";
|
|||
|
|
|||
|
// create the location message
|
|||
|
byte[] data = createLocationMessage((int)MessageBusCmds.LocationReceived,
|
|||
|
radioID.ToString(), toSendString);
|
|||
|
|
|||
|
// add location to message bus
|
|||
|
MainForm.udp.Send(data, data.Length);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
private void PollResponseReceivedOnSocketIO(object sender, GpsReceivedEventArgs e)
|
|||
|
{
|
|||
|
if (e.Gps == null || e.Gps.UserID == null)
|
|||
|
return;
|
|||
|
|
|||
|
string radioID = "0";
|
|||
|
if (MulticastListener.MobileVehicleList.ContainsKey(e.Gps.UserID))
|
|||
|
radioID = (String)MulticastListener.MobileVehicleList[e.Gps.UserID];
|
|||
|
|
|||
|
|
|||
|
Utils.WriteLine($"PollResponseReceivedOnSocketIO - imei:{radioID}|sip:{e.Gps.SipID} [{e.Gps.Lat:0.0000},{e.Gps.Lng:0.0000}]", ConsoleColor.DarkGreen);
|
|||
|
|
|||
|
// add location parameters to an array
|
|||
|
String[] toSendString = new String[4];
|
|||
|
toSendString[0] = e.Gps.UnitTime / 1000 + "";
|
|||
|
toSendString[1] = e.Gps.SpeedKmh + "";
|
|||
|
toSendString[2] = e.Gps.Lat + "";
|
|||
|
toSendString[3] = e.Gps.Lng + "";
|
|||
|
|
|||
|
// create the location message
|
|||
|
byte[] data = createLocationMessage((int)MessageBusCmds.PollResponseReceived,
|
|||
|
radioID.ToString(), toSendString);
|
|||
|
|
|||
|
// add location to message bus
|
|||
|
MainForm.udp.Send(data, data.Length);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Create a Location Message that can be sent on message bus
|
|||
|
/// </summary>
|
|||
|
/// <param name="opCode">GPS Location operation code</param>
|
|||
|
/// <param name="suid">Radio id of the unit</param>
|
|||
|
/// <param name="dataString">Position data</param>
|
|||
|
/// <returns></returns>
|
|||
|
public static byte[] createLocationMessage(int opCode, string suid, String[] dataString)
|
|||
|
{
|
|||
|
string msg = "";
|
|||
|
msg = "#1." + (Utils.GetSecondsLocalFromDT(DateTime.Now)) + DateTime.Now.Millisecond.ToString() + "#" + opCode + "#" + suid + "#";
|
|||
|
msg = msg + dataString[0] + "#" + dataString[1] + "#" + dataString[2] + "#" + dataString[3];
|
|||
|
int totalSize = 5 + msg.Length;
|
|||
|
string sizeMsg = String.Format("#{0:000}", totalSize);
|
|||
|
msg = sizeMsg + msg;
|
|||
|
|
|||
|
Byte[] toSendMulticast = new Byte[totalSize];
|
|||
|
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
|
|||
|
Byte[] toSendMulticastPartial = encoding.GetBytes(msg);
|
|||
|
for (int i = 0; i < toSendMulticastPartial.Length; i++)
|
|||
|
{
|
|||
|
toSendMulticast[i] = toSendMulticastPartial[i];
|
|||
|
}
|
|||
|
toSendMulticast[totalSize - 1] = 35;
|
|||
|
|
|||
|
return toSendMulticast;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Event handler for an emergency message received via SocketIO
|
|||
|
/// </summary>
|
|||
|
/// <param name="sender"></param>
|
|||
|
/// <param name="e"></param>
|
|||
|
private void EmergencyReceivedOnSocketIO(object sender, EmergencyReceivedEventArgs e)
|
|||
|
{
|
|||
|
if (e.Emergency == null || e.Emergency.UserID == null)
|
|||
|
return;
|
|||
|
|
|||
|
Utils.WriteLine("EmergencyReceivedOnSocketIO " + e.Emergency.SipID, ConsoleColor.DarkGreen);
|
|||
|
|
|||
|
string radioID = "0";
|
|||
|
if (e.Emergency.UserID == null)
|
|||
|
return;
|
|||
|
if (MulticastListener.MobileVehicleList.ContainsKey(e.Emergency.UserID))
|
|||
|
radioID = (String)MulticastListener.MobileVehicleList[e.Emergency.UserID];
|
|||
|
|
|||
|
// handle the emergency received
|
|||
|
mListener?.onEmergencyReceivedHandler(e.Emergency.SequenceId, radioID, e.Emergency.EmergencyType, e.Emergency);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private void ArsReceivedOnSocketIO(object sender, ArsReceivedEventArgs e)
|
|||
|
{
|
|||
|
if (e.Ars == null || e.Ars.UserID == null)
|
|||
|
return;
|
|||
|
|
|||
|
Utils.WriteLine("ArsReceivedOnSocketIO " + e.Ars.SipID, ConsoleColor.DarkGreen);
|
|||
|
// new ars received
|
|||
|
string radioID = "0";
|
|||
|
|
|||
|
if (MulticastListener.MobileVehicleList.ContainsKey(e.Ars.UserID))
|
|||
|
radioID = (String)MulticastListener.MobileVehicleList[e.Ars.UserID];
|
|||
|
|
|||
|
|
|||
|
if (MainForm.VehicleHashStat[radioID] != null)
|
|||
|
{
|
|||
|
((VehicleStatus)MainForm.VehicleHashStat[radioID]).lastArsTime = DateTime.Now;
|
|||
|
|
|||
|
// do not push any status update if the current status is emergency
|
|||
|
if (((VehicleStatus)MainForm.VehicleHashStat[radioID]).curentStatus == Status_for_tab.EMERG)
|
|||
|
return;
|
|||
|
|
|||
|
DBsubsOperationManager dbsubsoperManage = new DBsubsOperationManager(Program.cfg.DB_IP, Program.cfg.DB_schema, Program.cfg.DB_user, Program.cfg.DB_passwd, Program.cfg.DB_port);
|
|||
|
|
|||
|
dbsubsoperManage?.updateSUStatus(radioID, e.Ars.Ars ? 1 : 0);
|
|||
|
if (!e.Ars.Ars)
|
|||
|
{
|
|||
|
((VehicleStatus)MainForm.VehicleHashStat[radioID]).curentStatus = Status_for_tab.OFF;
|
|||
|
MulticastListener.PushStatus(radioID, Status_for_tab.OFF);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
if (MainForm.VehStolen.ContainsKey(radioID) && (int)MainForm.VehStolen[radioID] == 1)
|
|||
|
{
|
|||
|
Utils.WriteLine("ARS received on SocketIO for a stolen vehicle " + radioID, ConsoleColor.Cyan);
|
|||
|
}
|
|||
|
|
|||
|
((VehicleStatus)MainForm.VehicleHashStat[radioID]).curentStatus = Status_for_tab.ON;
|
|||
|
MulticastListener.PushStatus(radioID, Status_for_tab.ON);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
mListener.dbuser.SetUserStateForSipID(Int32.Parse(e.Ars.SipID), e.Ars.Ars);
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Callback for when an emergency ack is received over the MessageBus
|
|||
|
/// </summary>
|
|||
|
/// <param name="seqID">Unique identifier for the emergency ack</param>
|
|||
|
/// <param name="radioID">The unit that needs to receive the emergency ack</param>
|
|||
|
private void MListener_OnEmergencyAckReceived(string seqID, string radioID)
|
|||
|
{
|
|||
|
String scId = "";
|
|||
|
String sipId = "";
|
|||
|
|
|||
|
if (MainForm.VehList.ContainsKey(radioID))
|
|||
|
{
|
|||
|
scId = ((Vehicle_Data)MainForm.VehList[radioID]).sc_id + "";
|
|||
|
sipId = ((Vehicle_Data)MainForm.VehList[radioID]).sip_id + "";
|
|||
|
}
|
|||
|
|
|||
|
EmergencyAckInfo emergAckInfo = new EmergencyAckInfo()
|
|||
|
{
|
|||
|
SequenceId = seqID,
|
|||
|
SipID = sipId,
|
|||
|
UserID = scId,
|
|||
|
WhoAckId = "0",
|
|||
|
WhoAckSipId = "0"
|
|||
|
};
|
|||
|
_socketIOClass?.SendEmergencyAck(emergAckInfo);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Callback for when a poll request is received over the MessageBus
|
|||
|
/// </summary>
|
|||
|
/// <param name="seqID">Unique identifier for the poll request</param>
|
|||
|
/// <param name="radioID">The unit that needs to receive the poll request</param>
|
|||
|
private void MListener_OnPollRequestReceived(string seqID, string radioID)
|
|||
|
{
|
|||
|
String scId = "";
|
|||
|
String sipId = "";
|
|||
|
|
|||
|
|
|||
|
if (!MainForm.VehList.ContainsKey(radioID))
|
|||
|
return;
|
|||
|
|
|||
|
// do not continue to send the poll request over socketIO because the unit is not a mobile one
|
|||
|
if (((Vehicle_Data)MainForm.VehList[radioID]).type != 1)
|
|||
|
return;
|
|||
|
|
|||
|
// get scId and sipId for required radioID
|
|||
|
scId = ((Vehicle_Data)MainForm.VehList[radioID]).sc_id + "";
|
|||
|
sipId = ((Vehicle_Data)MainForm.VehList[radioID]).sip_id + "";
|
|||
|
|
|||
|
// pack the poll request
|
|||
|
PollRequestInfo pollReqInfo = new PollRequestInfo()
|
|||
|
{
|
|||
|
SequenceId = seqID,
|
|||
|
SipID = sipId,
|
|||
|
UserID = scId,
|
|||
|
};
|
|||
|
|
|||
|
// send the request over the socketIO
|
|||
|
_socketIOClass?.SendPollRequest(pollReqInfo);
|
|||
|
}
|
|||
|
|
|||
|
private void MListener_OnDatabaseDown()
|
|||
|
{
|
|||
|
// DB is down
|
|||
|
ServiceControlUtils.startService("PostgreSD");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void mListener_OnRefreshHashRequest()
|
|||
|
{
|
|||
|
Utils.WriteLine("DELEGATE ", ConsoleColor.Red);
|
|||
|
OnRefreshHashRequest?.Invoke();
|
|||
|
isGPSCheckboxChecked = IsGPSCheckboxChecked();
|
|||
|
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
DBemailServiceManager DB = new DBemailServiceManager(Program.cfg.DB_IP, Program.cfg.DB_schema, Program.cfg.DB_user, Program.cfg.DB_passwd, Program.cfg.DB_port);
|
|||
|
|
|||
|
Program.cfg.enableEmailService = DB.GetEmailServiceSettings().Enable;
|
|||
|
|
|||
|
|
|||
|
if (Program.cfg.enableEmailService)
|
|||
|
{
|
|||
|
SM.Debug("EmailService on");
|
|||
|
}
|
|||
|
|
|||
|
else
|
|||
|
{
|
|||
|
SM.Debug("Email Service is not enabled");
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
Utils.WriteLine("mListener_OnRefreshHashRequest error: " + ex.ToString(), ConsoleColor.DarkMagenta);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public Boolean IsGPSCheckboxChecked()
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
string EmergencyOnly = dbSettingsManager.getSettingValue(0, DBsettingsManager.EMERGENCY_ONLY_KEY);
|
|||
|
|
|||
|
if (EmergencyOnly.Trim().Equals("false") || EmergencyOnly.Trim().Equals(""))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
Utils.WriteLine("Error GPSCheckboxChecked: " + ex.ToString(), ConsoleColor.Red);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public enum ServiceStatus { RUNNING, STOPPED, PAUSED, STOPPING, STARTING, STATUS_CHANGING, NOT_INSTALLED };
|
|||
|
|
|||
|
public static ServiceStatus GetStatus(string serviceName)
|
|||
|
{
|
|||
|
ServiceController sc = new ServiceController(serviceName);
|
|||
|
try
|
|||
|
{
|
|||
|
switch (sc.Status)
|
|||
|
{
|
|||
|
case ServiceControllerStatus.Running:
|
|||
|
return ServiceStatus.RUNNING;
|
|||
|
case ServiceControllerStatus.Stopped:
|
|||
|
return ServiceStatus.STOPPED;
|
|||
|
case ServiceControllerStatus.Paused:
|
|||
|
return ServiceStatus.PAUSED;
|
|||
|
case ServiceControllerStatus.StopPending:
|
|||
|
return ServiceStatus.STOPPING;
|
|||
|
case ServiceControllerStatus.StartPending:
|
|||
|
return ServiceStatus.STARTING;
|
|||
|
default:
|
|||
|
return ServiceStatus.STATUS_CHANGING;
|
|||
|
}
|
|||
|
}
|
|||
|
catch
|
|||
|
{
|
|||
|
return ServiceStatus.NOT_INSTALLED;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public delegate void RefreshHashRequest();
|
|||
|
public event RefreshHashRequest OnRefreshHashRequest;
|
|||
|
}
|
|||
|
}
|