﻿B4J=true
Group=Default Group
ModulesStructureVersion=1
Type=StaticCode
Version=9.1
@EndOfDesignText@
'Static code module
Sub Process_Globals
	' Define all global variables
	Private fx As JFX
	Private serializator As B4XSerializator
	
	' MQTT variables
	Private MQTTCLIENT As MqttClient
	Private MQTTCLIENTID As String
	Private MQTTTOPIC As String
	Private MQTTMONITORTOPIC As String
	Private MQTTBROKER As String
	Private MQTTPORT As Int
	Private MQTTUSER As String
	Private MQTTPASS As String
	Private MQTTCONNECTED As Boolean = False
	
End Sub

' This method will initialize all variables for MQTT out of the INI file.
public Sub initializeMQTTVariables(map As Map)
	MQTTTOPIC = map.Get("MQTT.mqttTopic")
	MQTTMONITORTOPIC = map.Get("MQTT.mqttMonitorTopic")
	MQTTBROKER = map.Get("MQTT.mqttBroker")
	MQTTPORT = map.Get("MQTT.mqttPort")
	MQTTUSER = map.Get("MQTT.mqttUser")
	MQTTPASS = map.Get("MQTT.mqttPass")
End Sub

' This method will connect to the MQTT broker
public Sub connectoToMQTT
	If MQTTCONNECTED Then
		MQTTCLIENT_Disconnected
	End If
	
	' Set TIMERTIMEOUTMQTT to True
	Main.SetStateTIMERTIMEOUTMQTT(True) 

	' Assign the host his IP as the MQTTCLIENTID variable
	MQTTCLIENTID = $"${Main.COMPUTERNAME}-client"$
	' Initialize the MQTTCLIENT, WARNING: the eventname (in this case "MQTTCLIENT" must be used for all event handler functions!
	MQTTCLIENT.Initialize("MQTTCLIENT", $"ssl://${MQTTBROKER}:${MQTTPORT}"$, MQTTCLIENTID)
	
	' Define a abrupt disconnect message
	Private disconnectMessage As String
	disconnectMessage = $"The ${Main.COMPUTERNAME}$ ${MQTTCLIENTID}$ disconnected abruptly."$
	
	' Give extra MqttConnectionOptions -> user, pass and topic
	Private mqttConnectOptions As MqttConnectOptions
	mqttConnectOptions.Initialize(MQTTUSER, MQTTPASS)
	trustSelfSignedMQTTCertificate(mqttConnectOptions)
	mqttConnectOptions.SetLastWill($"${MQTTMONITORTOPIC}/${MQTTCLIENTID}"$, serializator.ConvertObjectToBytes(disconnectMessage), 0, False)
	
	Try
		' Start the MQTTCOnnection with the configured options
		MQTTCLIENT.Connect2(mqttConnectOptions)
		Logger.Logging($"Succesfully connected to MQTTBROKER ${MQTTBROKER}"$)
	Catch
		' Write log to logger method if an error occurs.
		Logger.Logging($"Error connecting to MQTTBROKER ${MQTTBROKER}"$)
	End Try
End Sub

' This method will subscribe to a topic if the MQTTCLIENT is connected
Private Sub MQTTCLIENT_Connected (Success As Boolean)
	' Set TIMERTIMEOUTMQTT to False
	Main.SetStateTIMERTIMEOUTMQTT(False) 

	' Check whether the connection is succesfull or not
	If Success Then
		' Write log to logger method
		Logger.Logging($"Connection to MQTTBROKER is ${Success}. Subscribing to topic ${MQTTTOPIC}"$)
		' Subscribe to topic
		MQTTCLIENT.Subscribe(MQTTTOPIC, 0)
		' Set MQTT connection state to true
		MQTTCONNECTED = True
	Else
		' Write log to logger method
		Logger.Logging($"Connection to MQTTBROKER is ${Success}"$)
		Logger.Logging($"Error message: ${LastException}$"$)
		Main.SetReconnectTimer
		Log(LastException)
	End If
End Sub

' This method will be called when a MQTT messages is received
Private Sub MQTTCLIENT_MessageArrived (Topic As String, Payload() As Byte)
	' Read Bytes array to string
	Private receivedData As String = BytesToString(Payload, 0, Payload.Length, "UTF-8")
	' Convert string to object via funtion
	Private receivedObject As Object = stringToObject(receivedData)
	Log(receivedObject)
End Sub

' This method will be called when the MQTT client will dissonnect.
Private Sub MQTTCLIENT_Disconnected
	If MQTTCONNECTED Then
		MQTTCONNECTED = False
		MQTTCLIENT.Close		
		Logger.Logging($"Succesfully disconnected from MQTTBROKER ${MQTTBROKER}"$)
	End If
End Sub

' This method will convert a non JAVA formatted string to an object
Sub stringToObject(inputString As String) As Object
	'Read plain text string and convert to bytes
	Private buffer() As Byte = serializator.ConvertObjectToBytes(inputString)
	' Read converted bytes in and return the object
	Return serializator.ConvertBytesToObject(buffer)
End Sub

'Depends on JavaObject and jNet or Net libraries
Sub trustSelfSignedMQTTCertificate (mo As MqttConnectOptions)
	Dim SSLContext As JavaObject
	SSLContext = SSLContext.InitializeStatic("javax.net.ssl.SSLContext").RunMethod("getInstance", Array("TLS"))
	Dim tm As CustomTrustManager
	tm.InitializeAcceptAll
	SSLContext.RunMethod("init", Array(Null, tm, Null))
	Dim jmo As JavaObject = mo
	jmo.RunMethod("setSocketFactory", Array(SSLContext.RunMethod("getSocketFactory", Null)))
End Sub