497 lines
19 KiB
C#
497 lines
19 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.ComponentModel;
|
|||
|
using System.Data;
|
|||
|
using System.Diagnostics;
|
|||
|
using System.Linq;
|
|||
|
using System.ServiceProcess;
|
|||
|
using System.Text;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using System.Timers;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using SafeMobileLib;
|
|||
|
using System.Text.RegularExpressions;
|
|||
|
using SafeMobileLib.Registration;
|
|||
|
using SafeMobileLib.Helpers;
|
|||
|
using System.Configuration;
|
|||
|
using System.Windows.Controls;
|
|||
|
using SDRGatewayService.Enums;
|
|||
|
using System.Threading;
|
|||
|
|
|||
|
namespace SDRGatewayService
|
|||
|
{
|
|||
|
//sc create SDRGatewayService binPath="E:\WorkSpace_cSharp\SafeDispatch_v4\ServiceGatewaySDR\bin\Debug\SDRGatewayService.exe" start= auto
|
|||
|
//C:\Windows\Microsoft.NET\Framework64\v4.0.30319>InstallUtil.exe /u E:\WorkSpace_cSharp\Services\MyNewService\MyNewService\bin\Debug\SDRGatewayService.exe
|
|||
|
public enum ServiceState
|
|||
|
{
|
|||
|
SERVICE_STOPPED = 0x00000001,
|
|||
|
SERVICE_START_PENDING = 0x00000002,
|
|||
|
SERVICE_STOP_PENDING = 0x00000003,
|
|||
|
SERVICE_RUNNING = 0x00000004,
|
|||
|
SERVICE_CONTINUE_PENDING = 0x00000005,
|
|||
|
SERVICE_PAUSE_PENDING = 0x00000006,
|
|||
|
SERVICE_PAUSED = 0x00000007,
|
|||
|
}
|
|||
|
|
|||
|
[StructLayout(LayoutKind.Sequential)]
|
|||
|
public struct ServiceStatus
|
|||
|
{
|
|||
|
public int dwServiceType;
|
|||
|
public ServiceState dwCurrentState;
|
|||
|
public int dwControlsAccepted;
|
|||
|
public int dwWin32ExitCode;
|
|||
|
public int dwServiceSpecificExitCode;
|
|||
|
public int dwCheckPoint;
|
|||
|
public int dwWaitHint;
|
|||
|
};
|
|||
|
|
|||
|
public partial class SDRGatewayService : ServiceBase
|
|||
|
{
|
|||
|
public bool registered = false;
|
|||
|
private int eventId = 1;
|
|||
|
private SDR SDRConnector;
|
|||
|
|
|||
|
[DllImport("advapi32.dll", SetLastError = true)]
|
|||
|
private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus);
|
|||
|
|
|||
|
public SDRGatewayService(string[] args)
|
|||
|
{
|
|||
|
InitializeComponent();
|
|||
|
string eventSourceName = "SDRGatewayServiceSource";
|
|||
|
string logName = "SDRGatewayServiceLog";
|
|||
|
if (args.Count() > 0)
|
|||
|
{
|
|||
|
eventSourceName = args[0];
|
|||
|
}
|
|||
|
if (args.Count() > 1)
|
|||
|
{
|
|||
|
logName = args[1];
|
|||
|
}
|
|||
|
eventLog1 = new System.Diagnostics.EventLog();
|
|||
|
if (!System.Diagnostics.EventLog.SourceExists(eventSourceName))
|
|||
|
{
|
|||
|
System.Diagnostics.EventLog.CreateEventSource(eventSourceName, logName);
|
|||
|
}
|
|||
|
eventLog1.Source = eventSourceName;
|
|||
|
eventLog1.Log = logName;
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
protected override void OnStart(string[] args)
|
|||
|
{
|
|||
|
// Update the service state to Start Pending.
|
|||
|
ServiceStatus serviceStatus = new ServiceStatus();
|
|||
|
serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
|
|||
|
serviceStatus.dwWaitHint = 100000;
|
|||
|
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// Set up a timer to trigger every minute.
|
|||
|
System.Timers.Timer timer = new System.Timers.Timer();
|
|||
|
timer.Interval = 20000; // 60 seconds
|
|||
|
timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
|
|||
|
timer.Start();
|
|||
|
|
|||
|
// Update the service state to Running.
|
|||
|
serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
|
|||
|
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
|
|||
|
|
|||
|
|
|||
|
this.OnRegistrationCompleted += OnRegistrationResponseHandler;
|
|||
|
|
|||
|
Register(true);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public void OnTimer(object sender, ElapsedEventArgs e)
|
|||
|
{
|
|||
|
if (!registered)
|
|||
|
Register(true);
|
|||
|
}
|
|||
|
|
|||
|
protected override void OnStop()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
private void eventLog1_EntryWritten(object sender, EntryWrittenEventArgs e)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//#region Service COntrol
|
|||
|
///// <summary>
|
|||
|
///// Start a service by it's name
|
|||
|
///// </summary>
|
|||
|
///// <param name="ServiceName"></param>
|
|||
|
//public void startService(string ServiceName)
|
|||
|
//{
|
|||
|
// ServiceController sc = new ServiceController();
|
|||
|
// sc.ServiceName = ServiceName;
|
|||
|
|
|||
|
// Console.WriteLine("The {0} service status is currently set to {1}", ServiceName, sc.Status.ToString());
|
|||
|
|
|||
|
// if (sc.Status == ServiceControllerStatus.Stopped)
|
|||
|
// {
|
|||
|
// // Start the service if the current status is stopped.
|
|||
|
// Console.WriteLine("Starting the {0} service ...", ServiceName);
|
|||
|
// try
|
|||
|
// {
|
|||
|
// // Start the service, and wait until its status is "Running".
|
|||
|
// sc.Start();
|
|||
|
// sc.WaitForStatus(ServiceControllerStatus.Running);
|
|||
|
|
|||
|
// // Display the current service status.
|
|||
|
// Console.WriteLine("The {0} service status is now set to {1}.", ServiceName, sc.Status.ToString());
|
|||
|
// }
|
|||
|
// catch (InvalidOperationException e)
|
|||
|
// {
|
|||
|
// Console.WriteLine("Could not start the {0} service.", ServiceName);
|
|||
|
// Console.WriteLine(e.Message);
|
|||
|
// }
|
|||
|
// }
|
|||
|
// else
|
|||
|
// {
|
|||
|
// Console.WriteLine("Service {0} already running.", ServiceName);
|
|||
|
// }
|
|||
|
//}
|
|||
|
|
|||
|
///// <summary>
|
|||
|
///// Stop a service that is active
|
|||
|
///// </summary>
|
|||
|
///// <param name="ServiceName"></param>
|
|||
|
//public void stopService(string ServiceName)
|
|||
|
//{
|
|||
|
// ServiceController sc = new ServiceController();
|
|||
|
// sc.ServiceName = ServiceName;
|
|||
|
|
|||
|
// Console.WriteLine("The {0} service status is currently set to {1}", ServiceName, sc.Status.ToString());
|
|||
|
|
|||
|
// if (sc.Status == ServiceControllerStatus.Running)
|
|||
|
// {
|
|||
|
// // Start the service if the current status is stopped.
|
|||
|
// Console.WriteLine("Stopping the {0} service ...", ServiceName);
|
|||
|
// try
|
|||
|
// {
|
|||
|
// // Start the service, and wait until its status is "Running".
|
|||
|
// sc.Stop();
|
|||
|
// sc.WaitForStatus(ServiceControllerStatus.Stopped);
|
|||
|
|
|||
|
// // Display the current service status.
|
|||
|
// Console.WriteLine("The {0} service status is now set to {1}.", ServiceName, sc.Status.ToString());
|
|||
|
// }
|
|||
|
// catch (InvalidOperationException e)
|
|||
|
// {
|
|||
|
// Console.WriteLine("Could not stop the {0} service.", ServiceName);
|
|||
|
// Console.WriteLine(e.Message);
|
|||
|
// }
|
|||
|
// }
|
|||
|
// else
|
|||
|
// {
|
|||
|
// Console.WriteLine("Cannot stop service {0} because it's already inactive.", ServiceName);
|
|||
|
// }
|
|||
|
//}
|
|||
|
|
|||
|
//public bool IsServiceRunning(string ServiceName)
|
|||
|
//{
|
|||
|
// ServiceController sc = new ServiceController();
|
|||
|
// sc.ServiceName = ServiceName;
|
|||
|
|
|||
|
// if (sc.Status == ServiceControllerStatus.Running)
|
|||
|
// {
|
|||
|
// return true;
|
|||
|
// }
|
|||
|
// else
|
|||
|
// {
|
|||
|
// return false;
|
|||
|
// }
|
|||
|
//}
|
|||
|
//#endregion
|
|||
|
|
|||
|
#region MainForm
|
|||
|
private MessageBuss msgBuss;
|
|||
|
private SMSmanager sms;
|
|||
|
private PingThread pingThread;
|
|||
|
|
|||
|
private Gateway currentGateway = null;
|
|||
|
|
|||
|
UInt32 callOutNumber = 1;
|
|||
|
byte cm_msg_id = 1;
|
|||
|
|
|||
|
public void MainForm()
|
|||
|
{
|
|||
|
Version v = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
|
|||
|
Utils.WriteEventLog(Program.COMPANY, "Version: " + v.ToString() +Environment.NewLine +
|
|||
|
"SDR gateway. SafeMobile 2012-2017", EventLogEntryType.Information, (int)EventId.EVENT_SDR);
|
|||
|
|
|||
|
ConfigurationManager.AppSettings.Set("SDR_Autoconnect", "true");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void pingThread_OnNewPingComplete(bool status, string ip)
|
|||
|
{
|
|||
|
if (status)
|
|||
|
{
|
|||
|
Utils.WriteLine("Ping to " + ip + " succeded");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Utils.WriteLine("Ping to " + ip + " failed");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Verify if an IP address is a valid IP address
|
|||
|
/// </summary>
|
|||
|
/// <param name="ip">IP which needs to be checked</param>
|
|||
|
/// <returns>True if the email is a valid one, or false otherwise</returns>
|
|||
|
bool IsValidIP(string ip)
|
|||
|
{
|
|||
|
Match match = Regex.Match(ip, @"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}");
|
|||
|
return match.Success;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
delegate void PropertyChangedCallback(SDR.SDR_STATUS register);
|
|||
|
void SDRConnector_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
|||
|
{
|
|||
|
Utils.WriteEventLog(Program.COMPANY, "New value for radio status: " + ((SDR)sender).registered, EventLogEntryType.Information, (int)EventId.EVENT_SDR);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private async void Register(bool registered)
|
|||
|
{
|
|||
|
RegistrationResponse regResponse = await RegistrationHelper.RegisterGateway(ConfigHelper.ServerIP, ConfigHelper.RegPort);
|
|||
|
// raise event for registration completed
|
|||
|
OnRegistrationCompleted?.Invoke(regResponse);
|
|||
|
}
|
|||
|
|
|||
|
#region REGISTRATION HANDLER
|
|||
|
private void OnRegistrationResponseHandler(RegistrationResponse regResponse)
|
|||
|
{
|
|||
|
switch (regResponse.RegistrationStatus)
|
|||
|
{
|
|||
|
case RegistrationCode.ServerUnreachable:
|
|||
|
onRegistrationServerUnreachable();
|
|||
|
break;
|
|||
|
case RegistrationCode.Unauthorized:
|
|||
|
onRegistraionUnauthorized();
|
|||
|
break;
|
|||
|
case RegistrationCode.Registered:
|
|||
|
onRegistrationCompleted(regResponse);
|
|||
|
registered = true;
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
//need to add a way to reconnect.
|
|||
|
private void onRegistrationServerUnreachable()
|
|||
|
{
|
|||
|
Utils.WriteEventLog(Program.COMPANY, "Application Server is unreachable. Please check internet connection and the application server IP in the configuration file.", EventLogEntryType.Error, (int)EventId.EVENT_SDR);
|
|||
|
if(!ServiceControlUtils.IsServiceRunning("AppServerService"))
|
|||
|
ServiceControlUtils.startService("AppServerService");
|
|||
|
registered = false;
|
|||
|
}
|
|||
|
//need to add a way to reconnect.
|
|||
|
private void onRegistraionUnauthorized()
|
|||
|
{
|
|||
|
Utils.WriteEventLog(Program.COMPANY, "Please register this gateway in the admin module.", EventLogEntryType.Error, (int)EventId.EVENT_SDR);
|
|||
|
registered = false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private void onRegistrationCompleted(RegistrationResponse response)
|
|||
|
{
|
|||
|
String currentIP = "127.0.0.1";
|
|||
|
|
|||
|
// this gateway is on other computer than the application server is
|
|||
|
if (!ConfigHelper.ServerIP.Equals("127.0.0.1"))
|
|||
|
currentIP = RegistrationHelper.GatewayIP;
|
|||
|
|
|||
|
// update values for Message bus, database received from AppServer
|
|||
|
ConfigurationManager.AppSettings.Set("dbIP", response.DataBaseServerIP);
|
|||
|
ConfigurationManager.AppSettings.Set("dbPassword", response.DataBasePassword);
|
|||
|
ConfigurationManager.AppSettings.Set("dbPort", response.DataBasePort.ToString());
|
|||
|
ConfigurationManager.AppSettings.Set("dbSchema", response.DataBaseName);
|
|||
|
ConfigurationManager.AppSettings.Set("dbUser", response.DataBaseUser);
|
|||
|
ConfigurationManager.AppSettings.Set("busIP", response.MessageBusIP);
|
|||
|
ConfigurationManager.AppSettings.Set("busPort", response.MessageBusPort.ToString());
|
|||
|
|
|||
|
DBgatewaysManager gatewayManager = new DBgatewaysManager(ConfigHelper.DBip, ConfigHelper.DBSchema,
|
|||
|
ConfigHelper.DBUser, ConfigHelper.DBPassword, ConfigHelper.DBPort);
|
|||
|
|
|||
|
// get current gateway
|
|||
|
currentGateway = getGateway(currentIP, gatewayManager);
|
|||
|
|
|||
|
List<RadioGateway> radioGws = getRadioGWsFromDB(currentGateway.Id, gatewayManager);
|
|||
|
|
|||
|
// check if any sdr gateway is defined
|
|||
|
if (radioGws.Count == 0)
|
|||
|
{
|
|||
|
onNoRadioGatewayDefined();
|
|||
|
return;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
RadioGateway currentRadioGw = radioGws[0];
|
|||
|
// search for radioGws with same identifier as this gateway
|
|||
|
foreach (RadioGateway rg in radioGws)
|
|||
|
{
|
|||
|
if (rg.Name.ToLower().Equals(ConfigHelper.GatewayName.ToLower()))
|
|||
|
{
|
|||
|
currentRadioGw = rg;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// update values for current gateway
|
|||
|
ConfigurationManager.AppSettings.Set("SDR_ISSI", currentRadioGw.Imei.ToString());
|
|||
|
ConfigurationManager.AppSettings.Set("SDR_IP", currentRadioGw.Ip);
|
|||
|
|
|||
|
// remove all others gateways from the list
|
|||
|
radioGws.Clear();
|
|||
|
radioGws.Add(currentRadioGw);
|
|||
|
}
|
|||
|
|
|||
|
if (ConfigHelper.SdrPing > 0)
|
|||
|
{
|
|||
|
pingThread = new PingThread(ConfigHelper.SdrIp, ConfigHelper.SdrPing);
|
|||
|
|
|||
|
pingThread.OnNewPingComplete += new PingThread.NewPingCompleteDEl(pingThread_OnNewPingComplete);
|
|||
|
}
|
|||
|
|
|||
|
Utils.WriteEventLog(Program.COMPANY, "Starting application.", EventLogEntryType.Information, (int)EventId.EVENT_SDR);
|
|||
|
SDRConnector = new SDR();
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// set if the message needs to be stored on the server and resent once at X seconds
|
|||
|
SDRConnector.setStoreAndForwardOption(ConfigHelper.SdrStoreTM == 1 ? true : false);
|
|||
|
SDRConnector.PropertyChanged += new PropertyChangedEventHandler(SDRConnector_PropertyChanged);
|
|||
|
//SDRConnector.Start();
|
|||
|
msgBuss = new MessageBuss(ConfigHelper.MsgBusIp, ConfigHelper.MsgBusPort.ToString(), SDRConnector);
|
|||
|
msgBuss.OnPollRequest += delegate (Int64 radioID, bool isLong, string seqNumber)
|
|||
|
{
|
|||
|
SDRConnector.Send_Imed_Loc_req((UInt32)radioID, isLong, seqNumber);
|
|||
|
};
|
|||
|
|
|||
|
msgBuss.OnSDSRequest += delegate (Int64 radioID, Int64 gatewayID, Int64 gatewayRadioID, string message, int type, string seqID)
|
|||
|
{
|
|||
|
SDRConnector.SEND_SMS((uint)radioID, message);
|
|||
|
|
|||
|
Utils.WriteEventLog(Program.COMPANY, "SMSConfirm.getFromConfirmationQueue(hret.seq_no)=" + seqID, EventLogEntryType.Information, (int)EventId.EVENT_SDR);
|
|||
|
string test = "#242#1#";
|
|||
|
|
|||
|
//send SMS ack to message bus
|
|||
|
MessageBuss.SendOnMsgBuss(seqID, test);
|
|||
|
};
|
|||
|
msgBuss.OnUnitsUpdated += delegate ()
|
|||
|
{
|
|||
|
DBvehiclesManager dbVehManager = new DBvehiclesManager(ConfigHelper.DBip, ConfigHelper.DBSchema, ConfigHelper.DBUser, ConfigHelper.DBPassword, ConfigHelper.DBPort);
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
lock (SDR.dictionaryLock)
|
|||
|
{
|
|||
|
SDR.RadioIdToLastPosDictionary = dbVehManager.getImeiLastPosDictionary(true);
|
|||
|
Utils.WriteEventLog(Program.COMPANY, "Received " + SDR.RadioIdToLastPosDictionary.Count + " units", EventLogEntryType.Information, (int)EventId.EVENT_SDR);
|
|||
|
StringBuilder sb = new StringBuilder();
|
|||
|
foreach (var item in SDR.RadioIdToLastPosDictionary)
|
|||
|
{
|
|||
|
sb.AppendFormat("{0:#############}, ", item.Key);
|
|||
|
//Utils.Write(String.Format("{0:#############} |||| ", item.Key), ConsoleType.ALL);
|
|||
|
}
|
|||
|
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);
|
|||
|
}
|
|||
|
};
|
|||
|
msgBuss.OnCallOutRequest += delegate (ulong destISSI, ushort callOutSeverity, string GeoName)
|
|||
|
{
|
|||
|
SDRConnector.SendCallOut((uint)destISSI, callOutSeverity, GeoName);
|
|||
|
};
|
|||
|
msgBuss.OnCallOutStopRequest += delegate (ulong destISSI, ushort callOutSeverity)
|
|||
|
{
|
|||
|
SDRConnector.SendCallOutStop((uint)destISSI, callOutSeverity);
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
|
|||
|
sms = new SMSmanager(SDRConnector);
|
|||
|
|
|||
|
if (ConfigHelper.HasSdrAutoconnect)
|
|||
|
SDRConnector.Start();
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region GATEWAY - RADIO GATEWAY
|
|||
|
|
|||
|
private Gateway getGateway(String gatewayIP, DBgatewaysManager gatewayManager)
|
|||
|
{
|
|||
|
List<Gateway> allGateways = gatewayManager.getAllGateways();
|
|||
|
|
|||
|
foreach (Gateway g in allGateways)
|
|||
|
{
|
|||
|
if (g.Ip == gatewayIP)
|
|||
|
{
|
|||
|
Utils.WriteEventLog(Program.COMPANY, "Gateway IP found in registration tabel. ID: " + g.Id, EventLogEntryType.Information, (int)EventId.EVENT_SDR);
|
|||
|
currentGateway = g;
|
|||
|
ConfigurationManager.AppSettings.Set("id", g.Id.ToString());
|
|||
|
ConfigurationManager.AppSettings.Set("thisIP", g.Ip.ToString());
|
|||
|
|
|||
|
// TODO update thegateway infos in the config file
|
|||
|
return g;
|
|||
|
}
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
private List<RadioGateway> getRadioGWsFromDB(Int64 gatewayID, DBgatewaysManager gatewayManager)
|
|||
|
{
|
|||
|
|
|||
|
List<RadioGateway> list = gatewayManager.gelAllRadioGateways(gatewayID);
|
|||
|
List<RadioGateway> listtoreturn = new List<RadioGateway>();
|
|||
|
foreach (RadioGateway g in list)
|
|||
|
listtoreturn.Add(g);
|
|||
|
|
|||
|
return listtoreturn;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private void onNoRadioGatewayDefined()
|
|||
|
{
|
|||
|
Utils.WriteEventLog(Program.COMPANY, "No SDR controller defined in the admin module for this computer. Please contact your administrator.",
|
|||
|
EventLogEntryType.Error, (int)EventId.EVENT_SDR);
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
private void CloseApp()
|
|||
|
{
|
|||
|
OnStop();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#region EVENTS
|
|||
|
public delegate void RegistrationCompleted(RegistrationResponse response);
|
|||
|
public event RegistrationCompleted OnRegistrationCompleted;
|
|||
|
#endregion
|
|||
|
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|