mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Fix MQTT server port crash Adjust device metrics grid colums Fix some index issues in the channel editor Clean up settings view, add duty cycle warning
166 lines
5.5 KiB
Swift
166 lines
5.5 KiB
Swift
//
|
|
// MQTTManager.swift
|
|
// Meshtastic
|
|
//
|
|
// Created by Garth Vander Houwen on 7/31/23.
|
|
//
|
|
|
|
import Foundation
|
|
import CocoaMQTT
|
|
|
|
protocol MqttClientProxyManagerDelegate: AnyObject {
|
|
func onMqttConnected()
|
|
func onMqttDisconnected()
|
|
func onMqttMessageReceived(message: CocoaMQTTMessage)
|
|
func onMqttError(message: String)
|
|
}
|
|
|
|
class MqttClientProxyManager {
|
|
// Singleton Instance
|
|
static let shared = MqttClientProxyManager()
|
|
private static let defaultKeepAliveInterval: Int32 = 60
|
|
weak var delegate: MqttClientProxyManagerDelegate?
|
|
var mqttClientProxy: CocoaMQTT?
|
|
var topic = "msh/2/c"
|
|
var debugLog = false
|
|
func connectFromConfigSettings(node: NodeInfoEntity) {
|
|
let defaultServerAddress = "mqtt.meshtastic.org"
|
|
let useSsl = node.mqttConfig?.tlsEnabled == true
|
|
var defaultServerPort = useSsl ? 8883 : 1883
|
|
var host = node.mqttConfig?.address
|
|
if host == nil || host!.isEmpty {
|
|
host = defaultServerAddress
|
|
} else if host != nil && host!.contains(":") {
|
|
if let fullHost = host {
|
|
host = fullHost.components(separatedBy: ":")[0]
|
|
defaultServerPort = Int(fullHost.components(separatedBy: ":")[1]) ?? (useSsl ? 8883 : 1883)
|
|
}
|
|
}
|
|
if let host = host {
|
|
let port = defaultServerPort
|
|
let username = node.mqttConfig?.username
|
|
let password = node.mqttConfig?.password
|
|
let root = node.mqttConfig?.root?.count ?? 0 > 0 ? node.mqttConfig?.root : "msh"
|
|
let prefix = root! + "/2/c"
|
|
topic = prefix + "/#"
|
|
let qos = CocoaMQTTQoS(rawValue: UInt8(1))!
|
|
connect(host: host, port: port, useSsl: useSsl, username: username, password: password, topic: topic, qos: qos, cleanSession: true)
|
|
}
|
|
}
|
|
func connect(host: String, port: Int, useSsl: Bool, username: String?, password: String?, topic: String?, qos: CocoaMQTTQoS, cleanSession: Bool) {
|
|
guard !host.isEmpty else {
|
|
delegate?.onMqttDisconnected()
|
|
return
|
|
}
|
|
let clientId = "MeshtasticAppleMqttProxy-" + String(ProcessInfo().processIdentifier)
|
|
mqttClientProxy = CocoaMQTT(clientID: clientId, host: host, port: UInt16(port))
|
|
if let mqttClient = mqttClientProxy {
|
|
mqttClient.enableSSL = useSsl
|
|
mqttClient.allowUntrustCACertificate = true
|
|
mqttClient.username = username
|
|
mqttClient.password = password
|
|
mqttClient.keepAlive = 60
|
|
mqttClient.cleanSession = cleanSession
|
|
if debugLog {
|
|
mqttClient.logLevel = .debug
|
|
}
|
|
mqttClient.willMessage = CocoaMQTTMessage(topic: "/will", string: "dieout")
|
|
mqttClient.autoReconnect = true
|
|
mqttClient.delegate = self
|
|
let success = mqttClient.connect()
|
|
if !success {
|
|
delegate?.onMqttError(message: "Mqtt connect error")
|
|
}
|
|
} else {
|
|
delegate?.onMqttError(message: "Mqtt initialization error")
|
|
}
|
|
}
|
|
func subscribe(topic: String, qos: CocoaMQTTQoS) {
|
|
print("📲 MQTT Client Proxy subscribed to: " + topic)
|
|
mqttClientProxy?.subscribe(topic, qos: qos)
|
|
}
|
|
func unsubscribe(topic: String) {
|
|
mqttClientProxy?.unsubscribe(topic)
|
|
print("📲 MQTT Client Proxy unsubscribe for: " + topic)
|
|
}
|
|
func publish(message: String, topic: String, qos: CocoaMQTTQoS) {
|
|
mqttClientProxy?.publish(topic, withString: message, qos: qos)
|
|
if debugLog {
|
|
print("📲 MQTT Client Proxy publish for: " + topic)
|
|
}
|
|
}
|
|
func disconnect() {
|
|
if let client = mqttClientProxy {
|
|
client.disconnect()
|
|
print("📲 MQTT Client Proxy Disconnected")
|
|
}
|
|
}
|
|
}
|
|
|
|
extension MqttClientProxyManager: CocoaMQTTDelegate {
|
|
func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
|
|
print("📲 MQTT Client Proxy didConnectAck: \(ack)")
|
|
if ack == .accept {
|
|
delegate?.onMqttConnected()
|
|
} else {
|
|
// Connection error
|
|
var errorDescription = "Unknown Error"
|
|
switch ack {
|
|
case .accept:
|
|
errorDescription = "No Error"
|
|
case .unacceptableProtocolVersion:
|
|
errorDescription = "Proto ver"
|
|
case .identifierRejected:
|
|
errorDescription = "Invalid Id"
|
|
case .serverUnavailable:
|
|
errorDescription = "Invalid Server"
|
|
case .badUsernameOrPassword:
|
|
errorDescription = "Invalid Credentials"
|
|
case .notAuthorized:
|
|
errorDescription = "Authorization Error"
|
|
default:
|
|
errorDescription = "Unknown Error"
|
|
}
|
|
print(errorDescription)
|
|
delegate?.onMqttError(message: errorDescription)
|
|
self.disconnect()
|
|
}
|
|
}
|
|
func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) {
|
|
print("mqttDidDisconnect: \(err?.localizedDescription ?? "")")
|
|
|
|
if let error = err {
|
|
delegate?.onMqttError(message: error.localizedDescription)
|
|
}
|
|
delegate?.onMqttDisconnected()
|
|
}
|
|
func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {
|
|
if debugLog {
|
|
print("📲 MQTT Client Proxy didPublishMessage from MqttClientProxyManager: \(message)")
|
|
}
|
|
}
|
|
func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {
|
|
if debugLog {
|
|
print("📲 MQTT Client Proxy didPublishAck from MqttClientProxyManager: \(id)")
|
|
}
|
|
}
|
|
|
|
public func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
|
|
delegate?.onMqttMessageReceived(message: message)
|
|
if debugLog {
|
|
print("📲 MQTT Client Proxy message received on topic: \(message.topic)")
|
|
}
|
|
}
|
|
func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopics success: NSDictionary, failed: [String]) {
|
|
print("📲 MQTT Client Proxy didSubscribeTopics: \(success.allKeys.count) topics. failed: \(failed.count) topics")
|
|
}
|
|
func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopics topics: [String]) {
|
|
print("didUnsubscribeTopics: \(topics.joined(separator: ", "))")
|
|
}
|
|
func mqttDidPing(_ mqtt: CocoaMQTT) {
|
|
print("📲 MQTT Client Proxy mqttDidPing")
|
|
}
|
|
func mqttDidReceivePong(_ mqtt: CocoaMQTT) {
|
|
print("📲 MQTT Client Proxy mqttDidReceivePong")
|
|
}
|
|
}
|