﻿B4A=true
Group=ATLAS CM\SERVICES
ModulesStructureVersion=1
Type=Service
Version=10.5
@EndOfDesignText@
#Region  Service Attributes 

	#StartAtBoot: False
	
#End Region


Sub Process_Globals
	'These global variables will be declared once when the application starts.
	'These variables can be accessed from all modules.
	
	Dim ws					As WebSocketHandler
	Dim linkws				As String
	
	
	Dim tmrKillMe 			As Timer
	Dim su 					As StringUtils
	Dim clsSE 				As cls_status_events
	Dim sEvent 				As CMSTAT
	
	Dim retrys				As Int
	Dim connected			As Boolean
	Dim connectionTime		As Long
	
End Sub

Sub Service_Create

	Dim wh1 As WebSocketHandler
	ws = wh1
	Dim clsSE1 As cls_status_events
	clsSE = clsSE1
	
	mod_functions.writelog("svc_status_event::Service_Create")
	retrys = 0
	connectionTime = 0
	connected = False
	clsSE.Initialize
	tmrKillMe.Initialize("tmrKillMe",15000)
		
	linkws  = $"ws://${Starter.appset.sm.ssl_host}:${Starter.appset.sm.ssl_port+1}/se_cm"$
	' // 2026.10.15
	mod_functions.CheckHeapMemory("svc_status_event::Service_Create")
			
End Sub

Sub Service_Start (StartingIntent As Intent)

	Try	
		mod_functions.writelog($"svc_status_event::Service_Start::ActiveNetworkType=${svc_service.mlWifi.ActiveNetworkType} │ ActiveNetworkTypeName=${svc_service.mlWifi.ActiveNetworkTypeName} "$)
		If Starter.appset.http_port_use = 0 Then
			get_connection
		Else
			CallSubDelayed(Me,"send_event_https")
		End If
	Catch
		mod_functions.writelog("svc_status_event::Service_Start, error - " & LastException.message)
		StopService(Me)
	End Try
	
End Sub

Sub Service_Destroy
		
	mod_functions.writelog("svc_status_event::Service_Destroy")	
	tmrKillMe.Enabled = False
	' // We are using WS/WSS
	If Starter.appset.http_port_use = 0 Then	
		If ws.IsInitialized Then
			ws.Close
		End If
	End If
	
	' // 2026.10.15
	Try
		ws = Null
		clsSE = Null
	Catch
		mod_functions.writelog($"svc_status_event::Service_Destroy:: -error- ${LastException.Message}"$)
	End Try	
	mod_functions.CheckHeapMemory("svc_status_event::Service_Destroy")
	
End Sub

Sub get_connection
	
	tmrKillMe.Enabled = True
	connectionTime = DateTime.now
	' // non ssl connection
	mod_functions.writelog($"svc_status_event::Connecting to ${linkws}"$)	
	Try 
		ws.Initialize(Me, "ws")
		ws.Connect(linkws)
	Catch
		mod_functions.writelog($"svc_status_event::get_connection::ws:: -error- ${LastException.Message}"$)
	End Try
	
End Sub

#region ws

Sub ws_Connected

	connected = True
	mod_functions.writelog($"svc_status_event::ws_Connected, Connected to ${linkws}, ${DateTime.Now-connectionTime}ms"$)
	
End Sub

Sub ws_Closed (Reason As String)
	
	mod_functions.writelog($"svc_status_event::ws_Closed, Reason=${Reason}"$)
	
	' // we did not connect
	If Not(connected) Then
		If retrys < 5 Then
			tmrKillMe.Enabled = False
			retrys = retrys + 1
			CallSubDelayed(Me,"get_connection")
		Else
			mod_functions.writelog($"svc_status_event::ws_Closed, retrys:${retrys} of ${5}, terminating service"$)
			StopService(Me)
		End If
	Else
		StopService(Me)
	End If
	
	
End Sub

Sub ws_ServerReady(Params As List)
	
	Dim s As String
		
	' // ser has responded to us
	s = Params.Get(0)
	Select Case s
		Case "READY"
			mod_functions.writelog("svc_status_event::ws_ServerReady, Server is READY")
			' // send status event
			CallSubDelayed(Me,"send_event")
			
		Case "OK"
			' // Server is just speaking to us
			Log("svc_status_event::ws_ServerReady, Hello from Server :)")
		Case Else
			ws.Close

	End Select
		
	
End Sub

