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 ///// ///// Start a service by it's name ///// ///// //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); // } //} ///// ///// Stop a service that is active ///// ///// //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"); } } /// /// Verify if an IP address is a valid IP address /// /// IP which needs to be checked /// True if the email is a valid one, or false otherwise 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 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 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 getRadioGWsFromDB(Int64 gatewayID, DBgatewaysManager gatewayManager) { List list = gatewayManager.gelAllRadioGateways(gatewayID); List listtoreturn = new List(); 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 }