mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Might work
This commit is contained in:
parent
b346ce2a37
commit
5929268171
4 changed files with 103 additions and 41 deletions
|
|
@ -11,6 +11,7 @@
|
|||
C9697FA527933B8C00250207 /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = C9697FA427933B8C00250207 /* SQLite */; };
|
||||
DD0D3D222A55CEB10066DB71 /* CocoaMQTT in Frameworks */ = {isa = PBXBuildFile; productRef = DD0D3D212A55CEB10066DB71 /* CocoaMQTT */; };
|
||||
DD0F791B28713C8A00A6FDAD /* AdminMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */; };
|
||||
DD14E72E2A82A614006E39BC /* RemoteHardware.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD14E72D2A82A614006E39BC /* RemoteHardware.swift */; };
|
||||
DD1925B728CDA5A400720036 /* CannedMessagesConfigEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1925B628CDA5A400720036 /* CannedMessagesConfigEnums.swift */; };
|
||||
DD1925B928CDA93900720036 /* SerialConfigEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1925B828CDA93900720036 /* SerialConfigEnums.swift */; };
|
||||
DD1BF2F92776FE2E008C8D2F /* UserMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */; };
|
||||
|
|
@ -198,6 +199,7 @@
|
|||
DD0E9C222A30CE3A00580CBB /* MeshtasticDataModelV14.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV14.xcdatamodel; sourceTree = "<group>"; };
|
||||
DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminMessageList.swift; sourceTree = "<group>"; };
|
||||
DD14E72C2A80738F006E39BC /* MeshtasticDataModelV15.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV15.xcdatamodel; sourceTree = "<group>"; };
|
||||
DD14E72D2A82A614006E39BC /* RemoteHardware.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteHardware.swift; sourceTree = "<group>"; };
|
||||
DD1925B628CDA5A400720036 /* CannedMessagesConfigEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CannedMessagesConfigEnums.swift; sourceTree = "<group>"; };
|
||||
DD1925B828CDA93900720036 /* SerialConfigEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerialConfigEnums.swift; sourceTree = "<group>"; };
|
||||
DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserMessageList.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -425,6 +427,7 @@
|
|||
DD47E3CD26F103C600029299 /* NodeList.swift */,
|
||||
DD90860D26F69BAE00DC5189 /* NodeMap.swift */,
|
||||
DD73FD1028750779000852D6 /* PositionLog.swift */,
|
||||
DD14E72D2A82A614006E39BC /* RemoteHardware.swift */,
|
||||
);
|
||||
path = Nodes;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1111,6 +1114,7 @@
|
|||
DD8169F9271F1A6100F4AB02 /* MeshLogger.swift in Sources */,
|
||||
DD41582A28585C32009B0E59 /* RangeTestConfig.swift in Sources */,
|
||||
DD1925B728CDA5A400720036 /* CannedMessagesConfigEnums.swift in Sources */,
|
||||
DD14E72E2A82A614006E39BC /* RemoteHardware.swift in Sources */,
|
||||
DDDB444429F8A8DD00EE2349 /* Float.swift in Sources */,
|
||||
DD5E5211298EE33B00D21B61 /* remote_hardware.pb.swift in Sources */,
|
||||
DD5E5204298EE33B00D21B61 /* xmodem.pb.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -8,8 +8,47 @@ import CocoaMQTT
|
|||
// ---------------------------------------------------------------------------------------
|
||||
// Meshtastic BLE Device Manager
|
||||
// ---------------------------------------------------------------------------------------
|
||||
class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
||||
class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate, ObservableObject {
|
||||
|
||||
// MqttClientProxyManagerDelegate
|
||||
func onMqttConnected() {
|
||||
mqttManager.status = .connected
|
||||
print("MQTT Connected")
|
||||
}
|
||||
|
||||
func onMqttDisconnected() {
|
||||
mqttManager.status = .disconnected
|
||||
print("MQTT Disconnected")
|
||||
}
|
||||
|
||||
func onMqttMessageReceived(message: CocoaMQTTMessage) {
|
||||
|
||||
print("onMqttMessageReceived")
|
||||
if message.topic.contains("/stat/") {
|
||||
// return
|
||||
}
|
||||
var proxyMessage = MqttClientProxyMessage()
|
||||
proxyMessage.topic = message.topic
|
||||
proxyMessage.data = Data(message.payload)
|
||||
proxyMessage.retained = message.retained
|
||||
|
||||
|
||||
var toRadio: ToRadio!
|
||||
toRadio = ToRadio()
|
||||
toRadio.mqttClientProxyMessage = proxyMessage
|
||||
let binaryData: Data = try! toRadio.serializedData()
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
print("📲 Sent Mqtt client proxy message to the connected device.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func onMqttError(message: String) {
|
||||
print("MQTT Error")
|
||||
}
|
||||
|
||||
|
||||
private static var documentsFolder: URL {
|
||||
do {
|
||||
return try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
||||
|
|
@ -57,6 +96,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
self.connectedVersion = "0.0.0"
|
||||
super.init()
|
||||
centralManager = CBCentralManager(delegate: self, queue: nil)
|
||||
mqttManager.delegate = self
|
||||
// centralManager = CBCentralManager(delegate: self, queue: nil, options: [CBCentralManagerOptionRestoreIdentifierKey: restoreKey])
|
||||
}
|
||||
|
||||
|
|
@ -393,31 +433,17 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
print(characteristic.value!)
|
||||
}
|
||||
|
||||
// Send a packet from mqtt to the radio
|
||||
// Publish mqttClientProxyMessages received on the from radio
|
||||
if decodedInfo.payloadVariant == FromRadio.OneOf_PayloadVariant.mqttClientProxyMessage(decodedInfo.mqttClientProxyMessage) {
|
||||
var message = CocoaMQTTMessage (
|
||||
topic: decodedInfo.mqttClientProxyMessage.topic,
|
||||
payload: [UInt8](decodedInfo.mqttClientProxyMessage.data),
|
||||
retained: decodedInfo.mqttClientProxyMessage.retained
|
||||
)
|
||||
print("📲 Publish Mqtt client proxy message received on FromRadio \(message)")
|
||||
print("📲 Publish Mqtt client proxy message received on FromRadio to the Mqtt server \(message)")
|
||||
mqttManager.mqttClient?.publish(message)
|
||||
}
|
||||
|
||||
//To Radio
|
||||
// if decodedInfo.mqttClientProxyMessage.topic.contains("/stat/") {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// var toRadio: ToRadio!
|
||||
// toRadio = ToRadio()
|
||||
// toRadio.mqttClientProxyMessage = decodedInfo.mqttClientProxyMessage
|
||||
// let binaryData: Data = try! toRadio.serializedData()
|
||||
// if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
// connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
// print("📲 Sent Mqtt client proxy message to the connected device.")
|
||||
// }
|
||||
|
||||
switch decodedInfo.packet.decoded.portnum {
|
||||
|
||||
// Handle Any local only packets we get over BLE
|
||||
|
|
@ -620,6 +646,8 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public func sendMessage(message: String, toUserNum: Int64, channel: Int32, isEmoji: Bool, replyID: Int64) -> Bool {
|
||||
var success = false
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,14 @@
|
|||
import Foundation
|
||||
import CocoaMQTT
|
||||
|
||||
protocol MqttClientProxyManagerDelegate: AnyObject {
|
||||
func onMqttConnected()
|
||||
func onMqttDisconnected()
|
||||
func onMqttMessageReceived(message: CocoaMQTTMessage)
|
||||
func onMqttError(message: String)
|
||||
}
|
||||
|
||||
class MqttClientProxyManager {
|
||||
|
||||
enum ConnectionStatus {
|
||||
case connecting
|
||||
case connected
|
||||
|
|
@ -25,11 +31,16 @@ class MqttClientProxyManager {
|
|||
case exactlyOnce = 2
|
||||
}
|
||||
|
||||
// Singleton Instance
|
||||
static let shared = MqttClientProxyManager()
|
||||
|
||||
private static let defaultKeepAliveInterval: Int32 = 60
|
||||
weak var delegate: CocoaMQTTDelegate?
|
||||
|
||||
weak var delegate: MqttClientProxyManagerDelegate?
|
||||
var status = ConnectionStatus.none
|
||||
|
||||
var mqttClient: CocoaMQTT?
|
||||
|
||||
var topic = "msh/2/c"
|
||||
|
||||
private init() {
|
||||
|
|
@ -51,7 +62,6 @@ class MqttClientProxyManager {
|
|||
let password = node.mqttConfig?.password
|
||||
|
||||
let root = node.mqttConfig?.root?.count ?? 0 > 0 ? node.mqttConfig?.root : "msh"
|
||||
let preset = ModemPresets(rawValue: Int(node.loRaConfig?.modemPreset ?? 0)) ?? ModemPresets.longFast
|
||||
let prefix = root! + "/2/c"
|
||||
topic = prefix + "/#"
|
||||
let qos = CocoaMQTTQoS(rawValue :UInt8(1))!
|
||||
|
|
@ -61,10 +71,16 @@ class MqttClientProxyManager {
|
|||
|
||||
func connect(host: String, port: Int, username: String?, password: String?, topic: String?, qos: CocoaMQTTQoS, cleanSession: Bool) {
|
||||
|
||||
let clientId = "MeshtasticAppleMqttProxy-" + String(ProcessInfo().processIdentifier)
|
||||
status = .connecting
|
||||
mqttClient = CocoaMQTT(clientID: clientId, host: host, port: UInt16(port))
|
||||
guard !host.isEmpty else {
|
||||
delegate?.onMqttDisconnected()
|
||||
return
|
||||
}
|
||||
|
||||
status = .connecting
|
||||
|
||||
let clientId = "MeshtasticAppleMqttProxy-" + String(ProcessInfo().processIdentifier)
|
||||
|
||||
mqttClient = CocoaMQTT(clientID: clientId, host: host, port: UInt16(port))
|
||||
if let mqttClient = mqttClient {
|
||||
|
||||
mqttClient.username = username
|
||||
|
|
@ -79,9 +95,11 @@ class MqttClientProxyManager {
|
|||
mqttClient.delegate = self
|
||||
let success = mqttClient.connect()
|
||||
if !success {
|
||||
delegate?.onMqttError(message: "Mqtt connect error")
|
||||
status = .error
|
||||
}
|
||||
} else {
|
||||
delegate?.onMqttError(message: "Mqtt initialization error")
|
||||
status = .error
|
||||
}
|
||||
}
|
||||
|
|
@ -118,16 +136,11 @@ class MqttClientProxyManager {
|
|||
|
||||
extension MqttClientProxyManager: CocoaMQTTDelegate {
|
||||
|
||||
func mqtt(_ mqtt: CocoaMQTT, didReceive trust: SecTrust, completionHandler: @escaping (Bool) -> Void) {
|
||||
completionHandler(true)
|
||||
}
|
||||
|
||||
func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
|
||||
|
||||
print("📲 MQTT Client Proxy didConnectAck: \(ack)")
|
||||
if ack == .accept {
|
||||
let qos = CocoaMQTTQoS.qos1
|
||||
mqttClient!.subscribe(topic, qos: qos)
|
||||
delegate?.onMqttConnected()
|
||||
print("📲 MQTT Client Proxy subscribed to: " + topic)
|
||||
|
||||
} else {
|
||||
|
|
@ -150,25 +163,38 @@ extension MqttClientProxyManager: CocoaMQTTDelegate {
|
|||
errorDescription = "Unknown Error"
|
||||
}
|
||||
print(errorDescription)
|
||||
// mqttClient!.delegate.onMqttError(message: errorDescription)
|
||||
delegate?.onMqttError(message: errorDescription)
|
||||
|
||||
//self.disconnect() // Stop reconnecting
|
||||
self.disconnect() // Stop reconnecting
|
||||
//mqttSettings.isConnected = false // Disable automatic connect on start
|
||||
}
|
||||
|
||||
self.status = ack == .accept ? ConnectionStatus.connected : ConnectionStatus.error // Set AFTER sending onMqttError (so the delegate can detect that was an error while stablishing connection)
|
||||
self.status = ack == .accept ? ConnectionStatus.connected : ConnectionStatus.error // Set AFTER sending onMqttError (so the delegate can detect that was an error while establishing connection)
|
||||
}
|
||||
|
||||
func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) {
|
||||
print("mqttDidDisconnect: \(err?.localizedDescription ?? "")")
|
||||
|
||||
if let error = err, status == .connecting {
|
||||
delegate?.onMqttError(message: error.localizedDescription)
|
||||
}
|
||||
|
||||
status = err == nil ? .disconnected : .error
|
||||
delegate?.onMqttDisconnected()
|
||||
}
|
||||
|
||||
func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {
|
||||
print("📲 MQTT Client Proxy didPublishMessage: \(message)")
|
||||
print("📲 MQTT Client Proxy didPublishMessage from MqttClientProxyManager: \(message)")
|
||||
}
|
||||
|
||||
func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {
|
||||
print("📲 MQTT Client Proxy didPublishAck: \(id)")
|
||||
print("didPublishAck")
|
||||
print("📲 MQTT Client Proxy didPublishAck from MqttClientProxyManager: \(id)")
|
||||
}
|
||||
|
||||
|
||||
|
||||
func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
|
||||
delegate?.onMqttMessageReceived(message: message)
|
||||
print("📲 MQTT Client Proxy message received on topic: \(message.topic)")
|
||||
}
|
||||
|
||||
|
|
@ -181,14 +207,10 @@ extension MqttClientProxyManager: CocoaMQTTDelegate {
|
|||
}
|
||||
|
||||
func mqttDidPing(_ mqtt: CocoaMQTT) {
|
||||
print("mqttDidPing")
|
||||
//print("mqttDidPing")
|
||||
}
|
||||
|
||||
func mqttDidReceivePong(_ mqtt: CocoaMQTT) {
|
||||
print("mqttDidReceivePong")
|
||||
}
|
||||
|
||||
func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) {
|
||||
print("mqttDidDisconnect")
|
||||
//print("mqttDidReceivePong")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
8
Meshtastic/Views/Nodes/RemoteHardware.swift
Normal file
8
Meshtastic/Views/Nodes/RemoteHardware.swift
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
//
|
||||
// RemoteHardware.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Created by Garth Vander Houwen on 8/8/23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
Loading…
Add table
Add a link
Reference in a new issue