2024-02-22 16:43:59 +00:00
using System ;
using System.Collections.Generic ;
using System.Drawing ;
using System.Linq ;
using System.Windows.Forms ;
using System.Threading ;
using RegLibDLL ;
using System.Diagnostics ;
using SafeMobileLib ;
using System.Runtime.InteropServices ;
using System.Collections ;
using System.Net.Mail ;
using System.IO ;
using SharedUI ;
using SafeMobileLib.Helpers ;
using System.IO.Pipes ;
using System.Threading.Tasks ;
using System.Timers ;
using Newtonsoft.Json ;
using SafeMobileLib.WebsocketClient ;
using System.Data ;
using System.ComponentModel ;
namespace AppServer
{
public partial class MainForm : Form
{
private static Int64 DB_NUMBER_OF_INSERTS = 100000 ;
public static readonly short FEEDBACK_INTERACTION_WAIT_TIME_SEC = 7 ;
public static Boolean isRunning = true ;
public static Boolean error = false ;
private Int32 regPort = 5680 ;
private RegLib regLib ;
private bool errorOnScreen = false ;
private Int32 ErrorCount = 0 ;
public MainClass m = null ;
public static Boolean withConsole = false ;
public static String fileName = "" ;
DBregistrationManager regManager ;
DBRadioTypeManager radioTypeManager ;
DBvehiclesManager vehManager ;
public static DBsettingsManager dbSettings ;
public static bool IS_SIERRA_WIRELESS = false ;
private DBsubsOperationManager dbsub ;
public static InterthreadMessageQueue < string > LocationQueue ;
public static InterthreadMessageQueue < string > prevLocationQueue ;
public static InterthreadMessageQueue < UnitDataToSend > websocketLocationQueue ;
public static InterthreadMessageQueue < MailMessage > ReportEmailQueue ; ///need to use this queue
public volatile static Hashtable VehListWithGroupDetails = new Hashtable ( ) ;
public volatile static Hashtable VehList = new Hashtable ( ) ;
public volatile static Hashtable userReportTimeList = new Hashtable ( ) ;
public volatile static Hashtable VehStolen = new Hashtable ( ) ;
public volatile static Hashtable VehicleHashStat = new Hashtable ( ) ;
public volatile static Boolean AIRTURKEYLIMIT = false ;
public volatile static UdpMulticast udp ;
public static Boolean UdpMulticastConnectionStatus = false ;
public static volatile bool ZonesBussy = false ;
/// <summary>
/// hash table used for gateway statuses (message 500, 501, 503)
/// </summary>
internal static volatile Hashtable RadioGWHash = new Hashtable ( ) ;
internal static Hashtable userStateHash = new Hashtable ( ) ;
public volatile static Boolean SendPOLLafterSMS = false ;
public volatile static Int32 CountInsert = 0 ;
public volatile static Boolean RegistrationAnswer = false ;
public static uint recordings = 0 ;
public static String GPS_Queue_File = "gps_queue.txt" ;
public static List < GatewayRegistration > allGateways = new List < GatewayRegistration > ( ) ;
[DllImportAttribute("user32.dll")]
public static extern int SendMessage ( IntPtr hWnd , int Msg , int wParam , int lParam ) ;
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture ( ) ;
public const int WM_NCLBUTTONDOWN = 0xA1 ;
public const int HT_CAPTION = 0x2 ;
// background colors for each panel, they will change at runtime with ones from the UI
private Color softwareColor = Color . Teal ;
private Color mapColor = Color . Crimson ;
private Color featuresColor = Color . FromArgb ( 202 , 80 , 0 ) ;
// Type of panels with licenses
private enum LicensePanel { SOFTWARE , MAP , FEATURES } ;
private LicensePanel prevLicensePanel = LicensePanel . SOFTWARE ;
public RADIOTYPE RadioType = RADIOTYPE . MOTO ;
public static Int32 Job_ticking_count = 0 ;
public System . Timers . Timer gwCheckTimer = new System . Timers . Timer ( ) ;
//Websocket
public static System . Timers . Timer sendWebsocketTimer = new System . Timers . Timer ( ) ;
public static System . Timers . Timer checkWebsocketServerStatus = new System . Timers . Timer ( ) ;
public static Boolean hasDBAccess ;
public static String dbAccess ;
private WebsocketThread websocket = null ;
2024-06-13 11:03:34 +00:00
public static Dictionary < string , int > blackListAddress = new Dictionary < string , int > ( ) ;
public const int MAX_ATTEMPTS = 100 ;
2024-02-22 16:43:59 +00:00
public delegate void UpdateLicensesUIInvokeCallBack ( ) ;
public MainForm ( )
{
FireWallException fw = new FireWallException ( ) ;
string name = System . AppDomain . CurrentDomain . FriendlyName ;
string path = System . Windows . Forms . Application . ExecutablePath ;
fw . checkFirewall ( name , path ) ;
//for loging
SM debug = new SM ( ) ;
Version v = System . Reflection . Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version ;
Console . WriteLine ( "Version: " + v . ToString ( ) ) ;
LocationQueue = new InterthreadMessageQueue < string > ( ) ;
prevLocationQueue = new InterthreadMessageQueue < string > ( ) ;
ReportEmailQueue = new InterthreadMessageQueue < MailMessage > ( ) ;
websocketLocationQueue = new InterthreadMessageQueue < UnitDataToSend > ( ) ;
gwCheckTimer . Elapsed + = new ElapsedEventHandler ( CheckGatewayStatus ) ;
gwCheckTimer . Interval = 10000 ;
gwCheckTimer . Enabled = true ;
sendWebsocketTimer . Elapsed + = new ElapsedEventHandler ( SendLocationToWebSocketHandler ) ;
sendWebsocketTimer . Interval = Program . cfg . websocketTimer ;
checkWebsocketServerStatus . Elapsed + = new ElapsedEventHandler ( BroadcastWebSocketStatusOnMessageBus ) ;
checkWebsocketServerStatus . Interval = 5000 ;
//test id app is already running
bool shoulLoadThisOne = testIfAlreadyRunning ( ) ;
// the test for application that is already running will return false only if the app
// already running but doesn't require to be closed, meaning this instance should be closed
if ( ! shoulLoadThisOne )
{
Program . SHOULD_LOAD = false ;
}
// continue with loading this instance because no other one is running
else
ContinueConstructor ( ) ;
Thread t = new Thread ( HandleUnitStatus ) ;
t . IsBackground = true ;
t . Start ( ) ;
}
private void ContinueConstructor ( )
{
InitializeComponent ( ) ;
// customize the new FeedbackRadMessageBox
FeedbackRadMessageBox . InteractionWaitSeconds = FEEDBACK_INTERACTION_WAIT_TIME_SEC ;
FeedbackRadMessageBox . SetTheme ( "TelerikMetroBlue" ) ;
// register for restart event
FeedbackRadMessageBox . OnRestartRequest + = delegate ( )
{
Utils . WriteLine ( "AppServer needs to be restarted" , ConsoleColor . Cyan ) ;
RestartApp ( ) ;
} ;
String dongleError = "" ;
regLib = new RegLibDLL . RegLib ( ) ;
RegStatus regStatus = RegStatus . UNKNOWN ;
if ( regLib . demoMode )
{
regStatus = RegStatus . VALID_DEMO ;
SM . Debug ( "AppServer in demo mode: " + regLib . remainingTime ( ) + " seconds remaining" ) ;
if ( regLib . remainingTime ( ) < = 1 )
{
regStatus = RegStatus . DEMO_EXPIRED ;
error = true ;
}
Job_ticking_count = ( regLib . jobTicketingCount ( ) > 0 & & regLib . jobTicketingCount ( ) < = regLib . safeDispatchCount ( ) ) ? regLib . jobTicketingCount ( ) : 0 ;
}
else
{
if ( ! regLib . dongleDetected ( ) )
{
regStatus = RegStatus . DONGLE_MISSING ;
dongleError = "Dongle missing." ;
error = true ;
}
else
{
regStatus = RegStatus . VALID_DONGLE ;
if ( ! regLib . validData ( ) )
{
dongleError = "No valid data found on dongle" ;
regStatus = RegStatus . DONGLE_NOT_INITIALIZED ;
error = true ;
}
else
{
if ( ! regLib . isCorrectHID ( ) )
{
regStatus = RegStatus . DONGLE_INVALID_HID ;
dongleError = "Incorrect dongle HID" ;
error = true ;
}
else
{
Job_ticking_count = ( regLib . jobTicketingCount ( ) > 0 & & regLib . jobTicketingCount ( ) < = regLib . safeDispatchCount ( ) ) ? regLib . jobTicketingCount ( ) : 0 ;
}
}
}
}
this . WindowState = FormWindowState . Minimized ;
this . Visible = false ;
notifyIcon1 . Visible = true ;
notifyIcon1 . ShowBalloonTip ( 500 ) ;
try
{
Utils . WriteEventLog ( Program . COMPANY , "AppServer ON" , EventLogEntryType . Information , 3152 ) ;
}
catch ( Exception ex )
{
SM . Debug ( "Unable to write log Event ex:" + ex . ToString ( ) ) ;
}
ContextMenu contextMenu = new ContextMenu ( ) ;
contextMenu . MenuItems . Add ( "Check for updates..." , ( s , e ) = > {
UpdateForm uf = new UpdateForm ( App . APP_SERVER , true ) { IsDevelop = Program . cfg . isDevelop } ;
uf . Show ( ) ;
} ) ;
contextMenu . MenuItems . Add ( "Exit" , ( s , e ) = > CloseApp ( ) ) ;
notifyIcon1 . ContextMenu = contextMenu ;
if ( ! error )
{
m = new MainClass ( this ) ;
// gestion reset event
m . OnRefreshHashRequest + = delegate ( )
{
ReportEmailQueue = new InterthreadMessageQueue < MailMessage > ( ) ;
Thread . Sleep ( 500 ) ;
m . Start ( ) ;
// update UI
this . Invoke ( ( MethodInvoker ) delegate ( )
{
UpdateLicensesUI ( ) ;
} ) ;
} ;
regPort = Program . cfg . regPort ;
//test if we can connect to DB
testDBconnection ( ) ;
//start main class
m . Start ( ) ;
LocationThread LocationConnection = new LocationThread ( ) ;
Thread LocThreadObj = new Thread ( new ThreadStart ( LocationConnection . handleConnection ) ) ;
LocThreadObj . IsBackground = true ;
LocThreadObj . Start ( ) ;
RegistrationThread RegistrationConnection = new RegistrationThread ( regPort , Program . cfg . DB_IP , Program . cfg . DB_schema , Program . cfg . DB_user ,
Program . cfg . DB_passwd , Program . cfg . DB_port ) ;
Thread LocationThreadObj = new Thread ( new ThreadStart ( RegistrationConnection . handleConnection ) ) ;
LocationThreadObj . IsBackground = true ;
LocationThreadObj . Start ( ) ;
}
else
{
String dialogMessage = "Invalid dongle. Please insert a valid dongle and restart the Application Server" ;
String dialogTitle = "Application Server Invalid Dongle" ;
// display other messages based on the error type
switch ( regStatus )
{
case RegStatus . DEMO_EXPIRED :
{
dialogMessage = $"Your demo period had expired. Please contact {Program.COMPANY} if you want to extend it." ;
dialogTitle = "Application Server Demo Expired" ;
break ;
}
case RegStatus . DONGLE_INVALID_HID :
{
dialogMessage = $"Your dongle has an invalid HID value. Please contact {Program.COMPANY} in order to reconfigure the dongle." ;
dialogTitle = "Application Server Dongle Invalid HID" ;
break ;
}
case RegStatus . DONGLE_MISSING :
{
dialogMessage = $"Your dongle is missing. Please connect the dongle if not connected, or change the port if already connected. Then restart Application Server." ;
dialogTitle = "Application Server Dongle Missing" ;
break ;
}
case RegStatus . DONGLE_NOT_INITIALIZED :
{
dialogMessage = $"Your dongle is not initialized or contains invalid data. Please contact {Program.COMPANY} in order to reconfigure the dongle." ;
dialogTitle = "Application Server Demo Expired" ;
break ;
}
}
FeedbackRadMessageBox . InteractionWaitSeconds = 15 ;
FeedbackRadMessageBox . ShowError ( dialogMessage , dialogTitle ) ;
FeedbackRadMessageBox . InteractionWaitSeconds = FEEDBACK_INTERACTION_WAIT_TIME_SEC ;
Environment . Exit ( 0 ) ;
}
// update UI
UpdateLicensesUI ( ) ;
//set DB Access Licence
dbAccess = regLib . dbAccessCount ( ) . ToString ( ) ;
MainForm . hasDBAccess = ( dbAccess . Equals ( "1" ) ? true : false ) ;
Utils . WriteLine ( "3rd Party API WebSocket: " + hasDBAccess . ToString ( ) ) ;
if ( hasDBAccess )
{
ThreadStart action = ( ) = > {
ConfigureWebSocket ( ) ;
} ;
Thread thread = new Thread ( action ) { IsBackground = true } ;
thread . Start ( ) ;
}
softwareColor = circularUnits . ProgressCircleColor ;
mapColor = circularGoogle . ProgressCircleColor ;
featuresColor = circularLive . ProgressCircleColor ;
// change the active panel in order to color the circular menus
ChangeFocusedLicensesGroup ( LicensePanel . SOFTWARE ) ;
}
2024-06-13 11:03:34 +00:00
public static void HandleTimeoutError ( string mailAdr )
{
// add address to backlist
if ( ! blackListAddress . ContainsKey ( mailAdr ) )
blackListAddress . Add ( mailAdr , MAX_ATTEMPTS ) ;
}
public static bool IsBlacklistedAddress ( string mailAdr )
{
if ( ! blackListAddress . ContainsKey ( mailAdr ) )
return false ;
// avoid to send the email MAX_ATTEMPTS times => give another chance to try to send email when count = 0
int count = blackListAddress [ mailAdr ] ;
if ( count = = 0 )
{
blackListAddress . Remove ( mailAdr ) ;
return false ;
}
blackListAddress [ mailAdr ] = count - 1 ;
return true ;
}
2024-02-22 16:43:59 +00:00
private void ConfigureWebSocket ( )
{
if ( ! checkWebsocketServerStatus . Enabled )
checkWebsocketServerStatus . Enabled = true ;
if ( ! sendWebsocketTimer . Enabled )
sendWebsocketTimer . Enabled = true ;
BackgroundWorker webSocketWorker = new BackgroundWorker ( ) ;
websocket = WebsocketThread . Instance ;
websocket . host = Program . cfg . websocketUrl ;
Utils . WriteLine ( "Setting 3rd Party API WebSocket host: " + Program . cfg . websocketUrl , ConsoleColor . Yellow ) ;
//websocket.StartWebsocket();
webSocketWorker . DoWork + = websocket . StartWebsocket ;
webSocketWorker . RunWorkerAsync ( ) ;
}
/// <summary>
/// Restart the application and close other notify icons
/// </summary>
public void RestartApp ( )
{
CloseNotifyIcon ( ) ;
Program . isRunning = false ;
Thread p = new Thread ( new ThreadStart ( delegate ( )
{
Process . Start ( System . Reflection . Assembly . GetExecutingAssembly ( ) . Location , String . Join ( " " , Program . cmdArgs ) ) ;
CloseApp ( ) ;
} ) ) ;
p . Start ( ) ;
}
private void CloseApp ( )
{
Process oldProcess = Process . GetCurrentProcess ( ) ;
oldProcess . Kill ( ) ;
Application . Exit ( ) ;
}
/// <summary>
/// Hide the notify icon method. This will cause the right bottom icon to be hide
/// </summary>
private void CloseNotifyIcon ( )
{
if ( notifyIcon1 ! = null )
{
notifyIcon1 . Visible = false ;
notifyIcon1 . Icon = null ;
notifyIcon1 . Dispose ( ) ;
}
}
2024-06-05 11:00:51 +00:00
private string get_radio_type ( )
{
string radio_type = string . Empty ;
// if radio_type isn't saved in db => check folder's name
System . IO . DirectoryInfo myDirectory = new DirectoryInfo ( Environment . CurrentDirectory ) ;
// get parent directory
string parentDirectory = myDirectory . Parent . FullName ;
DirectoryInfo dInfo = new DirectoryInfo ( parentDirectory ) ;
DirectoryInfo [ ] subdirs = dInfo . GetDirectories ( ) ;
foreach ( DirectoryInfo folder in subdirs )
{
if ( folder . Name = = "Gateway" ) { radio_type = ( ( int ) RADIOTYPE . MOTO ) . ToString ( ) ; break ; }
else if ( folder . Name = = "Hytera" ) { radio_type = ( ( int ) RADIOTYPE . HYT ) . ToString ( ) ; break ; }
else if ( folder . Name = = "Momentum" ) { radio_type = ( ( int ) RADIOTYPE . HARRIS ) . ToString ( ) ; break ; }
else if ( folder . Name = = "Astro" ) { radio_type = ( ( int ) RADIOTYPE . ATLAS ) . ToString ( ) ; break ; }
else if ( folder . Name = = "Tetra" ) { radio_type = ( ( int ) RADIOTYPE . TETRA ) . ToString ( ) ; break ; }
else if ( folder . Name = = "Connect Plus" ) { radio_type = ( ( int ) RADIOTYPE . CONECTPLUS ) . ToString ( ) ; break ; }
else if ( folder . Name = = "Repeater_Gateway" ) { radio_type = ( ( int ) RADIOTYPE . REPEATER_TRBO ) . ToString ( ) ; break ; }
else if ( folder . Name = = "SMC_Gateway" ) { radio_type = ( ( int ) RADIOTYPE . MOTO ) . ToString ( ) ; break ; }
else if ( folder . Name = = "Simoco" ) { radio_type = ( ( int ) RADIOTYPE . SIMOCO ) . ToString ( ) ; break ; }
else if ( folder . Name = = "Sepura3T_SDR" ) { radio_type = ( ( int ) RADIOTYPE . LISF ) . ToString ( ) ; break ; }
}
return radio_type ;
}
2024-02-22 16:43:59 +00:00
/// <summary>
/// Update the UI licenses circular controllers. This will read the dongle licenses
/// and the ones from the DB and the display them in the UI.
/// </summary>
private void UpdateLicensesUI ( )
{
Version v = System . Reflection . Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version ;
2024-06-05 11:00:51 +00:00
String [ ] appname = this . Text . Split ( " " . ToCharArray ( ) ) ;
2024-02-22 16:43:59 +00:00
this . Text = appname [ 0 ] + " " + v . ToString ( ) ;
lbVersion . Text = "Version " + v . ToString ( ) ;
2024-06-05 11:00:51 +00:00
2024-02-22 16:43:59 +00:00
//check radio type from database to set job ticketing to visible
if ( Program . cfg = = null )
return ;
2024-06-05 11:00:51 +00:00
2024-02-22 16:43:59 +00:00
radioTypeManager = new DBRadioTypeManager ( Program . cfg . DB_IP , Program . cfg . DB_schema , Program . cfg . DB_user , Program . cfg . DB_passwd , Program . cfg . DB_port ) ;
dbSettings = new DBsettingsManager ( Program . cfg . DB_IP , Program . cfg . DB_schema , Program . cfg . DB_user , Program . cfg . DB_passwd , Program . cfg . DB_port ) ;
string radio_type = radioTypeManager . getRadioType ( ) ;
if ( radio_type = = "" )
{
2024-06-05 11:00:51 +00:00
radio_type = get_radio_type ( ) ;
2024-02-22 16:43:59 +00:00
//save radiotype in db
radioTypeManager . setRadioType ( radio_type ) ;
}
2024-06-05 11:00:51 +00:00
2024-02-22 16:43:59 +00:00
if ( radio_type ! = "" )
RadioType = ( RADIOTYPE ) Enum . Parse ( typeof ( RADIOTYPE ) , radio_type ) ;
lbLicTicketing . Visible = circularTicketing . Visible = pbTicketing . Visible = labelTicketing . Visible = ( RadioType = = RADIOTYPE . MOTO | | RadioType = = RADIOTYPE . REPEATER_TRBO ) ;
lbLicTelemetry . Visible = circularTelemetry . Visible = pbTicketing . Visible = labelTelemetry . Visible
= ( RadioType = = RADIOTYPE . MOTO | | RadioType = = RADIOTYPE . REPEATER_TRBO | | RadioType = = RADIOTYPE . HYT | | RadioType = = RADIOTYPE . HARRIS ) ;
2024-06-05 11:00:51 +00:00
circularSDM . Visible = pbSDM . Visible = labelSDM . Visible = lbLicSDM . Visible = ( RadioType = = RADIOTYPE . SIMOCO ) ;
2024-02-22 16:43:59 +00:00
// change logo icon depending on the system type
2024-06-05 11:00:51 +00:00
pbLogo . Image = ( RadioType = = RADIOTYPE . SIMOCO ) ? AppServer . Properties . Resources . simoco :
AppServer . Properties . Resources . safemobile ;
2024-02-22 16:43:59 +00:00
if ( error )
{
if ( regLib . demoMode )
{
2024-06-05 11:00:51 +00:00
lbRegistrationStatus . Text = ( regLib . remainingTime ( ) = = 1 ) ? "Demo invalidated, please contact " + Program . COMPANY : "Demo registration expired" ; ;
lbRegistrationStatus . ForeColor = Color . DarkRed ;
2024-02-22 16:43:59 +00:00
}
}
else
{
if ( regLib . demoMode )
{
lbRegistrationStatus . Text = "trial ends in " + ( regLib . remainingTime ( ) / 86400 ) . ToString ( ) + " days " ;
lbRegistrationStatus . ForeColor = Color . Yellow ;
}
2024-06-05 11:00:51 +00:00
2024-02-22 16:43:59 +00:00
regManager = new DBregistrationManager ( Program . cfg . DB_IP , Program . cfg . DB_schema , Program . cfg . DB_user , Program . cfg . DB_passwd , Program . cfg . DB_port ) ;
vehManager = new DBvehiclesManager ( Program . cfg . DB_IP , Program . cfg . DB_schema , Program . cfg . DB_user , Program . cfg . DB_passwd , Program . cfg . DB_port ) ;
dbsub = new DBsubsOperationManager ( Program . cfg . DB_IP , Program . cfg . DB_schema , Program . cfg . DB_user , Program . cfg . DB_passwd , Program . cfg . DB_port ) ;
2024-06-05 11:00:51 +00:00
2024-02-22 16:43:59 +00:00
uint gpsCount = regManager . getGPSCount ( ) ;
uint smsCount = regManager . getSMSCount ( ) ;
uint reportsCount = regManager . getReportsCount ( ) ;
uint voiceCount = regManager . getVoiceCount ( ) ;
uint zonesCount = regManager . getZonesCount ( ) ;
uint telemetryCount = regManager . getTelemetryCount ( ) ;
uint GoogleCount = regManager . getGoogleCount ( ) ;
uint MapUSCount = regManager . getMapsUSCount ( ) ;
uint OSMCount = regManager . getOSMCount ( ) ;
uint ArcgisCount = regManager . getMapsArcgisCount ( ) ;
allGateways = regManager . getAllGateways ( ) ;
int gatewaysCount = allGateways . Count ( ) ;
uint ticketingCount = regManager . getTicketingCount ( ) ;
uint recordingsCount = recordings = regManager . getRecordingsCount ( ) ;
int allSDCount = regManager . getAllSafeDispatches ( ) . Count ( ) ;
#region VALUES
int nrOfUnits = regLib . getNumberOfUnits ( ) ;
// detect if Sierra Wireless
IS_SIERRA_WIRELESS = dbsub . IsSierraWireless ( ) ;
int totaldbunits = 0 ;
uint nrOfUnitsInDB = ( uint ) vehManager . getActiveVehiclesCount ( nrOfUnits , IS_SIERRA_WIRELESS , out totaldbunits ) ;
circularUnits . MinValue = ( nrOfUnits > 0 ) ? 0 : - 1 ;
circularUnits . MaxValue = regLib . getNumberOfUnits ( ) ;
circularUnits . Value = ( nrOfUnitsInDB > circularUnits . MaxValue
? circularUnits . MaxValue : nrOfUnitsInDB ) ;
lbLicUnits . Text = circularUnits . Value + " of " + circularUnits . MaxValue ;
int nrSD = regLib . safeDispatchCount ( ) ;
circularSD . MinValue = ( nrSD > 0 ) ? 0 : - 1 ;
circularSD . MaxValue = regLib . safeDispatchCount ( ) ;
circularSD . Value = ( allSDCount > circularSD . MaxValue
? circularSD . MaxValue : allSDCount ) ;
lbLicSD . Text = circularSD . Value + " of " + circularSD . MaxValue ;
int sdmCount = regLib . SDMobileCount ( ) ;
circularSDM . MinValue = ( sdmCount > 0 & & sdmCount < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
circularSDM . MaxValue = ( ( sdmCount > regLib . safeDispatchCount ( ) ) ? 0 : sdmCount ) ;
circularSDM . Value = 0 ;
lbLicSDM . Text = circularSDM . Value + " of " + circularSDM . MaxValue ;
int nrGateways = regLib . gatewayCount ( ) ;
circularGateways . MinValue = ( nrGateways > 0 & & nrGateways < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
circularGateways . MaxValue = regLib . gatewayCount ( ) ;
circularGateways . Value = ( gatewaysCount > circularGateways . MaxValue
? circularGateways . MaxValue : gatewaysCount ) ;
lbLicGateways . Text = circularGateways . Value + " of " + circularGateways . MaxValue ;
// set values for maps licenses
int nrGoogle = regLib . mapType1Count ( ) ;
circularGoogle . MinValue = ( nrGoogle > 0 & & nrGoogle < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
circularGoogle . MaxValue = regLib . mapType1Count ( ) ;
circularGoogle . Value = ( GoogleCount > circularGoogle . MaxValue
? circularGoogle . MaxValue : GoogleCount ) ;
lbLicGoogle . Text = circularGoogle . Value + " of " + circularGoogle . MaxValue ;
int nrArcGis = regLib . mapType4Count ( ) ;
circularArcGis . MinValue = ( nrArcGis > 0 & & nrArcGis < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
circularArcGis . MaxValue = regLib . mapType4Count ( ) ;
circularArcGis . Value = ( ArcgisCount > circularArcGis . MaxValue
? circularArcGis . MaxValue : ArcgisCount ) ;
lbLicArcGis . Text = circularArcGis . Value + " of " + circularArcGis . MaxValue ;
int nrOSM = regLib . mapType3Count ( ) ;
circularOSM . MinValue = ( nrOSM > 0 & & nrOSM < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
circularOSM . MaxValue = regLib . mapType3Count ( ) ;
circularOSM . Value = ( OSMCount > circularOSM . MaxValue
? circularOSM . MaxValue : OSMCount ) ;
lbLicOSM . Text = circularOSM . Value + " of " + circularOSM . MaxValue ;
// set values for features licenses
int nrGPS = regLib . gpsCount ( ) ;
circularLive . MinValue = ( nrGPS > 0 & & nrGPS < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
circularLive . MaxValue = regLib . gpsCount ( ) ;
circularLive . Value = ( gpsCount > circularLive . MaxValue
? circularLive . MaxValue : gpsCount ) ;
lbLicLive . Text = circularLive . Value + " of " + circularLive . MaxValue ;
int nrVoice = regLib . voiceCount ( ) ;
circularVoice . MinValue = ( nrVoice > 0 & & nrVoice < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
//circularVoice.MaxValue = ((nrVoice > regLib.safeDispatchCount()) ? 0 : nrVoice);
circularVoice . MaxValue = regLib . voiceCount ( ) ;
uint nrOfVoice = regManager . getVoiceCount ( ) ;
circularVoice . Value = ( nrOfVoice > circularVoice . MaxValue ?
circularVoice . MaxValue : nrOfVoice ) ;
lbLicVoice . Text = circularVoice . Value + " of " + circularVoice . MaxValue ;
int nrText = regLib . smsCount ( ) ;
circularText . MinValue = ( nrText > 0 & & nrText < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
circularText . MaxValue = regLib . smsCount ( ) ;
circularText . Value = ( smsCount > circularText . MaxValue
? circularText . MaxValue : smsCount ) ;
lbLicText . Text = circularText . Value + " of " + circularText . MaxValue ;
int nrTicketing = regLib . jobTicketingCount ( ) ;
circularTicketing . MinValue = ( nrTicketing > 0 & & nrTicketing < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
//circularTicketing.MaxValue = ((nrTicketing > regLib.safeDispatchCount()) ? 0 : nrTicketing);
circularTicketing . MaxValue = regLib . jobTicketingCount ( ) ;
circularTicketing . Value = ( ticketingCount > circularTicketing . MaxValue
? circularTicketing . MaxValue : ticketingCount ) ;
lbLicTicketing . Text = circularTicketing . Value + " of " + circularTicketing . MaxValue ;
int nrReports = regLib . reportsCount ( ) ;
circularReports . MinValue = ( nrReports > 0 & & nrReports < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
circularReports . MaxValue = nrReports ;
circularReports . Value = ( reportsCount > circularReports . MaxValue
? circularReports . MaxValue : reportsCount ) ;
lbLicReports . Text = circularReports . Value + " of " + circularReports . MaxValue ;
int nrZones = regLib . zonesCount ( ) ;
circularZones . MinValue = ( nrZones > 0 & & nrZones < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
circularZones . MaxValue = nrZones ;
circularZones . Value = ( zonesCount > circularZones . MaxValue
? circularZones . MaxValue : zonesCount ) ;
lbLicEmail . Text = circularZones . Value + " of " + circularZones . MaxValue ;
int nrTelem = regLib . telemetryCount ( ) ;
circularTelemetry . MinValue = ( nrTelem > 0 & & nrTelem < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
circularTelemetry . MaxValue = regLib . telemetryCount ( ) ;
circularTelemetry . Value = ( telemetryCount > circularTelemetry . MaxValue
? circularTelemetry . MaxValue : telemetryCount ) ;
lbLicTelemetry . Text = circularTelemetry . Value + " of " + circularTelemetry . MaxValue ;
int nrRecordings = regLib . recordingsCount ( ) ;
circularRecordings . MinValue = ( nrRecordings > 0 & & nrRecordings < = regLib . safeDispatchCount ( ) ) ? 0 : - 1 ;
circularRecordings . MaxValue = regLib . recordingsCount ( ) ;
circularRecordings . Value = ( recordingsCount > circularRecordings . MaxValue
? circularRecordings . MaxValue : recordingsCount ) ;
lbLicRecordings . Text = circularRecordings . Value + " of " + circularRecordings . MaxValue ;
#endregion
if ( regLib . AIRTURKEYLIMIT )
{
AIRTURKEYLIMIT = true ;
lbRegistrationRemaining . Text = "Demo 1.10.2014 - 1.05.2015" ;
}
if ( gpsCount > regLib . gpsCount ( ) | | smsCount > regLib . smsCount ( ) | | reportsCount > regLib . reportsCount ( )
| | voiceCount > regLib . voiceCount ( ) | | zonesCount > regLib . zonesCount ( )
| | telemetryCount > regLib . telemetryCount ( )
| | GoogleCount > regLib . mapType1Count ( ) | | MapUSCount > regLib . mapType2Count ( )
| | OSMCount > regLib . mapType3Count ( ) | | ArcgisCount > regLib . mapType4Count ( )
| | ticketingCount > regLib . jobTicketingCount ( ) | | recordingsCount > regLib . recordingsCount ( ) )
{
regManager . resetSafeDispatchRegistrations ( ) ;
lbRegistrationRemaining . Text = "Database licenses reset" ;
}
2024-06-05 11:00:51 +00:00
2024-02-22 16:43:59 +00:00
if ( gatewaysCount > regLib . gatewayCount ( ) )
regManager . removeAllGatewayRegistrations ( ) ;
}
}
/// <summary>
/// Intercept mouse move on all the items of the form
/// </summary>
/// <param name="sender">UI object which raised the event</param>
/// <param name="e">Mouse event parameters</param>
private void MainForm_MouseMove ( object sender , MouseEventArgs e )
{
// move form window if mouse moved with mouse pressed
if ( e . Button = = MouseButtons . Left )
{
ReleaseCapture ( ) ;
SendMessage ( Handle , WM_NCLBUTTONDOWN , HT_CAPTION , 0 ) ;
}
// get mouse position relative to the form
var relativePoint = this . PointToClient ( Cursor . Position ) ;
// detect which panel is active
LicensePanel panel = LicensePanel . SOFTWARE ;
if ( relativePoint . Y > = dividerFeature . Location . Y )
panel = LicensePanel . FEATURES ;
else if ( relativePoint . Y > dividerMap . Location . Y )
panel = LicensePanel . MAP ;
else
panel = LicensePanel . SOFTWARE ;
// change UI only if prev panel is different
if ( panel ! = prevLicensePanel )
{
// change the focused licenses panel
ChangeFocusedLicensesGroup ( panel ) ;
}
// save previous panel
prevLicensePanel = panel ;
}
/// <summary>
/// Change the circle color according to the mouse position and the
/// focused panel of licenses
/// </summary>
/// <param name="panel">The corresponding panel which is active</param>
private void ChangeFocusedLicensesGroup ( LicensePanel panel )
{
foreach ( Control ctrl in this . Controls )
{
if ( ctrl is CircularProgressBar . CircularProgressBar )
{
CircularProgressBar . CircularProgressBar circular = ( CircularProgressBar . CircularProgressBar ) ctrl ;
circular . ProgressCircleColor = Color . DarkGray ;
circular . InnerCircleColor = Color . DarkGray ;
circular . OuterCircleColor = Color . DarkGray ;
}
}
dividerSoftware . BackColor = Color . DarkGray ;
dividerMap . BackColor = Color . DarkGray ;
dividerFeature . BackColor = Color . DarkGray ;
lbFeatureLicenses . ForeColor = Color . DarkGray ;
lbMapLicenses . ForeColor = Color . DarkGray ;
lbSoftwareLicenses . ForeColor = Color . DarkGray ;
lbSoftwareLicenses . Text = "Software Licenses" ;
lbMapLicenses . Text = "Map Licenses" ;
lbFeatureLicenses . Text = "Feature Licenses" ;
pbFeatureLicenses . Image = Properties . Resources . feature ;
pbSoftwareLicenses . Image = Properties . Resources . software ;
pbMapLicenses . Image = Properties . Resources . maps ;
// detect panel lower and higher Y coordinates
int minY = 0 , maxY = 0 ;
Color toPrintColor = softwareColor ;
switch ( panel )
{
case LicensePanel . SOFTWARE :
{
// get panel coordinates and color in which needs to be printed
toPrintColor = softwareColor ;
dividerSoftware . BackColor = softwareColor ;
lbSoftwareLicenses . ForeColor = Color . FromArgb ( 211 , 211 , 211 ) ;
pbSoftwareLicenses . Image = Properties . Resources . software_over ;
lbSoftwareLicenses . Text = "Software Licenses" ;
minY = 0 ;
maxY = dividerMap . Location . Y ;
break ;
}
case LicensePanel . MAP :
{
// get panel coordinates and color in which needs to be printed
toPrintColor = mapColor ;
lbMapLicenses . ForeColor = Color . FromArgb ( 211 , 211 , 211 ) ;
pbMapLicenses . Image = Properties . Resources . maps_over ;
dividerMap . BackColor = mapColor ;
lbMapLicenses . Text = "Map Licenses" ;
minY = dividerMap . Location . Y ;
maxY = dividerFeature . Location . Y ;
break ;
}
case LicensePanel . FEATURES :
{
// get panel coordinates and color in which needs to be printed
toPrintColor = featuresColor ;
dividerFeature . BackColor = featuresColor ;
lbFeatureLicenses . ForeColor = Color . FromArgb ( 211 , 211 , 211 ) ;
pbFeatureLicenses . Image = Properties . Resources . feature_over ;
lbFeatureLicenses . Text = "Feature Licenses" ;
minY = dividerFeature . Location . Y ;
maxY = 1000 ;
break ;
}
}
foreach ( Control ctrl in this . Controls )
{
if ( ctrl is CircularProgressBar . CircularProgressBar )
{
CircularProgressBar . CircularProgressBar circular = ( CircularProgressBar . CircularProgressBar ) ctrl ;
if ( circular . Location . Y > = minY & & circular . Location . Y < maxY )
{
circular . ProgressCircleColor = toPrintColor ;
circular . InnerCircleColor = toPrintColor ;
circular . OuterCircleColor = toPrintColor ;
}
}
}
}
private void notifyIcon1_DoubleClick ( object sender , EventArgs e )
{
this . Visible = true ;
this . WindowState = FormWindowState . Normal ;
notifyIcon1 . Visible = false ;
}
private void MainForm_Resize ( object sender , EventArgs e )
{
if ( this . WindowState = = FormWindowState . Minimized )
{
this . Visible = false ;
notifyIcon1 . Visible = true ;
}
}
private void MainForm_Load ( object sender , EventArgs e )
{
LoadLocationQueueFromFile ( ) ;
gwCheckTimer . Start ( ) ;
#region SOFTWARE LICENSES
circularUnits . Controls . Add ( labelUnits ) ;
labelUnits . Location = new Point ( 29 , 63 ) ;
labelUnits . BackColor = Color . Transparent ;
circularUnits . Controls . Add ( pbUnits ) ;
pbUnits . Location = new Point ( 26 , 14 ) ;
pbUnits . BackColor = Color . Transparent ;
circularSD . Controls . Add ( labelSD ) ;
labelSD . Location = new Point ( 23 , 63 ) ;
labelSD . BackColor = Color . Transparent ;
circularSD . Controls . Add ( pbSD ) ;
pbSD . Location = new Point ( 26 , 16 ) ;
pbSD . BackColor = Color . Transparent ;
circularGateways . Controls . Add ( labelGateways ) ;
labelGateways . Location = new Point ( 23 , 63 ) ;
labelGateways . BackColor = Color . Transparent ;
circularGateways . Controls . Add ( pbGateways ) ;
pbGateways . Location = new Point ( 27 , 16 ) ;
pbGateways . BackColor = Color . Transparent ;
circularSDM . Controls . Add ( labelSDM ) ;
labelSDM . Location = new Point ( 22 , 63 ) ;
labelSDM . BackColor = Color . Transparent ;
circularSDM . Controls . Add ( pbSDM ) ;
pbSDM . Location = new Point ( 31 , 21 ) ;
pbSDM . BackColor = Color . Transparent ;
#endregion
#region MAPS
circularGoogle . Controls . Add ( labelGoogle ) ;
labelGoogle . Location = new Point ( 20 , 63 ) ;
labelGoogle . BackColor = Color . Transparent ;
circularGoogle . Controls . Add ( pbGoogle ) ;
pbGoogle . Location = new Point ( 27 , 16 ) ;
pbGoogle . BackColor = Color . Transparent ;
circularArcGis . Controls . Add ( pbArcGis ) ;
pbArcGis . Location = new Point ( 29 , 21 ) ;
pbArcGis . BackColor = Color . Transparent ;
circularArcGis . Controls . Add ( labelArcGis ) ;
labelArcGis . Location = new Point ( 25 , 63 ) ;
labelArcGis . BackColor = Color . Transparent ;
circularOSM . Controls . Add ( pbOSM ) ;
pbOSM . Location = new Point ( 29 , 21 ) ;
pbOSM . BackColor = Color . Transparent ;
circularOSM . Controls . Add ( labelOSM ) ;
labelOSM . Location = new Point ( 25 , 63 ) ;
labelOSM . BackColor = Color . Transparent ;
#endregion
#region FEATURE LICENSES
circularLive . Controls . Add ( pbLive ) ;
pbLive . Location = new Point ( 29 , 21 ) ;
pbLive . BackColor = Color . Transparent ;
circularLive . Controls . Add ( labelLive ) ;
labelLive . Location = new Point ( 24 , 63 ) ;
labelLive . BackColor = Color . Transparent ;
circularVoice . Controls . Add ( pbVoice ) ;
pbVoice . Location = new Point ( 29 , 21 ) ;
pbVoice . BackColor = Color . Transparent ;
circularVoice . Controls . Add ( labelVoice ) ;
labelVoice . Location = new Point ( 24 , 63 ) ;
labelVoice . BackColor = Color . Transparent ;
circularText . Controls . Add ( pbText ) ;
pbText . Location = new Point ( 29 , 21 ) ;
pbText . BackColor = Color . Transparent ;
circularText . Controls . Add ( labelText ) ;
labelText . Location = new Point ( 24 , 63 ) ;
labelText . BackColor = Color . Transparent ;
circularTicketing . Controls . Add ( pbTicketing ) ;
pbTicketing . Location = new Point ( 29 , 21 ) ;
pbTicketing . BackColor = Color . Transparent ;
circularTicketing . Controls . Add ( labelTicketing ) ;
labelTicketing . Location = new Point ( 24 , 63 ) ;
labelTicketing . BackColor = Color . Transparent ;
circularReports . Controls . Add ( pbReports ) ;
pbReports . Location = new Point ( 31 , 21 ) ;
pbReports . BackColor = Color . Transparent ;
circularReports . Controls . Add ( labelReports ) ;
labelReports . Location = new Point ( 24 , 63 ) ;
labelReports . BackColor = Color . Transparent ;
circularZones . Controls . Add ( pbZones ) ;
pbZones . Location = new Point ( 29 , 21 ) ;
pbZones . BackColor = Color . Transparent ;
circularZones . Controls . Add ( labelZones ) ;
labelZones . Location = new Point ( 22 , 63 ) ;
labelZones . BackColor = Color . Transparent ;
circularTelemetry . Controls . Add ( pbTelemetry ) ;
pbTelemetry . Location = new Point ( 27 , 21 ) ;
pbTelemetry . BackColor = Color . Transparent ;
circularTelemetry . Controls . Add ( labelTelemetry ) ;
labelTelemetry . Location = new Point ( 21 , 63 ) ;
labelTelemetry . BackColor = Color . Transparent ;
circularRecordings . Controls . Add ( pbRecordings ) ;
pbRecordings . Location = new Point ( 29 , 21 ) ;
pbRecordings . BackColor = Color . Transparent ;
circularRecordings . Controls . Add ( labelRecordings ) ;
labelRecordings . Location = new Point ( 24 , 63 ) ;
labelRecordings . BackColor = Color . Transparent ;
#endregion
if ( ! error )
{
this . Visible = false ;
}
if ( udp ! = null )
{
byte [ ] heartbeatMsg = SafeMobileLib . Utils . Convert_text_For_multicast ( "#0.0#507#" ) ;
udp . Send ( heartbeatMsg , heartbeatMsg . Length ) ;
}
// check for a new version if available
if ( Program . cfg . autoupdate )
CheckForUpdate ( ) ;
}
/// <summary>
/// Test if the App Server is already running
/// </summary>
private bool testIfAlreadyRunning ( )
{
Process [ ] processlist = Process . GetProcesses ( ) ;
Process curentP = Process . GetCurrentProcess ( ) ;
int count = 0 ;
foreach ( Process theprocess in processlist )
{
if ( theprocess . ProcessName = = curentP . ProcessName )
{
count + + ;
}
}
if ( count > 1 )
{
SM . Debug ( "App already running!!!" ) ;
foreach ( Process theprocess in processlist )
{
if ( theprocess . ProcessName = = curentP . ProcessName )
{
Console . WriteLine ( "Process: {0} ID: {1}" , theprocess . ProcessName , theprocess . Id ) ;
Console . WriteLine ( "Curent Process: {0} ID: {1}" , curentP . ProcessName , curentP . Id ) ;
if ( theprocess . Id ! = curentP . Id )
{
Console . WriteLine ( "Killing Process: {0} ID: {1}" , theprocess . ProcessName , theprocess . Id ) ;
try
{
theprocess . Kill ( ) ;
}
catch ( NotSupportedException )
{
Utils . WriteLine ( "Process already killed!" , ConsoleColor . Yellow ) ;
}
catch ( Exception ex )
{
Utils . WriteLine ( "Fatal error!\n" + ex . ToString ( ) , ConsoleColor . Red ) ;
}
}
}
}
Thread . Sleep ( 1000 ) ;
return true ;
}
return true ;
}
private void testDBconnection ( )
{
DBmanager DB = new DBmanager ( Program . cfg . DB_IP , Program . cfg . DB_schema , Program . cfg . DB_user , Program . cfg . DB_passwd , Program . cfg . DB_port ) ;
try
{
DB . InitConnection ( ) ;
2024-06-05 11:00:51 +00:00
DB . CloseConnection ( ) ;
2024-02-22 16:43:59 +00:00
}
catch ( Exception ex )
{
SM . Debug ( ex . ToString ( ) ) ;
FeedbackRadMessageBox . ShowError ( "DB connection failed!!!Please check database settings and restart appServer!!!" , "AppServer - Database Error" ) ;
try
{
Utils . WriteEventLog ( Program . COMPANY , "AppServer OFF test DB connection" , EventLogEntryType . Information , 3152 ) ;
}
catch ( Exception exe )
{
SM . Debug ( "Unable to write log Event ex:" + exe . ToString ( ) ) ;
}
try
{
DB . CloseConnection ( ) ;
DB . InitConnection ( ) ;
}
catch ( Exception exe )
{
try
2024-06-27 10:17:09 +00:00
{
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0.0#210#4#AppServer stoped#" ) ;
udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
}
catch ( Exception ex2 )
{
SM . Debug ( "Error on sending Message to SD that APPServer has problem: " + ex2 . ToString ( ) ) ;
}
SM . Debug ( exe . ToString ( ) ) ;
notifyIcon1 . Dispose ( ) ;
// remove timers and other UI stuffs
MainForm_FormClosing ( this , null ) ;
// kill AppServer process
CloseApp ( ) ;
}
}
}
private int heartbeatWaitStep = 0 ;
private void Check_dongle_timer_Tick ( object sender , EventArgs e )
{
if ( udp = = null )
return ;
// increment at each 1000 ms tick of the timer
heartbeatWaitStep + + ;
// send heartbeat message if step is larger than number of seconds
if ( heartbeatWaitStep > = SafeMobileLib . Modules . AppServerMonitoring . APP_SERVER_HEARTBEAT_SEC )
{
byte [ ] heartbeatMsg = SafeMobileLib . Utils . Convert_text_For_multicast ( "#0.0#507#" ) ;
udp . Send ( heartbeatMsg , heartbeatMsg . Length ) ;
heartbeatWaitStep = 0 ;
}
if ( ! regLib . findDongle ( ) & & ! errorOnScreen )
{
if ( ! regLib . demoMode )
{
ErrorCount + + ;
if ( ErrorCount > 10 )
{
errorOnScreen = true ;
error = true ;
try
2024-06-27 10:17:09 +00:00
{
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0.0#210#2#Dongle missing Application server stopped#" ) ;
udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
}
catch ( Exception ex2 )
{
SM . Debug ( "Error on sending Message to SD that APPServer has problem: " + ex2 . ToString ( ) ) ;
}
try
{
Utils . WriteEventLog ( Program . COMPANY , "AppServer OFF Dongle missing" , EventLogEntryType . Information , 3152 ) ;
}
catch ( Exception exe )
{
SM . Debug ( "Unable to write log Event ex:" + exe . ToString ( ) ) ;
}
String dialogMessage = "Invalid dongle. Please insert a valid dongle and restart the Application Server" ;
String dialogTitle = "Application Server Invalid Dongle" ;
FeedbackRadMessageBox . InteractionWaitSeconds = 60 ;
FeedbackRadMessageBox . ShowError ( dialogMessage , dialogTitle ) ;
FeedbackRadMessageBox . InteractionWaitSeconds = FEEDBACK_INTERACTION_WAIT_TIME_SEC ;
// remove timers and other UI stuffs
MainForm_FormClosing ( this , null ) ;
// kill AppServer process
CloseApp ( ) ;
}
}
}
else ErrorCount = 0 ;
if ( CountInsert > DB_NUMBER_OF_INSERTS ) // 50000) //100000
{
Utils . WriteLine ( "Insert number is " + CountInsert , ConsoleColor . Cyan ) ;
// dump the gps queue to a file
// TODO
ProcessTick ( ) ;
}
}
public static void LoadLocationQueueFromFile ( )
{
// restore location queue
if ( File . Exists ( GPS_Queue_File ) )
{
// empty the previous queue file
prevLocationQueue . Clear ( ) ;
List < String > prevGpsMessages = SerializationHelper . DesirializeWithLinq ( GPS_Queue_File ) ;
prevLocationQueue . PostItems ( prevGpsMessages ) ;
Utils . WriteLine ( $"Loaded {prevGpsMessages.Count} positions from offline cached file" , ConsoleColor . Yellow ) ;
try
{
File . Delete ( GPS_Queue_File ) ;
}
catch ( Exception ex )
{
// unable to delete previous queue file
Utils . WriteLine ( "Exception when deleting previous gps queue file : " + ex . ToString ( ) , ConsoleColor . Red ) ;
}
}
}
public static void DumpLocationQueueToFile ( )
{
// write location queue to a file
if ( MainForm . LocationQueue . Count > 0 | | MainForm . prevLocationQueue . Count > 0 )
{
List < string > allPositions = MainForm . LocationQueue . ToList ( ) ;
allPositions . AddRange ( MainForm . prevLocationQueue . ToList ( ) ) ;
SerializationHelper . SerializeWithLinq ( allPositions , GPS_Queue_File ) ;
Utils . WriteLine ( $"Wrote {allPositions.Count} GPS messages from the queue into a file" , ConsoleColor . Yellow ) ;
}
}
/// <summary>
/// Populate the Websocket Location Queue and call the timer method to send the data
/// </summary>
/// <param name="radioID"></param>
/// <param name="lat"></param>
/// <param name="lng"></param>
/// <param name="speed"></param>
/// <param name="unit_time"></param>
public static void CheckLocationQueueAndSendToWebSocket ( string radioID , double lat , double lng , int speed , uint unit_time ,
String heading , Status_for_tab status )
{
Int64 radioId = 0 ;
bool parseResult = Int64 . TryParse ( radioID . Trim ( ) , out radioId ) ;
// skip any unit that is not
if ( parseResult & & radioId < 12000 & & radioId > 12999 )
{
return ;
}
UnitDataToSend data = new UnitDataToSend ( ) ;
data . radio_id = radioID ;
data . lat = lat ;
data . lng = lng ;
data . speed = speed ;
data . unix_time = unit_time ;
if ( VehListWithGroupDetails . ContainsKey ( radioID ) )
data . GroupName = ( ( Vehicles ) VehListWithGroupDetails [ radioID ] ) . GroupName ;
data . Heading = heading ;
data . GpsState = status . ToString ( ) ;
// get group name for the radioId
MainForm . websocketLocationQueue . PostItem ( data ) ;
2024-06-27 10:17:09 +00:00
if ( ! sendWebsocketTimer . Enabled )
2024-02-22 16:43:59 +00:00
sendWebsocketTimer . Enabled = true ;
2024-06-27 10:17:09 +00:00
2024-02-22 16:43:59 +00:00
if ( ! checkWebsocketServerStatus . Enabled )
checkWebsocketServerStatus . Enabled = true ;
}
private void BroadcastWebSocketStatusOnMessageBus ( object source , ElapsedEventArgs e )
{
2024-06-05 11:00:51 +00:00
//string message; //$"#0.0#{failoverStatusToMessBuss}#{configHelper.PCIp}#{msg}#{master}#";
2024-02-22 16:43:59 +00:00
2024-06-05 11:00:51 +00:00
string status = "offline" ;
IWebsocketClient iWebsocketClient = WebsocketThread . Instance . getClient ( ) ;
if ( iWebsocketClient ! = null )
status = iWebsocketClient . IsRunning ? "online" : "offline" ;
2024-02-22 16:43:59 +00:00
2024-06-05 11:00:51 +00:00
string message = $"#0.0#{Utils.enumConvertToString(MessageBusCmds.WebsocketStatusToMsgBus)}#{status}#" ;
2024-02-22 16:43:59 +00:00
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( message ) ;
2024-06-05 11:00:51 +00:00
if ( dataToSend ! = null & & dataToSend . Length > 0 )
udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
}
private void MainForm_FormClosing ( object sender , FormClosingEventArgs e )
{
// stop the dongle timer
Check_dongle_timer ? . Stop ( ) ;
//stop gatewaycheck
gwCheckTimer . Stop ( ) ;
sendWebsocketTimer . Stop ( ) ;
checkWebsocketServerStatus . Stop ( ) ;
WebsocketThread . _client ? . Dispose ( ) ;
// save all unhandled gps positions
DumpLocationQueueToFile ( ) ;
if ( Program . cfg . watchdog )
Program . KillWatchDog ( ) ;
try
{
CloseNotifyIcon ( ) ;
Utils . WriteEventLog ( Program . COMPANY , "AppServer OFF on close" , EventLogEntryType . Information , 3152 ) ;
}
catch ( Exception ex )
{
SM . Debug ( "Unable to write log Event ex:" + ex . ToString ( ) ) ;
}
try
{
2024-06-27 10:17:09 +00:00
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( $"#0.0#{Utils.enumConvertToString(MessageBusCmds.WebsocketStatusToMsgBus)}#offline#" ) ;
udp . Send ( dataToSend , dataToSend . Length ) ;
dataToSend = Utils . Convert_text_For_multicast ( "#0.0#210#4#Application server stopped#" ) ;
udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
}
catch ( Exception ex2 )
{
SM . Debug ( "Error on sending Message to SD that APPServer has problem: " + ex2 . ToString ( ) ) ;
}
isRunning = false ;
}
public void ProcessTick ( )
{
try
{
try
2024-06-27 10:17:09 +00:00
{
byte [ ] dataToSend = Utils . Convert_text_For_multicast ( "#0.0#210#5#Application server restart#" ) ;
udp . Send ( dataToSend , dataToSend . Length ) ;
2024-02-22 16:43:59 +00:00
}
catch ( Exception ex2 )
{
SM . Debug ( "Error on sending Message to SD that APPServer has problem: " + ex2 . ToString ( ) ) ;
}
finally
{
RestartApp ( ) ;
}
}
catch ( Exception ex )
{
SM . Debug ( "Error on restart timer:" + ex . ToString ( ) ) ;
// the process did not exist - probably already closed!
//TODO: --> LOG
}
}
private void pictClose_MouseEnter ( object sender , EventArgs e )
{
pictClose . Image = global :: AppServer . Properties . Resources . close_over ;
this . Cursor = Cursors . Hand ;
}
private void pictClose_MouseLeave ( object sender , EventArgs e )
{
pictClose . Image = global :: AppServer . Properties . Resources . close ;
this . Cursor = Cursors . Arrow ;
}
private void pictClose_MouseClick ( object sender , MouseEventArgs e )
{
this . Close ( ) ;
Process oldProcess = Process . GetCurrentProcess ( ) ;
oldProcess . Kill ( ) ;
System . Windows . Forms . Application . Exit ( ) ;
}
private void pictMin_MouseEnter ( object sender , EventArgs e )
{
pictMin . Image = global :: AppServer . Properties . Resources . minimize_over ;
this . Cursor = Cursors . Hand ;
}
private void pictMin_MouseLeave ( object sender , EventArgs e )
{
pictMin . Image = global :: AppServer . Properties . Resources . minimize ;
this . Cursor = Cursors . Arrow ;
}
private void pictMin_MouseClick ( object sender , MouseEventArgs e )
{
this . WindowState = FormWindowState . Minimized ;
}
private void StartReport_Tick ( object sender , EventArgs e )
{
foreach ( DictionaryEntry item in userReportTimeList )
{
if ( ! ( ( UserReportTime ) item . Value ) . ReportExecuted )
{
if ( ( DateTime . Now . Hour = = ( ( UserReportTime ) item . Value ) . HH & & ( DateTime . Now . Minute = = ( ( UserReportTime ) item . Value ) . MM ) ) )
{
( ( UserReportTime ) item . Value ) . ReportExecuted = true ;
Process notePad = new Process ( ) ;
notePad . StartInfo . FileName = "ReportstoEmail.exe" ;
notePad . StartInfo . Arguments = ( ( UserReportTime ) item . Value ) . UserID . ToString ( ) . Trim ( ) + " " + ( ( UserReportTime ) item . Value ) . UserName . Trim ( ) ;
notePad . Start ( ) ;
}
}
// put ReportExecuted on false 1 minute before event fired
if ( ( DateTime . Now . Hour = = ( ( UserReportTime ) item . Value ) . HH & & ( DateTime . Now . Minute = = ( ( UserReportTime ) item . Value ) . MM - 1 ) ) )
( ( UserReportTime ) item . Value ) . ReportExecuted = false ;
}
}
private void MainForm_FormClosed ( object sender , FormClosedEventArgs e )
{
if ( notifyIcon1 ! = null )
{
notifyIcon1 . Dispose ( ) ;
}
}
//for ARS DB thread
public void HandleUnitStatus ( )
{
Thread . Sleep ( 500 ) ;
Utils . WriteLine ( "HandleUnitStatus thread..." ) ;
int count = 0 ;
DBsubsOperationManager dbsubsoperManage = new DBsubsOperationManager ( Program . cfg . DB_IP , Program . cfg . DB_schema ,
Program . cfg . DB_user , Program . cfg . DB_passwd , Program . cfg . DB_port ) ;
while ( isRunning )
{
while ( ( + + count % 5 ! = 0 ) & & isRunning )
{
Thread . Sleep ( 100 ) ;
}
count = 0 ;
try
{
Dictionary < string , Status_for_tab > changedStatuses = new Dictionary < string , Status_for_tab > ( ) ;
foreach ( DictionaryEntry pair in MainForm . VehicleHashStat )
{
VehicleStatus vs = ( ( VehicleStatus ) MainForm . VehicleHashStat [ pair . Key ] ) ;
// change the status only if a last position is available or last Ars time is available
if ( vs . lastPositionTime . Year > 2010 | | vs . lastArsTime . Year > 2010 )
{
//Utils.WriteLine("CHECKING UNIT STATUS : " + pair.Key + " | " + vs.curentStatus, ConsoleColor.Magenta);
switch ( vs . curentStatus )
{
// NOTHING TO DO WHEN IN EMERGENCY
case Status_for_tab . EMERG :
break ;
case Status_for_tab . DISABLE : break ;
case Status_for_tab . ENABLE : break ;
case Status_for_tab . OFF : break ;
case Status_for_tab . MADEOFF : break ;
case Status_for_tab . NOGPSFIX :
case Status_for_tab . GPS_OFF :
{
// check if the unit needs to be made off
if ( CheckPositionMadeOff ( vs ) )
{
// update status and push changes
vs . curentStatus = Status_for_tab . MADEOFF ;
MulticastListener . PushStatus ( pair . Key + "" , vs . curentStatus ) ;
}
break ;
}
case Status_for_tab . MADEON :
case Status_for_tab . ON :
{
// check if the unit needs to be made off
if ( CheckArsMadeOff ( vs ) & & CheckPositionMadeOff ( vs ) )
{
// update status and push changes
vs . curentStatus = Status_for_tab . MADEOFF ;
MulticastListener . PushStatus ( pair . Key + "" , vs . curentStatus ) ;
}
break ;
}
case Status_for_tab . GPS_ON :
{
// check if the unit needs to be made off
if ( CheckGpsPoor ( vs ) )
{
// update status and push changes
vs . curentStatus = Status_for_tab . GPS_POOR ;
MulticastListener . PushStatus ( pair . Key + "" , vs . curentStatus ) ;
}
break ;
}
case Status_for_tab . GPS_POOR :
{
// check if the unit needs to be made off
if ( CheckGpsOff ( vs ) )
{
// update status and push changes
vs . curentStatus = Status_for_tab . GPS_OFF ;
MulticastListener . PushStatus ( pair . Key + "" , vs . curentStatus ) ;
}
break ;
}
}
}
if ( vs . curentStatus ! = vs . previousStatus )
{
changedStatuses . Add ( pair . Key + "" , vs . curentStatus ) ;
// force the previous status to become the same as the current status
vs . curentStatus = vs . curentStatus ;
}
}
// update the statuses that changed
if ( changedStatuses . Count > 0 )
{
dbsubsoperManage . updateOnlyStatus ( changedStatuses ) ;
Utils . WriteLine ( changedStatuses . Count + " units changed their states." , ConsoleColor . Green ) ;
changedStatuses . Clear ( ) ;
}
}
catch ( ThreadAbortException tae )
{
Utils . WriteLine ( tae . ToString ( ) , ConsoleColor . Red ) ;
}
catch ( Exception ex )
{
Utils . WriteLine ( "HandleUnitStatus Exception: " + ex . ToString ( ) , ConsoleColor . Red ) ;
}
} // end while (true)
}
private bool CheckArsMadeOff ( VehicleStatus vehicleStatus )
{
return ( DateTime . Now - vehicleStatus . lastArsTime ) . TotalSeconds > vehicleStatus . made_off ? true : false ;
}
private bool CheckPositionMadeOff ( VehicleStatus vehicleStatus )
{
return ( DateTime . Now - vehicleStatus . lastPositionTime ) . TotalSeconds > vehicleStatus . made_off ? true : false ;
}
private bool CheckGpsPoor ( VehicleStatus vehicleStatus )
{
//Utils.WriteLine((DateTime.Now - vehicleStatus.lastPositionTime).TotalSeconds + "");
return ( DateTime . Now - vehicleStatus . lastPositionTime ) . TotalSeconds > vehicleStatus . gps_poor ? true : false ;
}
private bool CheckGpsOff ( VehicleStatus vehicleStatus )
{
return ( DateTime . Now - vehicleStatus . lastPositionTime ) . TotalSeconds > vehicleStatus . gps_off ? true : false ;
}
/// <summary>
/// If the WebsocketServer is online populate a Dataset, convert it to JSON and send it on the websocket
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
private static void SendLocationToWebSocketHandler ( object source , ElapsedEventArgs e )
{
Utils . WriteLine ( "Preparing " + MainForm . websocketLocationQueue . Count + " positions to be sent to websocket!!!" ,
ConsoleColor . DarkYellow ) ;
if ( WebsocketThread . Instance . getClient ( ) = = null )
{
Utils . WriteLine ( "WebSocket client url not set or websocket not active" ) ;
MainForm . websocketLocationQueue . Clear ( ) ;
return ;
}
if ( MainForm . websocketLocationQueue . Count > 0 & & WebsocketThread . Instance . getClient ( ) . IsRunning )
{
List < UnitDataToSend > allPositions = MainForm . websocketLocationQueue . ToList ( ) ;
// send over websocket and clear list
WebsocketThread . SendJson ( WebsocketThread . Instance . getClient ( ) , WebSocketFormatter . ToJson ( allPositions ) ) ;
}
MainForm . websocketLocationQueue . Clear ( ) ;
}
private static void CheckGatewayStatus ( object source , ElapsedEventArgs e )
{
if ( Program . cfg . gatewayType = = "SDR" & & ! IsProcessRunning ( "SDRgateway" ) )
{
try
{
string Path = $@"{SafeMobileLib.Utils.GetRegValue(" Path ", " SafeMobile ")}\Tetra_SDR\SDRgateway.exe" ;
System . Diagnostics . Process . Start ( Path ) ;
SafeMobileLib . Utils . WriteLine ( "Gateway started" , ConsoleColor . Yellow ) ;
}
catch ( Exception ex )
{
Utils . WriteLine ( "Could not start Gateway because: " + ex . ToString ( ) + Environment . NewLine + "Path to Gateway = " +
$@"{SafeMobileLib.Utils.GetRegValue(" Path ", " SafeMobile ")}\Tetra_SDR\SDRgateway.exe" , ConsoleColor . Red ) ;
}
}
}
public static bool IsProcessRunning ( string ProcessName )
{
try
{
Process [ ] pname = Process . GetProcessesByName ( ProcessName ) ;
if ( pname . Length = = 0 )
return false ;
else
return true ;
}
catch
{
return false ;
}
}
#region UPDATE
/// <summary>
/// Check for new version release on SafeMobile Portal
/// The check is done by comparing Current Assembly Version with the one
/// written in a xml file on the portal.
/// </summary>
private void CheckForUpdate ( )
{
App appType = App . APP_SERVER ;
AutoUpdate au = new AutoUpdate ( appType ) { IsDevelop = Program . cfg . isDevelop } ;
au . OnNewVersionAvailable + = delegate ( string version )
{
notifyIcon1 . Text = "New version available" ;
notifyIcon1 . ShowBalloonTip ( 2500 , $"{App.GetAppName(appType)} version {version} available" ,
$"Press to download and install the latest version of {App.GetAppName(appType)}." , ToolTipIcon . Info ) ;
notifyIcon1 . BalloonTipClicked + = delegate ( object sender , EventArgs e )
{
if ( notifyIcon1 . Text . Equals ( "New version available" ) )
{
UpdateForm uf = new UpdateForm ( appType , true ) { IsDevelop = Program . cfg . isDevelop } ;
uf . Show ( ) ;
}
} ;
} ;
// call method to check for new updated
au . CheckUpdate ( ) ;
}
#endregion
}
}