Sub ws_ServerStatusReport(params As List)
	
	' // turn off killer
	tmrKillMe.Enabled = False
	clsSE.remove_cached_event(sEvent.TimeStamp)
	' // try to send another event	
	CallSubDelayed(Me,"send_event")
	
End Sub

#End Region


Sub send_event_https()

	' // turn on killer
	tmrKillMe.Enabled = True
	
	Try
		
		Dim ser As B4XSerializator
		
		sEvent = clsSE.get_cached_event
		If sEvent.IsInitialized Then
			ser.ConvertObjectToBytesAsync(sEvent, "ser")
		Else
			mod_functions.writelog("svc_status_event::send_event() finished")
			StopService(Me)
		End If
	Catch
		mod_functions.writelog($"svc_status_event::send_event() - error - ${LastException.Message}"$)
		StopService(Me)
	End Try
	
End Sub

Sub ser_ObjectToBytes (Success As Boolean, Bytes() As Byte)
	
	mod_functions.writelog($"svc_status_event::ser_ObjectToBytes::${Success}"$)
	If Success Then
		' // 2021.06.01 - AES - encrypt data with host address
		Dim c As B4XCipher, b() As Byte, bc As ByteConverter
		b = c.Encrypt(Bytes,Starter.appset.sm.dns)
		
		Dim ecb64 As String = bc.HexFromBytes(b)
		
		Dim j			As HttpJob
		Dim link		As String
		Dim parm		As String
		
		bc.HexFromBytes(b)
		j.Initialize("j",Me)
		j.GetRequest.Timeout = 5000
		' // HTTP(S) 2022.04.20 - PLAY PROTECT WONT ALLOW HTTP REQUESTS
		link  = $"https://${Starter.appset.sm.http_host}:${Starter.appset.sm.https_port}/eventcm"$		
				
		mod_functions.writelog($"svc_status_event::${link}"$)		
		parm = $"?EVENT_CM=${ecb64}"$		
		j.PostString($"${link}${parm}"$,"")
		
	End If
	
End Sub

Sub JobDone(Job As HttpJob)
	
	Dim resetHttp As Boolean
					
	If Job.Success Then
		mod_functions.writelog($"svc_status_event::JobDone() ${Job.GetString}"$)
		' // turn off killer
		tmrKillMe.Enabled = False
		clsSE.remove_cached_event(sEvent.TimeStamp)
		' // try to send another event
		CallSubDelayed(Me,"send_event_https")
	Else
		mod_functions.writelog($"svc_status_event::JobDone() Failed."$)
		resetHttp = True
	End If
	Job.Release

	If resetHttp Then
		StopService(HttpUtils2Service)
		Dim newHC As OkHttpClient
		#if HU2_ACCEPTALL
			mod_functions.writelog("(Http client initialized with accept all option.)")
			newHC.InitializeAcceptAll("hc")
		#else
			newHC.Initialize("hc")
		#End If
		HttpUtils2Service.hc = newHC
	End If
	
End Sub

Sub send_event()
			
	Dim data As Map
	Try
		
		Dim ser As B4XSerializator
		
		sEvent = clsSE.get_cached_event
		If sEvent.IsInitialized Then
			ser.ConvertObjectToBytesAsync(sEvent, "ser")
			Wait For (ser) ser_ObjectToBytes (Success As Boolean, Bytes() As Byte)
			If Success Then								
				' // 2021.06.01 - AES - encrypt data with host address
				Dim c As B4XCipher, b() As Byte
				b = c.Encrypt(Bytes,Starter.appset.sm.dns)

				Dim ecb64 As String = su.EncodeBase64(b)
				Dim imei As String = Starter.appset.imei
				Dim data As Map
				data.Initialize
				data.Put("imei",imei)
				data.Put("report",ecb64)
				ws.SendEventToServer("Status_Report_AES", data)
			Else
				mod_functions.writelog("svc_status_event::ser_ObjectToBytes() FAILED")
			End If
		Else
			mod_functions.writelog("svc_status_event::send_event() finished")
			StopService(Me)
		End If
	Catch
		mod_functions.writelog("svc_status_event::send_event() error - " & LastException.Message)
		StopService(Me)
	End Try
	
End Sub

Sub tmrKillMe_Tick
	
	mod_functions.writelog("svc_status_event::Kill_Tick::timeout interval = " & tmrKillMe.Interval)	
	StopService(Me)

End Sub

