mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Merge pull request #112 from meshtastic/feature/module_settings
Admin Message History
This commit is contained in:
commit
e347154e76
16 changed files with 344 additions and 133 deletions
|
|
@ -13,6 +13,7 @@
|
|||
C9A7BC1027759A9600760B50 /* PositionAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A7BC0F27759A9600760B50 /* PositionAnnotationView.swift */; };
|
||||
C9A88B55278B503C00BD810A /* MapViewModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A88B54278B503C00BD810A /* MapViewModule.swift */; };
|
||||
C9A88B57278B559900BD810A /* apponly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A88B56278B559900BD810A /* apponly.pb.swift */; };
|
||||
DD0F791B28713C8A00A6FDAD /* AdminMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */; };
|
||||
DD17E5DE277D49D400010EC2 /* storeforward.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD17E5DC277D49D400010EC2 /* storeforward.pb.swift */; };
|
||||
DD1BF2F92776FE2E008C8D2F /* UserMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */; };
|
||||
DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */; };
|
||||
|
|
@ -99,6 +100,7 @@
|
|||
C9A7BC0F27759A9600760B50 /* PositionAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionAnnotationView.swift; sourceTree = "<group>"; };
|
||||
C9A88B54278B503C00BD810A /* MapViewModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MapViewModule.swift; sourceTree = "<group>"; };
|
||||
C9A88B56278B559900BD810A /* apponly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = apponly.pb.swift; sourceTree = "<group>"; };
|
||||
DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminMessageList.swift; sourceTree = "<group>"; };
|
||||
DD17E5DC277D49D400010EC2 /* storeforward.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = storeforward.pb.swift; sourceTree = "<group>"; };
|
||||
DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserMessageList.swift; sourceTree = "<group>"; };
|
||||
DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeripheralModel.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -244,6 +246,7 @@
|
|||
DD8169FE272476C700F4AB02 /* LogDocument.swift */,
|
||||
DD6B85A728009258000ACD6B /* ShareChannel.swift */,
|
||||
DDCE4E2B2869F92900BE9F8F /* UserConfig.swift */,
|
||||
DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */,
|
||||
DD61937A2863876A00E59241 /* Config */,
|
||||
);
|
||||
path = Settings;
|
||||
|
|
@ -659,6 +662,7 @@
|
|||
DD47E3D926F3093800029299 /* MessageBubble.swift in Sources */,
|
||||
DD415828285859C4009B0E59 /* TelemetryConfig.swift in Sources */,
|
||||
C9697F9D279336B700250207 /* LocalMBTileOverlay.swift in Sources */,
|
||||
DD0F791B28713C8A00A6FDAD /* AdminMessageList.swift in Sources */,
|
||||
DD8169F9271F1A6100F4AB02 /* MeshLogger.swift in Sources */,
|
||||
DD539502276DAA6A00AD86B1 /* MapLocation.swift in Sources */,
|
||||
DD41582A28585C32009B0E59 /* RangeTestConfig.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -892,65 +892,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
return false
|
||||
}
|
||||
|
||||
public func saveUser(config: User, entity: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setOwner = 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 = wantResponse
|
||||
meshPacket.hopLimit = 0
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
var toRadio: ToRadio!
|
||||
toRadio = ToRadio()
|
||||
toRadio.packet = meshPacket
|
||||
|
||||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.fromUser = entity
|
||||
newMessage.toUser = entity
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Admin Message for node number: \(String(entity.num))") }
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
} catch {
|
||||
|
||||
context!.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
|
||||
}
|
||||
}
|
||||
|
||||
return newMessageId
|
||||
}
|
||||
|
||||
public func sendFactoryReset(destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
|
||||
var deviceConfig = Config.DeviceConfig()
|
||||
|
|
@ -989,7 +930,69 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
return false
|
||||
}
|
||||
|
||||
public func saveDeviceConfig(config: Config.DeviceConfig, destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
public func saveUser(config: User, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setOwner = 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 = wantResponse
|
||||
meshPacket.hopLimit = 0
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
var toRadio: ToRadio!
|
||||
toRadio = ToRadio()
|
||||
toRadio.packet = meshPacket
|
||||
|
||||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(meshPacket.id)
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.adminDescription = "Saved User Config for \(toUser.longName ?? "Unknown")"
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new User Config Admin Message for node: \(String(toUser.num))") }
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
} catch {
|
||||
|
||||
context!.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
|
||||
}
|
||||
}
|
||||
|
||||
return newMessageId
|
||||
}
|
||||
|
||||
public func saveDeviceConfig(config: Config.DeviceConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setConfig.device = config
|
||||
|
|
@ -1015,16 +1018,40 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(meshPacket.id)
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.adminDescription = "Saved Device Config for \(toUser.longName ?? "Unknown")"
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
return true
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved Device Config Admin Message for node: \(String(toUser.num))") }
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
} catch {
|
||||
|
||||
context!.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return newMessageId
|
||||
}
|
||||
|
||||
public func saveDisplayConfig(config: Config.DisplayConfig, destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
public func saveDisplayConfig(config: Config.DisplayConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setConfig.display = config
|
||||
|
|
@ -1050,16 +1077,40 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(meshPacket.id)
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.adminDescription = "Saved Display Config for \(toUser.longName ?? "Unknown")"
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
return true
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved Display Config Admin Message for node: \(String(toUser.num))") }
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
} catch {
|
||||
|
||||
context!.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return newMessageId
|
||||
}
|
||||
|
||||
public func saveLoRaConfig(config: Config.LoRaConfig, destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
public func saveLoRaConfig(config: Config.LoRaConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setConfig.lora = config
|
||||
|
|
@ -1068,6 +1119,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
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 = wantResponse
|
||||
meshPacket.hopLimit = 0
|
||||
|
|
@ -1085,16 +1137,40 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(meshPacket.id)
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "IN"
|
||||
newMessage.admin = true
|
||||
newMessage.adminDescription = "Saved LoRa Config for \(toUser.longName ?? "Unknown")"
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
return true
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved LoRa Config Admin Message for node: \(String(toUser.num))") }
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
} catch {
|
||||
|
||||
context!.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return newMessageId
|
||||
}
|
||||
|
||||
public func savePositionConfig(config: Config.PositionConfig, destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
public func savePositionConfig(config: Config.PositionConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setConfig.position = config
|
||||
|
|
@ -1120,16 +1196,39 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(meshPacket.id)
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.adminDescription = "Saved Position Config for \(toUser.longName ?? "Unknown")"
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
return true
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved Position Config Admin Message for node: \(String(toUser.num))") }
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
} catch {
|
||||
|
||||
context!.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
|
||||
}
|
||||
}
|
||||
return newMessageId
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
public func saveCannedMessageModuleConfig(config: ModuleConfig.CannedMessageConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
public func saveCannedMessageModuleConfig(config: ModuleConfig.CannedMessageConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
|
|
@ -1158,12 +1257,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessage.messageId = Int64(meshPacket.id)
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.adminDescription = "Saved Canned Message Module Config for \(toUser.longName ?? "Unknown")"
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
|
@ -1172,7 +1272,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Canned Message Module Config Admin Message for node number: \(String(toUser.num))") }
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved Canned Message Module Config Admin Message for node: \(String(toUser.num))") }
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
} catch {
|
||||
|
|
@ -1215,12 +1315,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessage.messageId = Int64(meshPacket.id)
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.adminDescription = "Saved External Notification Module Config for \(toUser.longName ?? "Unknown")"
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
|
@ -1229,7 +1330,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Canned Message Module Config Admin Message for node number: \(String(toUser.num))") }
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved External Notification Module Config Admin Message for node: \(String(toUser.num))") }
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
} catch {
|
||||
|
|
@ -1274,12 +1375,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessage.messageId = Int64(meshPacket.id)
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.adminDescription = "Saved Range Test Module Config for \(toUser.longName ?? "Unknown")"
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
|
@ -1288,7 +1390,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Range Test Module Config Admin Message for node number: \(String(toUser.num))") }
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Range Test Module Config Admin Message for node: \(String(toUser.num))") }
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
} catch {
|
||||
|
|
@ -1334,12 +1436,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessage.messageId = Int64(meshPacket.id)
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.adminDescription = "Saved Serial Module Config for \(toUser.longName ?? "Unknown")"
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
|
@ -1348,7 +1451,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Telemetry Module Config Admin Message for node number: \(String(toUser.num))") }
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved Serial Module Config Admin Message for node: \(String(toUser.num))") }
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
} catch {
|
||||
|
|
@ -1392,12 +1495,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessage.messageId = Int64(meshPacket.id)
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.adminDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "Unknown")"
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
|
@ -1406,7 +1510,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Canned Message Module Config Admin Message for node number: \(String(toUser.num))") }
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved Telemetry Module Config Admin Message for node number: \(String(toUser.num))") }
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
} catch {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
<attribute name="ackSNR" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="ackTimestamp" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="admin" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="adminDescription" optional="YES" attributeType="String"/>
|
||||
<attribute name="direction" attributeType="String"/>
|
||||
<attribute name="isEmoji" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="messageId" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
|
|
@ -183,6 +184,9 @@
|
|||
<relationship name="receivedMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="toUser" inverseEntity="MessageEntity"/>
|
||||
<relationship name="sentMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="fromUser" inverseEntity="MessageEntity"/>
|
||||
<relationship name="userNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="user" inverseEntity="NodeInfoEntity"/>
|
||||
<fetchedProperty name="adminMessages" optional="YES">
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="(toUser.num == $FETCH_SOURCE.num) AND isEmoji == false AND admin = true"/>
|
||||
</fetchedProperty>
|
||||
<fetchedProperty name="allMessages" optional="YES">
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="((toUser.num == $FETCH_SOURCE.num) OR (fromUser.num == $FETCH_SOURCE.num)) AND isEmoji == false AND admin = false"/>
|
||||
</fetchedProperty>
|
||||
|
|
@ -192,14 +196,14 @@
|
|||
<element name="DeviceConfigEntity" positionX="45" positionY="144" width="128" height="104"/>
|
||||
<element name="DisplayConfigEntity" positionX="54" positionY="153" width="128" height="104"/>
|
||||
<element name="LoRaConfigEntity" positionX="45" positionY="144" width="128" height="104"/>
|
||||
<element name="MessageEntity" positionX="-36" positionY="63" width="128" height="230"/>
|
||||
<element name="MessageEntity" positionX="-36" positionY="63" width="128" height="245"/>
|
||||
<element name="MyInfoEntity" positionX="-18" positionY="81" width="128" height="209"/>
|
||||
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="299"/>
|
||||
<element name="PositionConfigEntity" positionX="63" positionY="162" width="128" height="149"/>
|
||||
<element name="PositionEntity" positionX="-54" positionY="54" width="128" height="119"/>
|
||||
<element name="RangeTestConfigEntity" positionX="72" positionY="171" width="128" height="104"/>
|
||||
<element name="TelemetryEntity" positionX="160" positionY="192" width="128" height="194"/>
|
||||
<element name="UserEntity" positionX="0" positionY="144" width="128" height="200"/>
|
||||
<element name="UserEntity" positionX="0" positionY="144" width="128" height="215"/>
|
||||
<element name="SerialConfigEntity" positionX="54" positionY="153" width="128" height="164"/>
|
||||
<element name="ExternalNotificationConfigEntity" positionX="63" positionY="162" width="128" height="149"/>
|
||||
<element name="TelemetryConfigEntity" positionX="72" positionY="171" width="128" height="179"/>
|
||||
|
|
|
|||
|
|
@ -13,4 +13,9 @@ extension UserEntity {
|
|||
|
||||
self.value(forKey: "allMessages") as! [MessageEntity]
|
||||
}
|
||||
|
||||
var adminMessageList: [MessageEntity] {
|
||||
|
||||
self.value(forKey: "adminMessages") as! [MessageEntity]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
//
|
||||
// DateTimeText.swift
|
||||
// MeshtasticApple
|
||||
// Meshtastic Apple
|
||||
//
|
||||
// Created by Garth Vander Houwen on 5/30/22.
|
||||
// Copyright(C) Garth Vander Houwen 5/30/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
|
|
|||
|
|
@ -24,16 +24,15 @@ struct Contacts: View {
|
|||
|
||||
List(users) { (user: UserEntity) in
|
||||
|
||||
let allMessages = user.value(forKey: "allMessages") as! [MessageEntity]
|
||||
let connectedNodeNum = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.num : 0
|
||||
|
||||
if user.num != connectedNodeNum {
|
||||
|
||||
NavigationLink(destination: UserMessageList(user: user)) {
|
||||
|
||||
if allMessages.count > 0 {
|
||||
if user.messageList.count > 0 {
|
||||
|
||||
let mostRecent = allMessages.last
|
||||
let mostRecent = user.messageList.last
|
||||
let lastMessageTime = Date(timeIntervalSince1970: TimeInterval(Int64((mostRecent!.messageTimestamp ))))
|
||||
let lastMessageDay = Calendar.current.dateComponents([.day], from: lastMessageTime).day ?? 0
|
||||
let currentDay = Calendar.current.dateComponents([.day], from: Date()).day ?? 0
|
||||
|
|
|
|||
72
Meshtastic/Views/Settings/AdminMessageList.swift
Normal file
72
Meshtastic/Views/Settings/AdminMessageList.swift
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// AdminMessageList.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Created by Garth Vander Houwen on 7/2/22.
|
||||
//
|
||||
/*
|
||||
Abstract:
|
||||
A view showing the details for a node.
|
||||
*/
|
||||
|
||||
import SwiftUI
|
||||
import MapKit
|
||||
import CoreLocation
|
||||
|
||||
struct AdminMessageList: View {
|
||||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
|
||||
var user: UserEntity?
|
||||
|
||||
var body: some View {
|
||||
|
||||
List {
|
||||
if user != nil {
|
||||
|
||||
ForEach ( user!.adminMessageList ) { am in
|
||||
|
||||
HStack {
|
||||
|
||||
Text("\(am.adminDescription ?? "Unknown") - \(Date(timeIntervalSince1970: TimeInterval(am.messageTimestamp)), style: .date) \(Date(timeIntervalSince1970: TimeInterval(am.messageTimestamp)), style: .time)")
|
||||
.font(.caption)
|
||||
|
||||
if am.receivedACK {
|
||||
|
||||
Image(systemName: "checkmark.square")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
Text("Acknowledged: ")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
DateTimeText(dateTime: Date(timeIntervalSince1970: TimeInterval(am.messageTimestamp)))
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
|
||||
} else {
|
||||
Image(systemName: "square")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
Text("Acknowledged")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("Admin Message History")
|
||||
.navigationBarItems(trailing:
|
||||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
self.bleManager.context = context
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -156,12 +156,6 @@ struct AppSettings: View {
|
|||
.pickerStyle(DefaultPickerStyle())
|
||||
|
||||
}
|
||||
Section(header: Text("DEBUG")) {
|
||||
|
||||
NavigationLink(destination: MeshLog()) {
|
||||
Text("View Mesh Log")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("App Settings")
|
||||
|
|
|
|||
|
|
@ -124,7 +124,9 @@ struct DeviceConfig: View {
|
|||
dc.serialDisabled = !serialEnabled
|
||||
dc.debugLogEnabled = debugLogEnabled
|
||||
|
||||
if bleManager.saveDeviceConfig(config: dc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
|
||||
let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: node.user!, toUser: node.user!, wantResponse: true)
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -203,7 +203,9 @@ struct DisplayConfig: View {
|
|||
dc.screenOnSecs = UInt32(screenOnSeconds)
|
||||
dc.autoScreenCarouselSecs = UInt32(screenCarouselInterval)
|
||||
|
||||
if bleManager.saveDisplayConfig(config: dc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
|
||||
let adminMessageId = bleManager.saveDisplayConfig(config: dc, fromUser: node.user!, toUser: node.user!, wantResponse: true)
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -263,7 +263,9 @@ struct LoRaConfig: View {
|
|||
lc.region = RegionCodes(rawValue: region)!.protoEnumValue()
|
||||
lc.modemPreset = ModemPresets(rawValue: modemPreset)!.protoEnumValue()
|
||||
|
||||
if bleManager.saveLoRaConfig(config: lc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
|
||||
let adminMessageId = bleManager.saveLoRaConfig(config: lc, fromUser: node.user!, toUser: node.user!, wantResponse: true)
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -311,15 +311,17 @@ struct TelemetryConfig: View {
|
|||
tc.environmentRecoveryInterval = UInt32(environmentRecoveryInterval)
|
||||
tc.environmentReadErrorCountThreshold = UInt32(environmentReadErrorCountThreshold)
|
||||
|
||||
//if bleManager.saveRangeTestModuleConfig(config: rtc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
|
||||
let adminMessageId = bleManager.saveTelemetryModuleConfig(config: tc, fromUser: node.user!, toUser: node.user!, wantResponse: true)
|
||||
|
||||
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
|
||||
hasChanges = false
|
||||
|
||||
//} else {
|
||||
} else {
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -282,7 +282,9 @@ struct PositionConfig: View {
|
|||
pc.gpsAttemptTime = UInt32(gpsAttemptTime)
|
||||
pc.positionBroadcastSecs = UInt32(positionBroadcastSeconds)
|
||||
|
||||
if bleManager.savePositionConfig(config: pc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
|
||||
let adminMessageId = bleManager.savePositionConfig(config: pc, fromUser: node.user!, toUser: node.user!, wantResponse: true)
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ struct MeshLog: View {
|
|||
)
|
||||
|
||||
.textSelection(.enabled)
|
||||
.font(.caption2)
|
||||
.font(.caption)
|
||||
|
||||
HStack(alignment: .center) {
|
||||
Spacer()
|
||||
|
|
|
|||
|
|
@ -25,27 +25,17 @@ struct Settings: View {
|
|||
|
||||
let connectedNodeNum = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.num : 0
|
||||
|
||||
Section("General") {
|
||||
NavigationLink {
|
||||
AppSettings()
|
||||
} label: {
|
||||
|
||||
Image(systemName: "gearshape")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("App Settings")
|
||||
}
|
||||
Text("Apple app specific settings and features, app username, share position with mesh options, map and keyboard type, mesh log.")
|
||||
.font(.caption)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
|
||||
NavigationLink {
|
||||
AppSettings()
|
||||
} label: {
|
||||
|
||||
Image(systemName: "gearshape")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("App Settings")
|
||||
}
|
||||
|
||||
Section("Radio Configuration") {
|
||||
|
||||
Text("Radio config views will be be enabled when there is a connected node. Save buttons will be enabled when there are config changes to save.")
|
||||
.font(.caption)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
|
||||
NavigationLink {
|
||||
ShareChannel(node: nodes.first(where: { $0.num == connectedNodeNum }) ?? NodeInfoEntity())
|
||||
} label: {
|
||||
|
|
@ -109,7 +99,7 @@ struct Settings: View {
|
|||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil)
|
||||
|
||||
Text("Default settings values are prefered whenever possible as they consume no bandwidth when sent over the mesh.")
|
||||
Text("Default settings values are prefered as they consume no bandwidth when sent over the mesh.")
|
||||
.font(.caption2)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
|
|
@ -173,6 +163,35 @@ struct Settings: View {
|
|||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil)
|
||||
}
|
||||
Section(header: Text("Logging")) {
|
||||
|
||||
NavigationLink {
|
||||
|
||||
MeshLog()
|
||||
|
||||
} label: {
|
||||
|
||||
Image(systemName: "list.bullet.rectangle")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
|
||||
Text("Mesh Log")
|
||||
}
|
||||
|
||||
NavigationLink {
|
||||
|
||||
let connectedNode = nodes.first(where: { $0.num == connectedNodeNum })
|
||||
|
||||
AdminMessageList(user: connectedNode?.user ?? UserEntity())
|
||||
} label: {
|
||||
|
||||
Image(systemName: "building.columns")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
|
||||
Text("Admin Message Log")
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil)
|
||||
}
|
||||
|
||||
// Not Implemented:
|
||||
// Store Forward Config - Not Working, TBEAM Only
|
||||
// WiFi Config - Would break connection to device
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ struct UserConfig: View {
|
|||
u.shortName = shortName
|
||||
u.longName = longName
|
||||
|
||||
let adminMessageId = bleManager.saveUser(config: u, entity: node.user!, wantResponse: true)
|
||||
let adminMessageId = bleManager.saveUser(config: u, fromUser: node.user!, toUser: node.user!, wantResponse: true)
|
||||
|
||||
if adminMessageId > 0 {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue