mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Merge pull request #303 from meshtastic/working_changes_2.0.12
Working changes 2.0.12
This commit is contained in:
commit
60b4a5182e
16 changed files with 372 additions and 304 deletions
|
|
@ -295,10 +295,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
|
||||
guard (connectedPeripheral!.peripheral.state == CBPeripheralState.connected) else { return 0 }
|
||||
|
||||
let nodeName = connectedPeripheral!.peripheral.name ?? NSLocalizedString("unknown", comment: NSLocalizedString("unknown", comment: "Unknown"))
|
||||
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.devicemetadata %@",
|
||||
comment: "Requesting Device Metadata for %@"), nodeName)
|
||||
MeshLogger.log("🛎️ \(logString)")
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.getDeviceMetadataRequest = true
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
|
|
@ -307,6 +303,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
|
|
@ -322,13 +319,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
func sendTraceRouteRequest(destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
|
||||
var success = false
|
||||
guard (connectedPeripheral!.peripheral.state == CBPeripheralState.connected) else { return success }
|
||||
|
||||
let fromNodeNum = connectedPeripheral.num
|
||||
|
||||
let routePacket = RouteDiscovery()
|
||||
|
||||
var meshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(destNum)
|
||||
meshPacket.from = UInt32(fromNodeNum)//0 // Send 0 as from from phone to device to avoid warning about client trying to set node num
|
||||
meshPacket.from = UInt32(fromNodeNum)
|
||||
meshPacket.wantAck = true
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! routePacket.serializedData()
|
||||
dataMessage.portnum = PortNum.tracerouteApp
|
||||
|
|
@ -831,7 +829,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
public func sendShutdown(fromUser: UserEntity, toUser: UserEntity) -> Bool {
|
||||
public func sendShutdown(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.shutdownSeconds = 5
|
||||
|
|
@ -841,12 +839,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Sent Shutdown Admin Message to: \(toUser.longName ?? NSLocalizedString("unknown", comment: ""))"
|
||||
let messageDescription = "🚀 Sent Shutdown Admin Message to: \(toUser.longName ?? NSLocalizedString("unknown", comment: "")) from: \(fromUser.longName ?? NSLocalizedString("unknown", comment: ""))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return true
|
||||
}
|
||||
|
|
@ -854,7 +853,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
return false
|
||||
}
|
||||
|
||||
public func sendReboot(fromUser: UserEntity, toUser: UserEntity) -> Bool {
|
||||
public func sendReboot(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.rebootSeconds = 5
|
||||
|
|
@ -865,13 +864,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Sent Reboot Admin Message to: \(toUser.longName ?? NSLocalizedString("unknown", comment: ""))"
|
||||
let messageDescription = "🚀 Sent Reboot Admin Message to: \(toUser.longName ?? NSLocalizedString("unknown", comment: "")) from: \(fromUser.longName ?? NSLocalizedString("unknown", comment: ""))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return true
|
||||
}
|
||||
|
|
@ -881,7 +880,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
public func sendFactoryReset(fromUser: UserEntity, toUser: UserEntity) -> Bool {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.factoryReset = 1
|
||||
adminPacket.factoryReset = 5
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
|
|
@ -895,7 +894,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Sent Factory Reset Admin Message to: \(toUser.longName ?? NSLocalizedString("unknown", comment: ""))"
|
||||
let messageDescription = "🚀 Sent Factory Reset Admin Message to: \(toUser.longName ?? NSLocalizedString("unknown", comment: "")) from: \(fromUser.longName ?? NSLocalizedString("unknown", comment: ""))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return true
|
||||
}
|
||||
|
|
@ -905,7 +904,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
public func sendNodeDBReset(fromUser: UserEntity, toUser: UserEntity) -> Bool {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.nodedbReset = 1
|
||||
adminPacket.nodedbReset = 10
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
|
|
@ -913,13 +912,12 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
let messageDescription = "Sent NodeDB Reset Admin Message to: \(toUser.longName ?? NSLocalizedString("unknown", comment: ""))"
|
||||
let messageDescription = "🚀 Sent NodeDB Reset Admin Message to: \(toUser.longName ?? NSLocalizedString("unknown", comment: "")) from: \(fromUser.longName ?? NSLocalizedString("unknown", comment: ""))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return true
|
||||
}
|
||||
|
|
@ -1109,7 +1107,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
let messageDescription = "Saved User Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
let messageDescription = "🛟 Saved User Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return Int64(meshPacket.id)
|
||||
|
|
@ -1118,13 +1116,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
return 0
|
||||
}
|
||||
|
||||
public func saveBluetoothConfig(config: Config.BluetoothConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
public func saveBluetoothConfig(config: Config.BluetoothConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setConfig.bluetooth = config
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedPeripheral.num)
|
||||
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
|
@ -1132,7 +1131,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
let messageDescription = "Saved Bluetooth Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
let messageDescription = "🛟 Saved Bluetooth Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return Int64(meshPacket.id)
|
||||
|
|
@ -1141,14 +1140,15 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
return 0
|
||||
}
|
||||
|
||||
public func saveDeviceConfig(config: Config.DeviceConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
public func saveDeviceConfig(config: Config.DeviceConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setConfig.device = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedPeripheral.num)
|
||||
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
|
@ -1157,7 +1157,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved Device Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
let messageDescription = "🛟 Saved Device Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
|
||||
|
|
@ -1167,13 +1167,16 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
return 0
|
||||
}
|
||||
|
||||
public func saveDisplayConfig(config: Config.DisplayConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
public func saveDisplayConfig(config: Config.DisplayConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setConfig.display = config
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedPeripheral.num)
|
||||
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
if adminIndex > 0 {
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
}
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
|
@ -1182,7 +1185,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
let messageDescription = "Saved Display Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
let messageDescription = "🛟 Saved Display Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return Int64(meshPacket.id)
|
||||
|
|
@ -1208,7 +1211,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
let messageDescription = "Saved LoRa Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
let messageDescription = "🛟 Saved LoRa Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return Int64(meshPacket.id)
|
||||
|
|
@ -1217,14 +1220,15 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
return 0
|
||||
}
|
||||
|
||||
public func savePositionConfig(config: Config.PositionConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
public func savePositionConfig(config: Config.PositionConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setConfig.position = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedPeripheral.num)
|
||||
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
|
@ -1236,7 +1240,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved Position Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
let messageDescription = "🛟 Saved Position Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
|
||||
|
|
@ -1246,14 +1250,15 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
return 0
|
||||
}
|
||||
|
||||
public func saveNetworkConfig(config: Config.NetworkConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
public func saveNetworkConfig(config: Config.NetworkConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setConfig.network = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedPeripheral.num)
|
||||
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
|
@ -1265,35 +1270,147 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛟 Saved Network Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
public func saveCannedMessageModuleConfig(config: ModuleConfig.CannedMessageConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.cannedMessage = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛟 Saved Canned Message Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
public func saveCannedMessageModuleMessages(messages: String, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setCannedMessageModuleMessages = messages
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
dataMessage.wantResponse = true
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛟 Saved Canned Message Module Messages for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
public func saveExternalNotificationModuleConfig(config: ModuleConfig.ExternalNotificationConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.externalNotification = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved External Notification Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
public func saveMQTTConfig(config: ModuleConfig.MQTTConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.mqtt = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
meshPacket.hopLimit = 0
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved WiFi Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
public func saveCannedMessageModuleConfig(config: ModuleConfig.CannedMessageConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
public func saveRangeTestModuleConfig(config: ModuleConfig.RangeTestConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.rangeTest = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.cannedMessage = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = 0 //UInt32(fromUser.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved Canned Message Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
let messageDescription = "Saved Range Test Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
|
||||
|
|
@ -1303,32 +1420,54 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
return 0
|
||||
}
|
||||
|
||||
public func saveCannedMessageModuleMessages(messages: String, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
public func saveSerialModuleConfig(config: ModuleConfig.SerialConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setCannedMessageModuleMessages = messages
|
||||
adminPacket.setModuleConfig.serial = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = 0 //UInt32(fromUser.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
meshPacket.hopLimit = 0
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved Serial Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
public func saveTelemetryModuleConfig(config: ModuleConfig.TelemetryConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.telemetry = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
dataMessage.wantResponse = wantResponse
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "💾 Saved Canned Message Module Messages for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
|
||||
let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
@ -1339,7 +1478,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = 0 //UInt32(cnodeNum)
|
||||
meshPacket.from = UInt32(fromUser.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = wantResponse
|
||||
|
|
@ -1367,8 +1506,8 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
adminPacket.getCannedMessageModuleMessagesRequest = true
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedPeripheral.num)
|
||||
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
|
||||
meshPacket.to = UInt32(destNum)
|
||||
meshPacket.from = UInt32(connectedPeripheral.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
|
@ -1408,6 +1547,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1435,6 +1575,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1462,6 +1603,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1489,6 +1631,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1518,6 +1661,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1544,6 +1688,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1570,6 +1715,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1596,6 +1742,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1622,6 +1769,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1648,6 +1796,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1674,6 +1823,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1700,6 +1850,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1715,133 +1866,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
return false
|
||||
}
|
||||
|
||||
public func saveExternalNotificationModuleConfig(config: ModuleConfig.ExternalNotificationConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.externalNotification = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = 0 //UInt32(fromUser.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved External Notification Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
public func saveMQTTConfig(config: ModuleConfig.MQTTConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.mqtt = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedPeripheral.num)
|
||||
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
meshPacket.hopLimit = 0
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved WiFi Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
public func saveRangeTestModuleConfig(config: ModuleConfig.RangeTestConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.rangeTest = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = 0 //UInt32(fromUser.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved Range Test Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
public func saveSerialModuleConfig(config: ModuleConfig.SerialConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.serial = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedPeripheral.num)
|
||||
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
meshPacket.hopLimit = 0
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved Serial Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
public func saveTelemetryModuleConfig(config: ModuleConfig.TelemetryConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.telemetry = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = 0 //UInt32(fromUser.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Send an admin message to a radio, save a message to core data for logging
|
||||
private func sendAdminMessageToRadio(meshPacket: MeshPacket, adminDescription: String, fromUser: UserEntity, toUser: UserEntity) -> Bool {
|
||||
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ func deviceMetadataPacket (metadata: DeviceMetadata, fromNum: Int64, context: NS
|
|||
newMetadata.role = Int32(metadata.role.rawValue)
|
||||
newMetadata.positionFlags = Int32(metadata.positionFlags)
|
||||
fetchedNode[0].metadata = newMetadata
|
||||
|
||||
|
||||
do {
|
||||
try context.save()
|
||||
} catch {
|
||||
|
|
@ -525,6 +525,35 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
|
|||
} else {
|
||||
MeshLogger.log("🕸️ MESH PACKET received for Admin App \(try! packet.decoded.jsonString())")
|
||||
}
|
||||
|
||||
// Save an ack for the admin message log for each admin message response received as we stopped sending acks if there is also a response to reduce airtime.
|
||||
adminResponseAck(packet: packet, context: context)
|
||||
}
|
||||
}
|
||||
|
||||
func adminResponseAck (packet: MeshPacket, context: NSManagedObjectContext) {
|
||||
|
||||
let fetchedAdminMessageRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MessageEntity")
|
||||
fetchedAdminMessageRequest.predicate = NSPredicate(format: "messageId == %lld", packet.decoded.requestID)
|
||||
do {
|
||||
let fetchedMessage = try context.fetch(fetchedAdminMessageRequest) as! [MessageEntity]
|
||||
if fetchedMessage.count > 0 {
|
||||
fetchedMessage[0].ackTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
fetchedMessage[0].ackError = Int32(RoutingError.none.rawValue)
|
||||
fetchedMessage[0].receivedACK = true
|
||||
fetchedMessage[0].realACK = true
|
||||
fetchedMessage[0].ackSNR = packet.rxSnr
|
||||
if fetchedMessage[0].fromUser != nil {
|
||||
fetchedMessage[0].fromUser?.objectWillChange.send()
|
||||
}
|
||||
do {
|
||||
try context.save()
|
||||
} catch {
|
||||
print("Failed to save admin message response as an ack")
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
print("Failed to fetch admin message by requestID")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -357,11 +357,12 @@ struct NodeDetail: View {
|
|||
}
|
||||
}
|
||||
|
||||
if self.bleManager.connectedPeripheral != nil && self.bleManager.connectedPeripheral.num == node.num && self.bleManager.connectedPeripheral.num == node.num {
|
||||
if (self.bleManager.connectedPeripheral != nil && self.bleManager.connectedPeripheral.num == node.num)
|
||||
|| (self.bleManager.connectedPeripheral != nil && node.metadata != nil) {
|
||||
|
||||
HStack {
|
||||
|
||||
if node.metadata != nil && node.metadata?.canShutdown ?? false {
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if node.metadata?.canShutdown ?? false {
|
||||
|
||||
Button(action: {
|
||||
showingShutdownConfirm = true
|
||||
|
|
@ -378,7 +379,7 @@ struct NodeDetail: View {
|
|||
isPresented: $showingShutdownConfirm
|
||||
) {
|
||||
Button("Shutdown Node?", role: .destructive) {
|
||||
if !bleManager.sendShutdown(fromUser: node.user!, toUser: node.user!) {
|
||||
if !bleManager.sendShutdown(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo!.adminIndex) {
|
||||
print("Shutdown Failed")
|
||||
}
|
||||
}
|
||||
|
|
@ -398,7 +399,7 @@ struct NodeDetail: View {
|
|||
isPresented: $showingRebootConfirm
|
||||
) {
|
||||
Button("reboot.node", role: .destructive) {
|
||||
if !bleManager.sendReboot(fromUser: node.user!, toUser: node.user!) {
|
||||
if !bleManager.sendReboot(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo!.adminIndex) {
|
||||
print("Reboot Failed")
|
||||
}
|
||||
}
|
||||
|
|
@ -407,21 +408,22 @@ struct NodeDetail: View {
|
|||
.padding(5)
|
||||
Divider()
|
||||
}
|
||||
|
||||
VStack {
|
||||
AsyncImage(url: attributionLogo) { image in
|
||||
image
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
} placeholder: {
|
||||
ProgressView()
|
||||
.controlSize(.mini)
|
||||
if node.positions?.count ?? 0 > 0 {
|
||||
VStack {
|
||||
AsyncImage(url: attributionLogo) { image in
|
||||
image
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
} placeholder: {
|
||||
ProgressView()
|
||||
.controlSize(.mini)
|
||||
}
|
||||
.frame(height: 15)
|
||||
|
||||
Link("Other data sources", destination: attributionLink ?? URL(string: "https://weather-data.apple.com/legal-attribution.html")!)
|
||||
}
|
||||
.frame(height: 15)
|
||||
|
||||
Link("Other data sources", destination: attributionLink ?? URL(string: "https://weather-data.apple.com/legal-attribution.html")!)
|
||||
.font(.footnote)
|
||||
}
|
||||
.font(.footnote)
|
||||
}
|
||||
}
|
||||
.edgesIgnoringSafeArea([.leading, .trailing])
|
||||
|
|
@ -440,6 +442,16 @@ struct NodeDetail: View {
|
|||
})
|
||||
.onAppear {
|
||||
self.bleManager.context = context
|
||||
|
||||
if bleManager.connectedPeripheral != nil {
|
||||
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if connectedNode.myInfo != nil {
|
||||
|
||||
let adminMessageId = bleManager.requestDeviceMetadata(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo!.adminIndex, context: context)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.task(id: node.num) {
|
||||
do {
|
||||
|
|
@ -456,9 +468,7 @@ struct NodeDetail: View {
|
|||
let attribution = try await WeatherService.shared.attribution
|
||||
attributionLink = attribution.legalPageURL
|
||||
attributionLogo = colorScheme == .light ? attribution.combinedMarkLightURL : attribution.combinedMarkDarkURL
|
||||
|
||||
}
|
||||
|
||||
} catch {
|
||||
print("Could not gather weather information...", error.localizedDescription)
|
||||
condition = .clear
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
// Created by Garth Vander Houwen on 7/2/22.
|
||||
//
|
||||
/*
|
||||
Abstract:
|
||||
A view showing the details for a node.
|
||||
*/
|
||||
Abstract:
|
||||
A view showing the details for a node.
|
||||
*/
|
||||
|
||||
import SwiftUI
|
||||
import MapKit
|
||||
|
|
@ -17,39 +17,41 @@ struct AdminMessageList: View {
|
|||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
|
||||
|
||||
var user: UserEntity?
|
||||
|
||||
|
||||
var body: some View {
|
||||
let localeDateFormat = DateFormatter.dateFormat(fromTemplate: "yyMMddjmmssa", options: 0, locale: Locale.current)
|
||||
let dateFormatString = (localeDateFormat ?? "MM/dd/YY j:mm:ss a")
|
||||
List {
|
||||
if user != nil {
|
||||
|
||||
ForEach ( user!.adminMessageList ) { am in
|
||||
|
||||
HStack {
|
||||
ForEach ( user!.adminMessageList.reversed() ) { am in
|
||||
|
||||
VStack (alignment: .leading) {
|
||||
|
||||
Text("\(am.adminDescription ?? NSLocalizedString("unknown", comment: "Unknown")) - \(Date(timeIntervalSince1970: TimeInterval(am.messageTimestamp)).formattedDate(format: dateFormatString))")
|
||||
.font(.caption)
|
||||
.font(.caption2)
|
||||
|
||||
if am.receivedACK {
|
||||
|
||||
Image(systemName: "checkmark.square")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
Text("routing.acknowledged").foregroundColor(.gray).font(.caption) + Text(": \(Date(timeIntervalSince1970: TimeInterval(am.ackTimestamp)).formattedDate(format: "h:mm:ss a"))")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
|
||||
} else {
|
||||
let ackErrorVal = RoutingError(rawValue: Int(am.ackError))
|
||||
Image(systemName: "square")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
Text(ackErrorVal?.display ?? "Empty Ack Error")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
HStack{
|
||||
if am.receivedACK {
|
||||
|
||||
Image(systemName: "checkmark.square")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
Text("routing.acknowledged").foregroundColor(.gray).font(.caption) + Text(": \(Date(timeIntervalSince1970: TimeInterval(am.ackTimestamp)).formattedDate(format: "h:mm:ss a"))")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
|
||||
} else {
|
||||
let ackErrorVal = RoutingError(rawValue: Int(am.ackError))
|
||||
Image(systemName: "square")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
Text(ackErrorVal?.display ?? "Empty Ack Error")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -57,7 +59,7 @@ struct AdminMessageList: View {
|
|||
}
|
||||
.navigationTitle("admin.log")
|
||||
.navigationBarItems(trailing:
|
||||
ZStack {
|
||||
ZStack {
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ struct BluetoothConfig: View {
|
|||
bc.enabled = enabled
|
||||
bc.mode = BluetoothModes(rawValue: mode)?.protoEnumValue() ?? Config.BluetoothConfig.PairingMode.randomPin
|
||||
bc.fixedPin = UInt32(fixedPin) ?? 123456
|
||||
let adminMessageId = bleManager.saveBluetoothConfig(config: bc, fromUser: connectedNode.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveBluetoothConfig(config: bc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
|
|||
|
|
@ -87,56 +87,59 @@ struct DeviceConfig: View {
|
|||
}
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.deviceConfig == nil)
|
||||
|
||||
HStack {
|
||||
|
||||
Button("Reset NodeDB", role: .destructive) {
|
||||
isPresentingNodeDBResetConfirm = true
|
||||
}
|
||||
.disabled(node?.user == nil)
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
.padding()
|
||||
.confirmationDialog(
|
||||
"are.you.sure",
|
||||
isPresented: $isPresentingNodeDBResetConfirm,
|
||||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Erase all device and app data?", role: .destructive) {
|
||||
if bleManager.sendNodeDBReset(fromUser: node!.user!, toUser: node!.user!) {
|
||||
bleManager.disconnectPeripheral()
|
||||
clearCoreDataDatabase(context: context)
|
||||
} else {
|
||||
print("NodeDB Reset Failed")
|
||||
// Only show these buttons for the BLE connected node
|
||||
if bleManager.connectedPeripheral != nil && node?.num ?? -1 == bleManager.connectedPeripheral.num {
|
||||
HStack {
|
||||
|
||||
Button("Reset NodeDB", role: .destructive) {
|
||||
isPresentingNodeDBResetConfirm = true
|
||||
}
|
||||
.disabled(node?.user == nil)
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
.padding()
|
||||
.confirmationDialog(
|
||||
"are.you.sure",
|
||||
isPresented: $isPresentingNodeDBResetConfirm,
|
||||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Erase all device and app data?", role: .destructive) {
|
||||
|
||||
if bleManager.sendNodeDBReset(fromUser: node!.user!, toUser: node!.user!) {
|
||||
bleManager.disconnectPeripheral()
|
||||
clearCoreDataDatabase(context: context)
|
||||
} else {
|
||||
print("NodeDB Reset Failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Button("Factory Reset", role: .destructive) {
|
||||
isPresentingFactoryResetConfirm = true
|
||||
}
|
||||
.disabled(node?.user == nil)
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
.padding()
|
||||
.confirmationDialog(
|
||||
"All device and app data will be deleted. You will also need to forget your devices under Settings > Bluetooth.",
|
||||
isPresented: $isPresentingFactoryResetConfirm,
|
||||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Factory reset your device and app? ", role: .destructive) {
|
||||
|
||||
if bleManager.sendFactoryReset(fromUser: node!.user!, toUser: node!.user!) {
|
||||
bleManager.disconnectPeripheral()
|
||||
clearCoreDataDatabase(context: context)
|
||||
} else {
|
||||
print("Factory Reset Failed")
|
||||
Button("Factory Reset", role: .destructive) {
|
||||
isPresentingFactoryResetConfirm = true
|
||||
}
|
||||
.disabled(node?.user == nil)
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
.padding()
|
||||
.confirmationDialog(
|
||||
"All device and app data will be deleted. You will also need to forget your devices under Settings > Bluetooth.",
|
||||
isPresented: $isPresentingFactoryResetConfirm,
|
||||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Factory reset your device and app? ", role: .destructive) {
|
||||
|
||||
if bleManager.sendFactoryReset(fromUser: node!.user!, toUser: node!.user!) {
|
||||
bleManager.disconnectPeripheral()
|
||||
clearCoreDataDatabase(context: context)
|
||||
} else {
|
||||
print("Factory Reset Failed")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HStack {
|
||||
|
||||
Button {
|
||||
|
|
@ -167,7 +170,7 @@ struct DeviceConfig: View {
|
|||
dc.buttonGpio = UInt32(buttonGPIO)
|
||||
dc.buzzerGpio = UInt32(buzzerGPIO)
|
||||
|
||||
let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: connectedNode.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ struct DisplayConfig: View {
|
|||
dc.oled = OledTypes(rawValue: oledType)!.protoEnumValue()
|
||||
dc.displaymode = DisplayModes(rawValue: displayMode)!.protoEnumValue()
|
||||
|
||||
let adminMessageId = bleManager.saveDisplayConfig(config: dc, fromUser: connectedNode.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveDisplayConfig(config: dc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ struct CannedMessagesConfig: View {
|
|||
cmc.inputbrokerEventCw = InputEventChars(rawValue: inputbrokerEventCw)!.protoEnumValue()
|
||||
cmc.inputbrokerEventCcw = InputEventChars(rawValue: inputbrokerEventCcw)!.protoEnumValue()
|
||||
cmc.inputbrokerEventPress = InputEventChars(rawValue: inputbrokerEventPress)!.protoEnumValue()
|
||||
let adminMessageId = bleManager.saveCannedMessageModuleConfig(config: cmc, fromUser: node!.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveCannedMessageModuleConfig(config: cmc, fromUser: node!.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
@ -251,7 +251,7 @@ struct CannedMessagesConfig: View {
|
|||
}
|
||||
}
|
||||
if hasMessagesChanges {
|
||||
let adminMessageId = bleManager.saveCannedMessageModuleMessages(messages: messages, fromUser: node!.user!, toUser: node!.user!, wantResponse: true)
|
||||
let adminMessageId = bleManager.saveCannedMessageModuleMessages(messages: messages, fromUser: node!.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ struct ExternalNotificationConfig: View {
|
|||
enc.outputVibra = UInt32(outputVibra)
|
||||
enc.outputMs = UInt32(outputMilliseconds)
|
||||
enc.usePwm = usePWM
|
||||
let adminMessageId = bleManager.saveExternalNotificationModuleConfig(config: enc, fromUser: connectedNode.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveExternalNotificationModuleConfig(config: enc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0{
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ struct MQTTConfig: View {
|
|||
mqtt.password = self.password
|
||||
mqtt.encryptionEnabled = self.encryptionEnabled
|
||||
mqtt.jsonEnabled = self.jsonEnabled
|
||||
let adminMessageId = bleManager.saveMQTTConfig(config: mqtt, fromUser: connectedNode.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveMQTTConfig(config: mqtt, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ struct RangeTestConfig: View {
|
|||
rtc.enabled = enabled
|
||||
rtc.save = save
|
||||
rtc.sender = UInt32(sender)
|
||||
let adminMessageId = bleManager.saveRangeTestModuleConfig(config: rtc, fromUser: connectedNode.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveRangeTestModuleConfig(config: rtc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ struct SerialConfig: View {
|
|||
sc.timeout = UInt32(timeout)
|
||||
sc.mode = SerialModeTypes(rawValue: mode)!.protoEnumValue()
|
||||
|
||||
let adminMessageId = bleManager.saveSerialModuleConfig(config: sc, fromUser: connectedNode.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveSerialModuleConfig(config: sc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ struct TelemetryConfig: View {
|
|||
tc.environmentMeasurementEnabled = environmentMeasurementEnabled
|
||||
tc.environmentScreenEnabled = environmentScreenEnabled
|
||||
tc.environmentDisplayFahrenheit = environmentDisplayFahrenheit
|
||||
let adminMessageId = bleManager.saveTelemetryModuleConfig(config: tc, fromUser: connectedNode.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveTelemetryModuleConfig(config: tc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ struct NetworkConfig: View {
|
|||
network.ethEnabled = self.ethEnabled
|
||||
//network.addressMode = Config.NetworkConfig.AddressMode.dhcp
|
||||
|
||||
let adminMessageId = bleManager.saveNetworkConfig(config: network, fromUser: connectedNode.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveNetworkConfig(config: network, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ struct PositionConfig: View {
|
|||
if includeSpeed { pf.insert(.Speed) }
|
||||
if includeHeading { pf.insert(.Heading) }
|
||||
pc.positionFlags = UInt32(pf.rawValue)
|
||||
let adminMessageId = bleManager.savePositionConfig(config: pc, fromUser: connectedNode.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.savePositionConfig(config: pc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ struct Settings: View {
|
|||
let adminMessageId = bleManager.requestDeviceMetadata(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode!.myInfo!.adminIndex, context: context)
|
||||
|
||||
if adminMessageId > 0 {
|
||||
print("Saved node metadata")
|
||||
print("Sent node metadata request from node details")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue