SafeDispatch/AppServer/MainClass.cs
2024-02-22 18:43:59 +02:00

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;
}
}