From 677963be59fcf262484fcb368e97f2d40363705d Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 29 Dec 2021 16:13:17 -0800 Subject: [PATCH 1/2] clearDatabase on error --- .../Persistence/Persistence.swift | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/MeshtasticClient/Persistence/Persistence.swift b/MeshtasticClient/Persistence/Persistence.swift index 9168f07d..8c0c00f7 100644 --- a/MeshtasticClient/Persistence/Persistence.swift +++ b/MeshtasticClient/Persistence/Persistence.swift @@ -32,6 +32,7 @@ class PersistenceController { let container: NSPersistentContainer init(inMemory: Bool = false) { + container = NSPersistentContainer(name: "Meshtastic") if inMemory { container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") @@ -39,7 +40,7 @@ class PersistenceController { container.loadPersistentStores(completionHandler: { (_, error) in // Merge policy that favors in memory data over data in the db self.container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy - + self.container.viewContext.automaticallyMergesChangesFromParent = true if let error = error as NSError? { // Replace this implementation with code to handle the error appropriately. @@ -53,21 +54,22 @@ class PersistenceController { * The store could not be migrated to the current model version. Check the error message to determine what the actual problem was. */ - - let firstStoreURL = self.container.persistentStoreCoordinator.persistentStores.first?.url - - do { - - try self.container.persistentStoreCoordinator.destroyPersistentStore(at: firstStoreURL!, type: .sqlite, options: nil) - - print("💥 Something went terribly wrong, CoreData database truncated. All app data is lost.") - - } catch { - print("💣 Failed to destroy broken CoreData database, delete the app.") - } - - print("💣💥 Unresolved error \(error), \(error.userInfo)") + self.clearDatabase() } }) } + + public func clearDatabase() { + guard let url = self.container.persistentStoreDescriptions.first?.url else { return } + + let persistentStoreCoordinator = self.container.persistentStoreCoordinator + + do { + try persistentStoreCoordinator.destroyPersistentStore(at:url, ofType: NSSQLiteStoreType, options: nil) + print("💥 Something went terribly wrong, CoreData database truncated. All app data is lost.") + try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil) + } catch let error { + print("💣 Failed to destroy broken CoreData database, delete the app. Attempted to clear persistent store: " + error.localizedDescription) + } + } } From 959e2c02eb1a9f898da383d6e3b8bb42a8cf5cca Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 31 Dec 2021 09:43:37 -0800 Subject: [PATCH 2/2] Update protobufs, add messaging features for core data, remove timer from messages view --- Meshtastic Client.xcodeproj/project.pbxproj | 16 +- MeshtasticClient/Helpers/BLEManager.swift | 46 +- .../CoreDataSample.xcdatamodel/contents | 4 +- .../Persistence/Persistence.swift | 5 +- MeshtasticClient/Protobufs/admin.pb.swift | 84 +- MeshtasticClient/Protobufs/channel.pb.swift | 58 +- .../Protobufs/deviceonly.pb.swift | 48 +- .../environmental_measurement.pb.swift | 4 +- MeshtasticClient/Protobufs/mesh.pb.swift | 1172 +++++++++++------ MeshtasticClient/Protobufs/mqtt.pb.swift | 104 +- MeshtasticClient/Protobufs/portnums.pb.swift | 8 +- .../Protobufs/radioconfig.pb.swift | 134 +- .../Protobufs/remote_hardware.pb.swift | 10 +- .../Protobufs/storeforward.pb.swift | 190 ++- .../Views/Messages/Channels.swift | 4 +- .../Views/Messages/Messages.swift | 18 +- MeshtasticClient/Views/Nodes/NodeMap.swift | 11 +- 17 files changed, 1209 insertions(+), 707 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index e10d6620..98ec63f9 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ C9483F6D2773017500998F6B /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9483F6C2773017500998F6B /* MapView.swift */; }; C9A7BC1027759A9600760B50 /* PositionAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A7BC0F27759A9600760B50 /* PositionAnnotationView.swift */; }; + DD17E5DD277D49D400010EC2 /* apponly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD17E5DB277D49D400010EC2 /* apponly.pb.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 */; }; DD2E65262767A01F00E45FC5 /* NodeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2E65252767A01F00E45FC5 /* NodeDetail.swift */; }; @@ -72,6 +74,8 @@ /* Begin PBXFileReference section */ C9483F6C2773017500998F6B /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; C9A7BC0F27759A9600760B50 /* PositionAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionAnnotationView.swift; sourceTree = ""; }; + DD17E5DB277D49D400010EC2 /* apponly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = apponly.pb.swift; sourceTree = ""; }; + DD17E5DC277D49D400010EC2 /* storeforward.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = storeforward.pb.swift; sourceTree = ""; }; DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserMessageList.swift; sourceTree = ""; }; DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeripheralModel.swift; sourceTree = ""; }; DD2E65252767A01F00E45FC5 /* NodeDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeDetail.swift; sourceTree = ""; }; @@ -202,6 +206,8 @@ DDAF8C5626ED07740058C060 /* Protobufs */ = { isa = PBXGroup; children = ( + DD17E5DB277D49D400010EC2 /* apponly.pb.swift */, + DD17E5DC277D49D400010EC2 /* storeforward.pb.swift */, DDAF8C5E26ED09B50058C060 /* radioconfig.pb.swift */, DDAF8C6426ED0A490058C060 /* channel.pb.swift */, DDAF8C6826ED0D070058C060 /* deviceonly.pb.swift */, @@ -537,6 +543,7 @@ DD47E3CE26F103C600029299 /* NodeList.swift in Sources */, DD47E3D626F17ED900029299 /* CircleText.swift in Sources */, DDC2E18F26CE25FE0042C5E4 /* ContentView.swift in Sources */, + DD17E5DE277D49D400010EC2 /* storeforward.pb.swift in Sources */, DDAF8C6326ED0A230058C060 /* admin.pb.swift in Sources */, C9483F6D2773017500998F6B /* MapView.swift in Sources */, DDAF8C5826ED07FD0058C060 /* mesh.pb.swift in Sources */, @@ -546,6 +553,7 @@ DD8169F9271F1A6100F4AB02 /* MeshLogger.swift in Sources */, DD539502276DAA6A00AD86B1 /* MapLocation.swift in Sources */, DDAF8C6726ED0C8C0058C060 /* remote_hardware.pb.swift in Sources */, + DD17E5DD277D49D400010EC2 /* apponly.pb.swift in Sources */, DDAF8C6526ED0A490058C060 /* channel.pb.swift in Sources */, DD47E3DD26F390A000029299 /* Messages.swift in Sources */, DDC2E15826CE248E0042C5E4 /* MeshtasticClientApp.swift in Sources */, @@ -719,13 +727,13 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.39; + MARKETING_VERSION = 1.42; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Debug; }; @@ -746,13 +754,13 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.39; + MARKETING_VERSION = 1.42; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Release; }; diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 4bdaab45..85a7c0a5 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -25,7 +25,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph @Published var peripherals = [Peripheral]() @Published var connectedPeripheral: Peripheral! - @Published var lastConnectedPeripheral: String + //@Published var lastConnectedPeripheral: String @Published var lastConnectionError: String @Published var isSwitchedOn: Bool = false @@ -54,7 +54,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph override init() { self.meshLoggingEnabled = true // UserDefaults.standard.object(forKey: "meshActivityLog") as? Bool ?? true - self.lastConnectedPeripheral = "" + //self.lastConnectedPeripheral = "" self.lastConnectionError = "" super.init() // let bleQueue: DispatchQueue = DispatchQueue(label: "CentralManager") @@ -221,7 +221,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if meshLoggingEnabled { MeshLogger.log("💥 Fetch NodeInfo Failed") } } - lastConnectedPeripheral = peripheral.identifier.uuidString + //lastConnectedPeripheral = peripheral.identifier.uuidString // Discover Services peripheral.discoverServices([meshtasticServiceCBUUID]) @@ -365,10 +365,23 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph // TODO: Convert to CoreData // FIXME: Remove broken JSON file data layer implementation func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { - if let e = error { + + + if let e = error { + + print("🚫 didUpdateValueFor Characteristic error \(e)") - print("🚫 didUpdateValueFor Characteristic error \(e)") - if meshLoggingEnabled { MeshLogger.log("🚫 BLE didUpdateValueFor characteristic error by \(peripheral.name ?? "Unknown") \(e)") } + let errorCode = (e as NSError).code + + if errorCode == 5 { // CBATTErrorDomain Code=5 "Authentication is insufficient." + + // BLE Pin connection error + // We will try and re-connect to this device + lastConnectionError = "🚫 BLE \(e.localizedDescription) Please try connecting again and check the PIN carefully." + if meshLoggingEnabled { MeshLogger.log("🚫 BLE \(e.localizedDescription) Please try connecting again and check the PIN carefully.") } + self.centralManager?.cancelPeripheralConnection(peripheral) + + } } switch characteristic.uuid { @@ -825,16 +838,17 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let preferredPeripheral = peripherals.filter({ $0.peripheral.identifier.uuidString == UserDefaults.standard.object(forKey: "preferredPeripheralId") as? String ?? "" }).first if preferredPeripheral != nil && preferredPeripheral?.peripheral != nil { connectTo(peripheral: preferredPeripheral!.peripheral) - } else { - - // Try and connect to the last connected device - let lastConnectedPeripheral = peripherals.filter({ $0.peripheral.identifier.uuidString == self.lastConnectedPeripheral }).first - if lastConnectedPeripheral != nil && lastConnectedPeripheral?.peripheral != nil { - connectTo(peripheral: lastConnectedPeripheral!.peripheral) - } } - print("🚫 Message Send Failed, not properly connected to \(lastConnectedPeripheral)") - if meshLoggingEnabled { MeshLogger.log("🚫 Message Send Failed, not properly connected to \(lastConnectedPeripheral)") } +// else { +// +// // Try and connect to the last connected device +// let lastConnectedPeripheral = peripherals.filter({ $0.peripheral.identifier.uuidString == self.lastConnectedPeripheral }).first +// if lastConnectedPeripheral != nil && lastConnectedPeripheral?.peripheral != nil { +// connectTo(peripheral: lastConnectedPeripheral!.peripheral) +// } +// } + //print("🚫 Message Send Failed, not properly connected to \(lastConnectedPeripheral)") + //if meshLoggingEnabled { MeshLogger.log("🚫 Message Send Failed, not properly connected to \(lastConnectedPeripheral)") } success = false } else if message.count < 1 { @@ -861,7 +875,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } else if fetchedUsers.count >= 1 { let newMessage = MessageEntity(context: context!) - newMessage.messageId = Int64(UInt32.random(in: UInt32.min.. + + @@ -65,7 +67,7 @@ - + diff --git a/MeshtasticClient/Persistence/Persistence.swift b/MeshtasticClient/Persistence/Persistence.swift index 8c0c00f7..9ba9d0f8 100644 --- a/MeshtasticClient/Persistence/Persistence.swift +++ b/MeshtasticClient/Persistence/Persistence.swift @@ -38,6 +38,7 @@ class PersistenceController { container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") } container.loadPersistentStores(completionHandler: { (_, error) in + // Merge policy that favors in memory data over data in the db self.container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy self.container.viewContext.automaticallyMergesChangesFromParent = true @@ -65,9 +66,11 @@ class PersistenceController { let persistentStoreCoordinator = self.container.persistentStoreCoordinator do { + try persistentStoreCoordinator.destroyPersistentStore(at:url, ofType: NSSQLiteStoreType, options: nil) - print("💥 Something went terribly wrong, CoreData database truncated. All app data is lost.") try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil) + print("💥 Something went terribly wrong, CoreData database truncated. All app data is lost.") + } catch let error { print("💣 Failed to destroy broken CoreData database, delete the app. Attempted to clear persistent store: " + error.localizedDescription) } diff --git a/MeshtasticClient/Protobufs/admin.pb.swift b/MeshtasticClient/Protobufs/admin.pb.swift index 0985262d..fe280abf 100644 --- a/MeshtasticClient/Protobufs/admin.pb.swift +++ b/MeshtasticClient/Protobufs/admin.pb.swift @@ -15,7 +15,7 @@ import SwiftProtobuf // incompatible with the version of SwiftProtobuf to which you are linking. // Please ensure that you are building against the same version of the API // that was used to generate this file. -private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} typealias Version = _2 } @@ -29,10 +29,10 @@ struct AdminMessage { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. - var variant: AdminMessage.OneOf_Variant? + var variant: AdminMessage.OneOf_Variant? = nil /// - /// set the radio provisioning for this node + /// Set the radio provisioning for this node var setRadio: RadioConfig { get { if case .setRadio(let v)? = variant {return v} @@ -66,7 +66,7 @@ struct AdminMessage { } /// - /// Send the current RadioConfig in the response for this message. + /// Send the current RadioConfig in the response to this message. var getRadioRequest: Bool { get { if case .getRadioRequest(let v)? = variant {return v} @@ -84,7 +84,7 @@ struct AdminMessage { } /// - /// Send the specified channel in the response for this message + /// Send the specified channel in the response to this message /// NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present) var getChannelRequest: UInt32 { get { @@ -102,6 +102,24 @@ struct AdminMessage { set {variant = .getChannelResponse(newValue)} } + /// + /// Send the current owner data in the response to this message. + var getOwnerRequest: Bool { + get { + if case .getOwnerRequest(let v)? = variant {return v} + return false + } + set {variant = .getOwnerRequest(newValue)} + } + + var getOwnerResponse: User { + get { + if case .getOwnerResponse(let v)? = variant {return v} + return User() + } + set {variant = .getOwnerResponse(newValue)} + } + /// /// Setting channels/radio config remotely carries the risk that you might send an invalid config and the radio never talks to your mesh again. /// Therefore if setting either of these properties remotely, you must send a confirm_xxx message within 10 minutes. @@ -148,7 +166,7 @@ struct AdminMessage { enum OneOf_Variant: Equatable { /// - /// set the radio provisioning for this node + /// Set the radio provisioning for this node case setRadio(RadioConfig) /// /// Set the owner for this node @@ -161,15 +179,19 @@ struct AdminMessage { /// If the client sets a particular channel to be primary, the previous channel will be set to SECONDARY automatically. case setChannel(Channel) /// - /// Send the current RadioConfig in the response for this message. + /// Send the current RadioConfig in the response to this message. case getRadioRequest(Bool) case getRadioResponse(RadioConfig) /// - /// Send the specified channel in the response for this message + /// Send the specified channel in the response to this message /// NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present) case getChannelRequest(UInt32) case getChannelResponse(Channel) /// + /// Send the current owner data in the response to this message. + case getOwnerRequest(Bool) + case getOwnerResponse(User) + /// /// Setting channels/radio config remotely carries the risk that you might send an invalid config and the radio never talks to your mesh again. /// Therefore if setting either of these properties remotely, you must send a confirm_xxx message within 10 minutes. /// If you fail to do so, the radio will assume loss of comms and revert your changes. @@ -218,6 +240,14 @@ struct AdminMessage { guard case .getChannelResponse(let l) = lhs, case .getChannelResponse(let r) = rhs else { preconditionFailure() } return l == r }() + case (.getOwnerRequest, .getOwnerRequest): return { + guard case .getOwnerRequest(let l) = lhs, case .getOwnerRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getOwnerResponse, .getOwnerResponse): return { + guard case .getOwnerResponse(let l) = lhs, case .getOwnerResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() case (.confirmSetChannel, .confirmSetChannel): return { guard case .confirmSetChannel(let l) = lhs, case .confirmSetChannel(let r) = rhs else { preconditionFailure() } return l == r @@ -255,10 +285,12 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat 5: .standard(proto: "get_radio_response"), 6: .standard(proto: "get_channel_request"), 7: .standard(proto: "get_channel_response"), + 8: .standard(proto: "get_owner_request"), + 9: .standard(proto: "get_owner_response"), 32: .standard(proto: "confirm_set_channel"), 33: .standard(proto: "confirm_set_radio"), 34: .standard(proto: "exit_simulator"), - 35: .standard(proto: "reboot_seconds") + 35: .standard(proto: "reboot_seconds"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -348,6 +380,27 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat self.variant = .getChannelResponse(v) } }() + case 8: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getOwnerRequest(v) + } + }() + case 9: try { + var v: User? + var hadOneofValue = false + if let current = self.variant { + hadOneofValue = true + if case .getOwnerResponse(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .getOwnerResponse(v) + } + }() case 32: try { var v: Bool? try decoder.decodeSingularBoolField(value: &v) @@ -387,9 +440,8 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat func traverse(visitor: inout V) throws { // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch self.variant { case .setRadio?: try { guard case .setRadio(let v)? = self.variant else { preconditionFailure() } @@ -419,6 +471,14 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat guard case .getChannelResponse(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 7) }() + case .getOwnerRequest?: try { + guard case .getOwnerRequest(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularBoolField(value: v, fieldNumber: 8) + }() + case .getOwnerResponse?: try { + guard case .getOwnerResponse(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 9) + }() case .confirmSetChannel?: try { guard case .confirmSetChannel(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularBoolField(value: v, fieldNumber: 32) diff --git a/MeshtasticClient/Protobufs/channel.pb.swift b/MeshtasticClient/Protobufs/channel.pb.swift index dff3f2a7..81b35faf 100644 --- a/MeshtasticClient/Protobufs/channel.pb.swift +++ b/MeshtasticClient/Protobufs/channel.pb.swift @@ -34,7 +34,7 @@ import SwiftProtobuf // incompatible with the version of SwiftProtobuf to which you are linking. // Please ensure that you are building against the same version of the API // that was used to generate this file. -private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} typealias Version = _2 } @@ -167,30 +167,40 @@ struct ChannelSettings { var unknownFields = SwiftProtobuf.UnknownStorage() /// - /// Standard predefined channel settings + /// Standard predefined channel settings /// Note: these mappings must match ModemConfigChoice in the device code. enum ModemConfig: SwiftProtobuf.Enum { typealias RawValue = Int /// /// < Bw = 125 kHz, Cr = 4/5, Sf(7) = 128chips/symbol, CRC - /// < on. Default medium range (5.469 kbps) + /// < on. ShortSlow | Short Range / Slow (5.469 kbps) case bw125Cr45Sf128 // = 0 /// /// < Bw = 500 kHz, Cr = 4/5, Sf(7) = 128chips/symbol, CRC - /// < on. Fast+short range (21.875 kbps) + /// < on. ShortFast | Short Range / Fast (21.875 kbps) case bw500Cr45Sf128 // = 1 /// /// < Bw = 31.25 kHz, Cr = 4/8, Sf(9) = 512chips/symbol, - /// < CRC on. Slow+long range (275 bps) + /// < CRC on. LongFast | Long Range / Fast (275 bps) case bw3125Cr48Sf512 // = 2 /// /// < Bw = 125 kHz, Cr = 4/8, Sf(12) = 4096chips/symbol, CRC - /// < on. Slow+long range (183 bps) + /// < on. LongSlow | Long Range / Slow (183 bps) case bw125Cr48Sf4096 // = 3 + + /// + /// < Bw = 250 kHz, Cr = 4/6, Sf(11) = 2048chips/symbol, CRC + /// < on. MediumSlow | Medium Range / Slow (895 bps) + case bw250Cr46Sf2048 // = 4 + + /// + /// < Bw = 250 kHz, Cr = 4/7, Sf(10) = 1024chips/symbol, CRC + /// < on. MediumFast | Medium Range / Fast (1400 bps) + case bw250Cr47Sf1024 // = 5 case UNRECOGNIZED(Int) init() { @@ -203,6 +213,8 @@ struct ChannelSettings { case 1: self = .bw500Cr45Sf128 case 2: self = .bw3125Cr48Sf512 case 3: self = .bw125Cr48Sf4096 + case 4: self = .bw250Cr46Sf2048 + case 5: self = .bw250Cr47Sf1024 default: self = .UNRECOGNIZED(rawValue) } } @@ -213,6 +225,8 @@ struct ChannelSettings { case .bw500Cr45Sf128: return 1 case .bw3125Cr48Sf512: return 2 case .bw125Cr48Sf4096: return 3 + case .bw250Cr46Sf2048: return 4 + case .bw250Cr47Sf1024: return 5 case .UNRECOGNIZED(let i): return i } } @@ -230,7 +244,9 @@ extension ChannelSettings.ModemConfig: CaseIterable { .bw125Cr45Sf128, .bw500Cr45Sf128, .bw3125Cr48Sf512, - .bw125Cr48Sf4096 + .bw125Cr48Sf4096, + .bw250Cr46Sf2048, + .bw250Cr47Sf1024, ] } @@ -245,8 +261,8 @@ struct Channel { /// /// The index of this channel in the channel table (from 0 to MAX_NUM_CHANNELS-1) - /// (Someday - not currently implemented) An index of -1 could be used to mean "set by name", - /// in which case the target node will find and set the channel by settings.name. + /// (Someday - not currently implemented) An index of -1 could be used to mean "set by name", + /// in which case the target node will find and set the channel by settings.name. var index: Int32 = 0 /// @@ -289,7 +305,7 @@ struct Channel { /// /// Secondary channels are only used for encryption/decryption/authentication purposes. - /// Their radio settings (freq etc) are ignored, only psk is used. + /// Their radio settings (freq etc) are ignored, only psk is used. case secondary // = 2 case UNRECOGNIZED(Int) @@ -319,7 +335,7 @@ struct Channel { init() {} - fileprivate var _settings: ChannelSettings? + fileprivate var _settings: ChannelSettings? = nil } #if swift(>=4.2) @@ -329,7 +345,7 @@ extension Channel.Role: CaseIterable { static var allCases: [Channel.Role] = [ .disabled, .primary, - .secondary + .secondary, ] } @@ -350,7 +366,7 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen 5: .same(proto: "name"), 10: .same(proto: "id"), 16: .standard(proto: "uplink_enabled"), - 17: .standard(proto: "downlink_enabled") + 17: .standard(proto: "downlink_enabled"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -434,7 +450,9 @@ extension ChannelSettings.ModemConfig: SwiftProtobuf._ProtoNameProviding { 0: .same(proto: "Bw125Cr45Sf128"), 1: .same(proto: "Bw500Cr45Sf128"), 2: .same(proto: "Bw31_25Cr48Sf512"), - 3: .same(proto: "Bw125Cr48Sf4096") + 3: .same(proto: "Bw125Cr48Sf4096"), + 4: .same(proto: "Bw250Cr46Sf2048"), + 5: .same(proto: "Bw250Cr47Sf1024"), ] } @@ -443,7 +461,7 @@ extension Channel: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .same(proto: "index"), 2: .same(proto: "settings"), - 3: .same(proto: "role") + 3: .same(proto: "role"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -461,16 +479,12 @@ extension Channel: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa } func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 if self.index != 0 { try visitor.visitSingularInt32Field(value: self.index, fieldNumber: 1) } - try { if let v = self._settings { + if let v = self._settings { try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() + } if self.role != .disabled { try visitor.visitSingularEnumField(value: self.role, fieldNumber: 3) } @@ -490,6 +504,6 @@ extension Channel.Role: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 0: .same(proto: "DISABLED"), 1: .same(proto: "PRIMARY"), - 2: .same(proto: "SECONDARY") + 2: .same(proto: "SECONDARY"), ] } diff --git a/MeshtasticClient/Protobufs/deviceonly.pb.swift b/MeshtasticClient/Protobufs/deviceonly.pb.swift index 77a21df1..b44ea5c8 100644 --- a/MeshtasticClient/Protobufs/deviceonly.pb.swift +++ b/MeshtasticClient/Protobufs/deviceonly.pb.swift @@ -15,7 +15,7 @@ import SwiftProtobuf // incompatible with the version of SwiftProtobuf to which you are linking. // Please ensure that you are building against the same version of the API // that was used to generate this file. -private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} typealias Version = _2 } @@ -56,7 +56,7 @@ struct LegacyRadioConfig { init() {} - fileprivate var _preferences: LegacyRadioConfig.LegacyPreferences? + fileprivate var _preferences: LegacyRadioConfig.LegacyPreferences? = nil } /// @@ -180,7 +180,7 @@ struct ChannelFile { extension LegacyRadioConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "LegacyRadioConfig" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "preferences") + 1: .same(proto: "preferences"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -196,13 +196,9 @@ extension LegacyRadioConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem } func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._preferences { + if let v = self._preferences { try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() + } try unknownFields.traverse(visitor: &visitor) } @@ -216,7 +212,7 @@ extension LegacyRadioConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem extension LegacyRadioConfig.LegacyPreferences: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = LegacyRadioConfig.protoMessageName + ".LegacyPreferences" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 15: .same(proto: "region") + 15: .same(proto: "region"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -256,17 +252,17 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati 8: .same(proto: "version"), 7: .standard(proto: "rx_text_message"), 9: .standard(proto: "no_save"), - 11: .standard(proto: "did_gps_reset") + 11: .standard(proto: "did_gps_reset"), ] fileprivate class _StorageClass { - var _legacyRadio: LegacyRadioConfig? - var _myNode: MyNodeInfo? - var _owner: User? + var _legacyRadio: LegacyRadioConfig? = nil + var _myNode: MyNodeInfo? = nil + var _owner: User? = nil var _nodeDb: [NodeInfo] = [] var _receiveQueue: [MeshPacket] = [] var _version: UInt32 = 0 - var _rxTextMessage: MeshPacket? + var _rxTextMessage: MeshPacket? = nil var _noSave: Bool = false var _didGpsReset: Bool = false @@ -319,28 +315,24 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati func traverse(visitor: inout V) throws { try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = _storage._legacyRadio { + if let v = _storage._legacyRadio { try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - try { if let v = _storage._myNode { + } + if let v = _storage._myNode { try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { if let v = _storage._owner { + } + if let v = _storage._owner { try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } }() + } if !_storage._nodeDb.isEmpty { try visitor.visitRepeatedMessageField(value: _storage._nodeDb, fieldNumber: 4) } if !_storage._receiveQueue.isEmpty { try visitor.visitRepeatedMessageField(value: _storage._receiveQueue, fieldNumber: 5) } - try { if let v = _storage._rxTextMessage { + if let v = _storage._rxTextMessage { try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - } }() + } if _storage._version != 0 { try visitor.visitSingularUInt32Field(value: _storage._version, fieldNumber: 8) } @@ -380,7 +372,7 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati extension ChannelFile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "ChannelFile" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "channels") + 1: .same(proto: "channels"), ] mutating func decodeMessage(decoder: inout D) throws { diff --git a/MeshtasticClient/Protobufs/environmental_measurement.pb.swift b/MeshtasticClient/Protobufs/environmental_measurement.pb.swift index 8fd5f131..73e7ef02 100644 --- a/MeshtasticClient/Protobufs/environmental_measurement.pb.swift +++ b/MeshtasticClient/Protobufs/environmental_measurement.pb.swift @@ -15,7 +15,7 @@ import SwiftProtobuf // incompatible with the version of SwiftProtobuf to which you are linking. // Please ensure that you are building against the same version of the API // that was used to generate this file. -private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} typealias Version = _2 } @@ -43,7 +43,7 @@ extension EnvironmentalMeasurement: SwiftProtobuf.Message, SwiftProtobuf._Messag static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .same(proto: "temperature"), 2: .standard(proto: "relative_humidity"), - 3: .standard(proto: "barometric_pressure") + 3: .standard(proto: "barometric_pressure"), ] mutating func decodeMessage(decoder: inout D) throws { diff --git a/MeshtasticClient/Protobufs/mesh.pb.swift b/MeshtasticClient/Protobufs/mesh.pb.swift index 2f09f5f1..512ab45a 100644 --- a/MeshtasticClient/Protobufs/mesh.pb.swift +++ b/MeshtasticClient/Protobufs/mesh.pb.swift @@ -34,7 +34,7 @@ import SwiftProtobuf // incompatible with the version of SwiftProtobuf to which you are linking. // Please ensure that you are building against the same version of the API // that was used to generate this file. -private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} typealias Version = _2 } @@ -52,7 +52,7 @@ enum HardwareModel: SwiftProtobuf.Enum { case tloraV211P6 // = 3 case tbeam // = 4 - /// The original heltec WiFi_Lora_32_V2, which had battery voltage sensing hooked to GPIO 13 (see HELTEC_V2 for the new version). + /// The original heltec WiFi_Lora_32_V2, which had battery voltage sensing hooked to GPIO 13 (see HELTEC_V2 for the new version). case heltecV20 // = 5 case tbeam0P7 // = 6 case tEcho // = 7 @@ -159,7 +159,7 @@ extension HardwareModel: CaseIterable { .nrf52Unknown, .portduino, .androidSim, - .diyV1 + .diyV1, ] } @@ -256,7 +256,7 @@ extension Team: CaseIterable { .teal, .green, .darkGreen, - .brown + .brown, ] } @@ -307,7 +307,7 @@ extension Constants: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. static var allCases: [Constants] = [ .unused, - .dataPayloadLen + .dataPayloadLen, ] } @@ -365,7 +365,7 @@ enum CriticalErrorCode: SwiftProtobuf.Enum { case sx1262Failure // = 10 /// A (likely software but possibly hardware) failure was detected while trying to send packets. If this occurs on your board, please - /// post in the forum so that we can ask you to collect some information to allow fixing this bug + ///post in the forum so that we can ask you to collect some information to allow fixing this bug case radioSpiBug // = 11 case UNRECOGNIZED(Int) @@ -427,7 +427,7 @@ extension CriticalErrorCode: CaseIterable { .transmitFailed, .brownout, .sx1262Failure, - .radioSpiBug + .radioSpiBug, ] } @@ -703,7 +703,7 @@ extension Position.LocSource: CaseIterable { .locsrcUnspecified, .locsrcManualEntry, .locsrcGpsInternal, - .locsrcGpsExternal + .locsrcGpsExternal, ] } @@ -714,7 +714,7 @@ extension Position.AltSource: CaseIterable { .altsrcManualEntry, .altsrcGpsInternal, .altsrcGpsExternal, - .altsrcBarometric + .altsrcBarometric, ] } @@ -779,7 +779,7 @@ struct User { var hwModel: HardwareModel = .unset /// - /// In some regions HAM radio operators have different bandwidth limitations than others. + /// In some regions Ham radio operators have different bandwidth limitations than others. /// If this user is a licensed operator, set this flag. /// Also, "long_name" should be their licence number. var isLicensed: Bool = false @@ -788,7 +788,7 @@ struct User { /// Participants in the same network can self-group into different teams. /// Short-term this can be used to visually differentiate them on the map; /// in the longer term it could also help users to semi-automatically - /// select or ignore messages according to team affiliation. + /// select or ignore messages according to team affiliation. /// In total, 14 teams are defined (encoded in 4 bits) var team: Team = .clear @@ -837,7 +837,7 @@ struct Routing { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. - var variant: Routing.OneOf_Variant? + var variant: Routing.OneOf_Variant? = nil /// /// A route request going from the requester @@ -860,8 +860,8 @@ struct Routing { } /// - /// A failure in delivering a message (usually used for routing control messages, but might be provided - /// in addition to ack.fail_id to provide details on the type of failure). + /// A failure in delivering a message (usually used for routing control messages, but might be provided + /// in addition to ack.fail_id to provide details on the type of failure). var errorReason: Routing.Error { get { if case .errorReason(let v)? = variant {return v} @@ -880,8 +880,8 @@ struct Routing { /// A route reply case routeReply(RouteDiscovery) /// - /// A failure in delivering a message (usually used for routing control messages, but might be provided - /// in addition to ack.fail_id to provide details on the type of failure). + /// A failure in delivering a message (usually used for routing control messages, but might be provided + /// in addition to ack.fail_id to provide details on the type of failure). case errorReason(Routing.Error) #if !swift(>=4.1) @@ -1016,7 +1016,7 @@ extension Routing.Error: CaseIterable { .tooLarge, .noResponse, .badRequest, - .notAuthorized + .notAuthorized, ] } @@ -1083,12 +1083,18 @@ struct MeshPacket { /// Note: Our crypto implementation uses this field as well. /// See [crypto](/developers/device/encryption.md) for details. /// FIXME - really should be fixed32 instead, this encoding only hurts the ble link though. - var from: UInt32 = 0 + var from: UInt32 { + get {return _storage._from} + set {_uniqueStorage()._from = newValue} + } /// /// The (immediatSee Priority description for more details.y should be fixed32 instead, this encoding only /// hurts the ble link though. - var to: UInt32 = 0 + var to: UInt32 { + get {return _storage._to} + set {_uniqueStorage()._to = newValue} + } /// /// (Usually) If set, this indicates the index in the secondary_channels table that this packet was sent/received on. @@ -1098,24 +1104,30 @@ struct MeshPacket { /// Very briefly, while sending and receiving deep inside the device Router code, this field instead /// contains the 'channel hash' instead of the index. /// This 'trick' is only used while the payloadVariant is an 'encrypted'. - var channel: UInt32 = 0 + var channel: UInt32 { + get {return _storage._channel} + set {_uniqueStorage()._channel = newValue} + } - var payloadVariant: MeshPacket.OneOf_PayloadVariant? + var payloadVariant: OneOf_PayloadVariant? { + get {return _storage._payloadVariant} + set {_uniqueStorage()._payloadVariant = newValue} + } var decoded: DataMessage { get { - if case .decoded(let v)? = payloadVariant {return v} + if case .decoded(let v)? = _storage._payloadVariant {return v} return DataMessage() } - set {payloadVariant = .decoded(newValue)} + set {_uniqueStorage()._payloadVariant = .decoded(newValue)} } var encrypted: Data { get { - if case .encrypted(let v)? = payloadVariant {return v} + if case .encrypted(let v)? = _storage._payloadVariant {return v} return Data() } - set {payloadVariant = .encrypted(newValue)} + set {_uniqueStorage()._payloadVariant = .encrypted(newValue)} } /// @@ -1129,27 +1141,39 @@ struct MeshPacket { /// See [crypto](/developers/device/encryption.md) for details. /// FIXME - really should be fixed32 instead, this encoding only /// hurts the ble link though. - var id: UInt32 = 0 + var id: UInt32 { + get {return _storage._id} + set {_uniqueStorage()._id = newValue} + } /// /// The time this message was received by the esp32 (secs since 1970). /// Note: this field is _never_ sent on the radio link itself (to save space) Times /// are typically not sent over the mesh, but they will be added to any Packet /// (chain of SubPacket) sent to the phone (so the phone can know exact time of reception) - var rxTime: UInt32 = 0 + var rxTime: UInt32 { + get {return _storage._rxTime} + set {_uniqueStorage()._rxTime = newValue} + } /// /// *Never* sent over the radio links. /// Set during reception to indicate the SNR of this packet. /// Used to collect statistics on current link quality. - var rxSnr: Float = 0 + var rxSnr: Float { + get {return _storage._rxSnr} + set {_uniqueStorage()._rxSnr = newValue} + } /// /// If unset treated as zero (no forwarding, send to adjacent nodes only) /// if 1, allow hopping through one node, etc... /// For our usecase real world topologies probably have a max of about 3. /// This field is normally placed into a few of bits in the header. - var hopLimit: UInt32 = 0 + var hopLimit: UInt32 { + get {return _storage._hopLimit} + set {_uniqueStorage()._hopLimit = newValue} + } /// /// This packet is being sent as a reliable message, we would prefer it to arrive at the destination. @@ -1161,16 +1185,47 @@ struct MeshPacket { /// So FloodingRouter.cpp generates an implicit ack which is delivered to the original sender. /// If after some time we don't hear anyone rebroadcast our packet, we will timeout and retransmit, using the regular resend logic. /// Note: This flag is normally sent in a flag bit in the header when sent over the wire - var wantAck: Bool = false + var wantAck: Bool { + get {return _storage._wantAck} + set {_uniqueStorage()._wantAck = newValue} + } /// - /// The priority of this message for sending. + /// The priority of this message for sending. /// See MeshPacket.Priority description for more details. - var priority: MeshPacket.Priority = .unset + var priority: MeshPacket.Priority { + get {return _storage._priority} + set {_uniqueStorage()._priority = newValue} + } /// /// rssi of received packet. Only sent to phone for dispay purposes. - var rxRssi: Int32 = 0 + var rxRssi: Int32 { + get {return _storage._rxRssi} + set {_uniqueStorage()._rxRssi = newValue} + } + + /// + /// Describe if this message is delayed + var delayed: MeshPacket.Delayed { + get {return _storage._delayed} + set {_uniqueStorage()._delayed = newValue} + } + + /// + /// If set, this message is intened to be a reply to a previously sent message with the defined id. + var replyID: UInt32 { + get {return _storage._replyID} + set {_uniqueStorage()._replyID = newValue} + } + + /// + /// Defaults to false. If true, then what is in the payload should be treated as an emoji like giving + /// a message a heart or poop emoji. + var isTapback: Bool { + get {return _storage._isTapback} + set {_uniqueStorage()._isTapback = newValue} + } var unknownFields = SwiftProtobuf.UnknownStorage() @@ -1282,7 +1337,51 @@ struct MeshPacket { } + /// + /// Identify if this is a delayed packet + enum Delayed: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// If unset, the message is being sent in real time. + case noDelay // = 0 + + /// + /// The message is delayed and was originally a broadcast + case broadcast // = 1 + + /// + /// The message is delayed and was originally a direct message + case direct // = 2 + case UNRECOGNIZED(Int) + + init() { + self = .noDelay + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .noDelay + case 1: self = .broadcast + case 2: self = .direct + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .noDelay: return 0 + case .broadcast: return 1 + case .direct: return 2 + case .UNRECOGNIZED(let i): return i + } + } + + } + init() {} + + fileprivate var _storage = _StorageClass.defaultInstance } #if swift(>=4.2) @@ -1296,7 +1395,16 @@ extension MeshPacket.Priority: CaseIterable { .default, .reliable, .ack, - .max + .max, + ] +} + +extension MeshPacket.Delayed: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [MeshPacket.Delayed] = [ + .noDelay, + .broadcast, + .direct, ] } @@ -1330,7 +1438,7 @@ struct NodeInfo { // methods supported on all messages. /// - /// the node number + /// The node number var num: UInt32 = 0 /// @@ -1369,8 +1477,8 @@ struct NodeInfo { init() {} - fileprivate var _user: User? - fileprivate var _position: Position? + fileprivate var _user: User? = nil + fileprivate var _position: Position? = nil } /// @@ -1385,22 +1493,34 @@ struct MyNodeInfo { /// /// Tells the phone what our node number is, default starting value is /// lowbyte of macaddr, but it will be fixed if that is already in use - var myNodeNum: UInt32 = 0 + var myNodeNum: UInt32 { + get {return _storage._myNodeNum} + set {_uniqueStorage()._myNodeNum = newValue} + } /// /// Note: This flag merely means we detected a hardware GPS in our node. /// Not the same as UserPreferences.location_sharing - var hasGps_p: Bool = false + var hasGps_p: Bool { + get {return _storage._hasGps_p} + set {_uniqueStorage()._hasGps_p = newValue} + } /// /// # of frequencies that can be used (set at build time in the device flash image). /// Note: this is different from max_channels, this field is telling the # of frequency bands this node can use. /// (old name was num_channels) - var numBands: UInt32 = 0 + var numBands: UInt32 { + get {return _storage._numBands} + set {_uniqueStorage()._numBands = newValue} + } /// - /// The maximum number of 'software' channels that can be set on this node. - var maxChannels: UInt32 = 0 + /// The maximum number of 'software' channels that can be set on this node. + var maxChannels: UInt32 { + get {return _storage._maxChannels} + set {_uniqueStorage()._maxChannels = newValue} + } /// /// Deprecated! ONLY USED IN DEVICE CODE (for upgrading old 1.0 firmwares) DO NOT READ ELSEWHERE. @@ -1410,18 +1530,27 @@ struct MyNodeInfo { /// But for newer builds this string will be unpopulated (missing/null). /// For those builds you should instead look at the new read/write region enum in UserSettings /// The format of this string was 1.0-US or 1.0-CN etc.. Or empty string if unset. - var region: String = String() + var region: String { + get {return _storage._region} + set {_uniqueStorage()._region = newValue} + } /// /// TBEAM, HELTEC, etc... /// Starting in 1.2.11 moved to hw_model enum in the NodeInfo object. /// Apps will still need the string here for older builds /// (so OTA update can find the right image), but if the enum is available it will be used instead. - var hwModelDeprecated: String = String() + var hwModelDeprecated: String { + get {return _storage._hwModelDeprecated} + set {_uniqueStorage()._hwModelDeprecated = newValue} + } /// /// 0.0.5 etc... - var firmwareVersion: String = String() + var firmwareVersion: String { + get {return _storage._firmwareVersion} + set {_uniqueStorage()._firmwareVersion = newValue} + } /// /// An error message we'd like to report back to the mothership through analytics. @@ -1430,43 +1559,98 @@ struct MyNodeInfo { /// This field will be cleared after the phone reads MyNodeInfo /// (i.e. it will only be reported once) /// a numeric error code to go with error message, zero means no error - var errorCode: CriticalErrorCode = .none + var errorCode: CriticalErrorCode { + get {return _storage._errorCode} + set {_uniqueStorage()._errorCode = newValue} + } /// /// A numeric error address (nonzero if available) - var errorAddress: UInt32 = 0 + var errorAddress: UInt32 { + get {return _storage._errorAddress} + set {_uniqueStorage()._errorAddress = newValue} + } /// /// The total number of errors this node has ever encountered /// (well - since the last time we discarded preferences) - var errorCount: UInt32 = 0 + var errorCount: UInt32 { + get {return _storage._errorCount} + set {_uniqueStorage()._errorCount = newValue} + } /// /// The total number of reboots this node has ever encountered /// (well - since the last time we discarded preferences) - var rebootCount: UInt32 = 0 + var rebootCount: UInt32 { + get {return _storage._rebootCount} + set {_uniqueStorage()._rebootCount = newValue} + } + + /// + /// Calculated bitrate of the current channel (in Bytes Per Second) + var bitrate: Float { + get {return _storage._bitrate} + set {_uniqueStorage()._bitrate = newValue} + } /// /// How long before we consider a message abandoned and we can clear our /// caches of any messages in flight Normally quite large to handle the worst case /// message delivery time, 5 minutes. /// Formerly called FLOOD_EXPIRE_TIME in the device code - var messageTimeoutMsec: UInt32 = 0 + var messageTimeoutMsec: UInt32 { + get {return _storage._messageTimeoutMsec} + set {_uniqueStorage()._messageTimeoutMsec = newValue} + } /// /// The minimum app version that can talk to this device. /// Phone/PC apps should compare this to their build number and if too low tell the user they must update their app - var minAppVersion: UInt32 = 0 + var minAppVersion: UInt32 { + get {return _storage._minAppVersion} + set {_uniqueStorage()._minAppVersion = newValue} + } + + /// + /// 48 time windows of 1hr each with the airtime transmitted out of the device per hour. + var airPeriodTx: [UInt32] { + get {return _storage._airPeriodTx} + set {_uniqueStorage()._airPeriodTx = newValue} + } + + /// + /// 48 time windows of 1hr each with the airtime of valid packets for your mesh. + var airPeriodRx: [UInt32] { + get {return _storage._airPeriodRx} + set {_uniqueStorage()._airPeriodRx = newValue} + } + + /// + /// Is the device wifi capable? + var hasWifi_p: Bool { + get {return _storage._hasWifi_p} + set {_uniqueStorage()._hasWifi_p = newValue} + } + + /// + /// Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). + var channelUtilization: Float { + get {return _storage._channelUtilization} + set {_uniqueStorage()._channelUtilization = newValue} + } var unknownFields = SwiftProtobuf.UnknownStorage() init() {} + + fileprivate var _storage = _StorageClass.defaultInstance } /// /// Debug output from the device. /// -/// To minimize the size of records inside the device code, if a time/source/level is not set +/// To minimize the size of records inside the device code, if a time/source/level is not set /// on the message it is assumed to be a continuation of the previously sent message. /// This allows the device code to use fixed maxlen 64 byte strings for messages, /// and then extend as needed by emitting multiple records. @@ -1550,7 +1734,7 @@ extension LogRecord.Level: CaseIterable { .warning, .info, .debug, - .trace + .trace, ] } @@ -1569,22 +1753,16 @@ struct FromRadio { /// /// The packet num, used to allow the phone to request missing read packets from the FIFO, /// see our bluetooth docs - var num: UInt32 { - get {return _storage._num} - set {_uniqueStorage()._num = newValue} - } + var num: UInt32 = 0 - var payloadVariant: OneOf_PayloadVariant? { - get {return _storage._payloadVariant} - set {_uniqueStorage()._payloadVariant = newValue} - } + var payloadVariant: FromRadio.OneOf_PayloadVariant? = nil var packet: MeshPacket { get { - if case .packet(let v)? = _storage._payloadVariant {return v} + if case .packet(let v)? = payloadVariant {return v} return MeshPacket() } - set {_uniqueStorage()._payloadVariant = .packet(newValue)} + set {payloadVariant = .packet(newValue)} } /// @@ -1592,57 +1770,57 @@ struct FromRadio { /// NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. var myInfo: MyNodeInfo { get { - if case .myInfo(let v)? = _storage._payloadVariant {return v} + if case .myInfo(let v)? = payloadVariant {return v} return MyNodeInfo() } - set {_uniqueStorage()._payloadVariant = .myInfo(newValue)} + set {payloadVariant = .myInfo(newValue)} } /// /// One packet is sent for each node in the on radio DB - /// starts over with the first node in our DB + /// starts over with the first node in our DB var nodeInfo: NodeInfo { get { - if case .nodeInfo(let v)? = _storage._payloadVariant {return v} + if case .nodeInfo(let v)? = payloadVariant {return v} return NodeInfo() } - set {_uniqueStorage()._payloadVariant = .nodeInfo(newValue)} + set {payloadVariant = .nodeInfo(newValue)} } /// - /// set to send debug console output over our protobuf stream + /// Set to send debug console output over our protobuf stream var logRecord: LogRecord { get { - if case .logRecord(let v)? = _storage._payloadVariant {return v} + if case .logRecord(let v)? = payloadVariant {return v} return LogRecord() } - set {_uniqueStorage()._payloadVariant = .logRecord(newValue)} + set {payloadVariant = .logRecord(newValue)} } /// - /// sent as true once the device has finished sending all of the responses to want_config + /// Sent as true once the device has finished sending all of the responses to want_config /// recipient should check if this ID matches our original request nonce, if /// not, it means your config responses haven't started yet. /// NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. var configCompleteID: UInt32 { get { - if case .configCompleteID(let v)? = _storage._payloadVariant {return v} + if case .configCompleteID(let v)? = payloadVariant {return v} return 0 } - set {_uniqueStorage()._payloadVariant = .configCompleteID(newValue)} + set {payloadVariant = .configCompleteID(newValue)} } /// /// Sent to tell clients the radio has just rebooted. /// Set to true if present. /// Not used on all transports, currently just used for the serial console. - /// NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. + /// NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. var rebooted: Bool { get { - if case .rebooted(let v)? = _storage._payloadVariant {return v} + if case .rebooted(let v)? = payloadVariant {return v} return false } - set {_uniqueStorage()._payloadVariant = .rebooted(newValue)} + set {payloadVariant = .rebooted(newValue)} } var unknownFields = SwiftProtobuf.UnknownStorage() @@ -1655,13 +1833,13 @@ struct FromRadio { case myInfo(MyNodeInfo) /// /// One packet is sent for each node in the on radio DB - /// starts over with the first node in our DB + /// starts over with the first node in our DB case nodeInfo(NodeInfo) /// - /// set to send debug console output over our protobuf stream + /// Set to send debug console output over our protobuf stream case logRecord(LogRecord) /// - /// sent as true once the device has finished sending all of the responses to want_config + /// Sent as true once the device has finished sending all of the responses to want_config /// recipient should check if this ID matches our original request nonce, if /// not, it means your config responses haven't started yet. /// NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. @@ -1670,7 +1848,7 @@ struct FromRadio { /// Sent to tell clients the radio has just rebooted. /// Set to true if present. /// Not used on all transports, currently just used for the serial console. - /// NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. + /// NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. case rebooted(Bool) #if !swift(>=4.1) @@ -1710,22 +1888,20 @@ struct FromRadio { } init() {} - - fileprivate var _storage = _StorageClass.defaultInstance } /// -/// packets/commands to the radio will be written (reliably) to the toRadio characteristic. +/// Packets/commands to the radio will be written (reliably) to the toRadio characteristic. /// Once the write completes the phone can assume it is handled. struct ToRadio { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. - var payloadVariant: ToRadio.OneOf_PayloadVariant? + var payloadVariant: ToRadio.OneOf_PayloadVariant? = nil /// - /// send this packet on the mesh + /// Send this packet on the mesh var packet: MeshPacket { get { if case .packet(let v)? = payloadVariant {return v} @@ -1746,7 +1922,7 @@ struct ToRadio { } /// - /// phone wants radio to send full node db to the phone, This is + /// Phone wants radio to send full node db to the phone, This is /// typically the first packet sent to the radio when the phone gets a /// bluetooth connection. The radio will respond by sending back a /// MyNodeInfo, a owner, a radio config and a series of @@ -1778,14 +1954,14 @@ struct ToRadio { enum OneOf_PayloadVariant: Equatable { /// - /// send this packet on the mesh + /// Send this packet on the mesh case packet(MeshPacket) /// /// Information about the peer, sent after the phone sneds want_config_id. /// Old clients do not send this, which is fine. case peerInfo(ToRadio.PeerInfo) /// - /// phone wants radio to send full node db to the phone, This is + /// Phone wants radio to send full node db to the phone, This is /// typically the first packet sent to the radio when the phone gets a /// bluetooth connection. The radio will respond by sending back a /// MyNodeInfo, a owner, a radio config and a series of @@ -1836,7 +2012,7 @@ struct ToRadio { // methods supported on all messages. /// - /// The numeric version code for the client application, which in some cases are used to control device behavior (so the device can + /// The numeric version code for the client application, which in some cases are used to control device behavior (so the device can /// make assumptions about who is using the API. var appVersion: UInt32 = 0 @@ -1877,7 +2053,7 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { 36: .same(proto: "NRF52_UNKNOWN"), 37: .same(proto: "PORTDUINO"), 38: .same(proto: "ANDROID_SIM"), - 39: .same(proto: "DIY_V1") + 39: .same(proto: "DIY_V1"), ] } @@ -1897,14 +2073,14 @@ extension Team: SwiftProtobuf._ProtoNameProviding { 11: .same(proto: "TEAL"), 12: .same(proto: "GREEN"), 13: .same(proto: "DARK_GREEN"), - 14: .same(proto: "BROWN") + 14: .same(proto: "BROWN"), ] } extension Constants: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 0: .same(proto: "Unused"), - 237: .same(proto: "DATA_PAYLOAD_LEN") + 237: .same(proto: "DATA_PAYLOAD_LEN"), ] } @@ -1921,7 +2097,7 @@ extension CriticalErrorCode: SwiftProtobuf._ProtoNameProviding { 8: .same(proto: "TransmitFailed"), 9: .same(proto: "Brownout"), 10: .same(proto: "SX1262Failure"), - 11: .same(proto: "RadioSpiBug") + 11: .same(proto: "RadioSpiBug"), ] } @@ -1950,7 +2126,7 @@ extension Position: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB 24: .standard(proto: "sats_in_view"), 25: .standard(proto: "sensor_id"), 40: .standard(proto: "pos_next_update"), - 41: .standard(proto: "pos_seq_number") + 41: .standard(proto: "pos_seq_number"), ] fileprivate class _StorageClass { @@ -2170,7 +2346,7 @@ extension Position.LocSource: SwiftProtobuf._ProtoNameProviding { 0: .same(proto: "LOCSRC_UNSPECIFIED"), 1: .same(proto: "LOCSRC_MANUAL_ENTRY"), 2: .same(proto: "LOCSRC_GPS_INTERNAL"), - 3: .same(proto: "LOCSRC_GPS_EXTERNAL") + 3: .same(proto: "LOCSRC_GPS_EXTERNAL"), ] } @@ -2180,7 +2356,7 @@ extension Position.AltSource: SwiftProtobuf._ProtoNameProviding { 1: .same(proto: "ALTSRC_MANUAL_ENTRY"), 2: .same(proto: "ALTSRC_GPS_INTERNAL"), 3: .same(proto: "ALTSRC_GPS_EXTERNAL"), - 4: .same(proto: "ALTSRC_BAROMETRIC") + 4: .same(proto: "ALTSRC_BAROMETRIC"), ] } @@ -2196,7 +2372,7 @@ extension User: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, 8: .same(proto: "team"), 10: .standard(proto: "tx_power_dbm"), 11: .standard(proto: "ant_gain_dbi"), - 12: .standard(proto: "ant_azimuth") + 12: .standard(proto: "ant_azimuth"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2273,7 +2449,7 @@ extension User: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, extension RouteDiscovery: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "RouteDiscovery" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 2: .same(proto: "route") + 2: .same(proto: "route"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2307,7 +2483,7 @@ extension Routing: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .standard(proto: "route_request"), 2: .standard(proto: "route_reply"), - 3: .standard(proto: "error_reason") + 3: .standard(proto: "error_reason"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2357,9 +2533,8 @@ extension Routing: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa func traverse(visitor: inout V) throws { // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch self.variant { case .routeRequest?: try { guard case .routeRequest(let v)? = self.variant else { preconditionFailure() } @@ -2397,7 +2572,7 @@ extension Routing.Error: SwiftProtobuf._ProtoNameProviding { 7: .same(proto: "TOO_LARGE"), 8: .same(proto: "NO_RESPONSE"), 32: .same(proto: "BAD_REQUEST"), - 33: .same(proto: "NOT_AUTHORIZED") + 33: .same(proto: "NOT_AUTHORIZED"), ] } @@ -2409,7 +2584,7 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati 3: .standard(proto: "want_response"), 4: .same(proto: "dest"), 5: .same(proto: "source"), - 6: .standard(proto: "request_id") + 6: .standard(proto: "request_id"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2477,112 +2652,187 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 10: .standard(proto: "hop_limit"), 11: .standard(proto: "want_ack"), 12: .same(proto: "priority"), - 13: .standard(proto: "rx_rssi") + 13: .standard(proto: "rx_rssi"), + 15: .same(proto: "delayed"), + 16: .standard(proto: "reply_id"), + 17: .standard(proto: "is_tapback"), ] + fileprivate class _StorageClass { + var _from: UInt32 = 0 + var _to: UInt32 = 0 + var _channel: UInt32 = 0 + var _payloadVariant: MeshPacket.OneOf_PayloadVariant? + var _id: UInt32 = 0 + var _rxTime: UInt32 = 0 + var _rxSnr: Float = 0 + var _hopLimit: UInt32 = 0 + var _wantAck: Bool = false + var _priority: MeshPacket.Priority = .unset + var _rxRssi: Int32 = 0 + var _delayed: MeshPacket.Delayed = .noDelay + var _replyID: UInt32 = 0 + var _isTapback: Bool = false + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _from = source._from + _to = source._to + _channel = source._channel + _payloadVariant = source._payloadVariant + _id = source._id + _rxTime = source._rxTime + _rxSnr = source._rxSnr + _hopLimit = source._hopLimit + _wantAck = source._wantAck + _priority = source._priority + _rxRssi = source._rxRssi + _delayed = source._delayed + _replyID = source._replyID + _isTapback = source._isTapback + } + } + + fileprivate mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularFixed32Field(value: &self.from) }() - case 2: try { try decoder.decodeSingularFixed32Field(value: &self.to) }() - case 3: try { try decoder.decodeSingularUInt32Field(value: &self.channel) }() - case 4: try { - var v: DataMessage? - var hadOneofValue = false - if let current = self.payloadVariant { - hadOneofValue = true - if case .decoded(let m) = current {v = m} + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularFixed32Field(value: &_storage._from) }() + case 2: try { try decoder.decodeSingularFixed32Field(value: &_storage._to) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &_storage._channel) }() + case 4: try { + var v: DataMessage? + var hadOneofValue = false + if let current = _storage._payloadVariant { + hadOneofValue = true + if case .decoded(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._payloadVariant = .decoded(v) + } + }() + case 5: try { + var v: Data? + try decoder.decodeSingularBytesField(value: &v) + if let v = v { + if _storage._payloadVariant != nil {try decoder.handleConflictingOneOf()} + _storage._payloadVariant = .encrypted(v) + } + }() + case 6: try { try decoder.decodeSingularFixed32Field(value: &_storage._id) }() + case 7: try { try decoder.decodeSingularFixed32Field(value: &_storage._rxTime) }() + case 8: try { try decoder.decodeSingularFloatField(value: &_storage._rxSnr) }() + case 10: try { try decoder.decodeSingularUInt32Field(value: &_storage._hopLimit) }() + case 11: try { try decoder.decodeSingularBoolField(value: &_storage._wantAck) }() + case 12: try { try decoder.decodeSingularEnumField(value: &_storage._priority) }() + case 13: try { try decoder.decodeSingularInt32Field(value: &_storage._rxRssi) }() + case 15: try { try decoder.decodeSingularEnumField(value: &_storage._delayed) }() + case 16: try { try decoder.decodeSingularFixed32Field(value: &_storage._replyID) }() + case 17: try { try decoder.decodeSingularBoolField(value: &_storage._isTapback) }() + default: break } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .decoded(v) - } - }() - case 5: try { - var v: Data? - try decoder.decodeSingularBytesField(value: &v) - if let v = v { - if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} - self.payloadVariant = .encrypted(v) - } - }() - case 6: try { try decoder.decodeSingularFixed32Field(value: &self.id) }() - case 7: try { try decoder.decodeSingularFixed32Field(value: &self.rxTime) }() - case 8: try { try decoder.decodeSingularFloatField(value: &self.rxSnr) }() - case 10: try { try decoder.decodeSingularUInt32Field(value: &self.hopLimit) }() - case 11: try { try decoder.decodeSingularBoolField(value: &self.wantAck) }() - case 12: try { try decoder.decodeSingularEnumField(value: &self.priority) }() - case 13: try { try decoder.decodeSingularInt32Field(value: &self.rxRssi) }() - default: break } } } func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if self.from != 0 { - try visitor.visitSingularFixed32Field(value: self.from, fieldNumber: 1) - } - if self.to != 0 { - try visitor.visitSingularFixed32Field(value: self.to, fieldNumber: 2) - } - if self.channel != 0 { - try visitor.visitSingularUInt32Field(value: self.channel, fieldNumber: 3) - } - switch self.payloadVariant { - case .decoded?: try { - guard case .decoded(let v)? = self.payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - }() - case .encrypted?: try { - guard case .encrypted(let v)? = self.payloadVariant else { preconditionFailure() } - try visitor.visitSingularBytesField(value: v, fieldNumber: 5) - }() - case nil: break - } - if self.id != 0 { - try visitor.visitSingularFixed32Field(value: self.id, fieldNumber: 6) - } - if self.rxTime != 0 { - try visitor.visitSingularFixed32Field(value: self.rxTime, fieldNumber: 7) - } - if self.rxSnr != 0 { - try visitor.visitSingularFloatField(value: self.rxSnr, fieldNumber: 8) - } - if self.hopLimit != 0 { - try visitor.visitSingularUInt32Field(value: self.hopLimit, fieldNumber: 10) - } - if self.wantAck != false { - try visitor.visitSingularBoolField(value: self.wantAck, fieldNumber: 11) - } - if self.priority != .unset { - try visitor.visitSingularEnumField(value: self.priority, fieldNumber: 12) - } - if self.rxRssi != 0 { - try visitor.visitSingularInt32Field(value: self.rxRssi, fieldNumber: 13) + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + if _storage._from != 0 { + try visitor.visitSingularFixed32Field(value: _storage._from, fieldNumber: 1) + } + if _storage._to != 0 { + try visitor.visitSingularFixed32Field(value: _storage._to, fieldNumber: 2) + } + if _storage._channel != 0 { + try visitor.visitSingularUInt32Field(value: _storage._channel, fieldNumber: 3) + } + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch _storage._payloadVariant { + case .decoded?: try { + guard case .decoded(let v)? = _storage._payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + }() + case .encrypted?: try { + guard case .encrypted(let v)? = _storage._payloadVariant else { preconditionFailure() } + try visitor.visitSingularBytesField(value: v, fieldNumber: 5) + }() + case nil: break + } + if _storage._id != 0 { + try visitor.visitSingularFixed32Field(value: _storage._id, fieldNumber: 6) + } + if _storage._rxTime != 0 { + try visitor.visitSingularFixed32Field(value: _storage._rxTime, fieldNumber: 7) + } + if _storage._rxSnr != 0 { + try visitor.visitSingularFloatField(value: _storage._rxSnr, fieldNumber: 8) + } + if _storage._hopLimit != 0 { + try visitor.visitSingularUInt32Field(value: _storage._hopLimit, fieldNumber: 10) + } + if _storage._wantAck != false { + try visitor.visitSingularBoolField(value: _storage._wantAck, fieldNumber: 11) + } + if _storage._priority != .unset { + try visitor.visitSingularEnumField(value: _storage._priority, fieldNumber: 12) + } + if _storage._rxRssi != 0 { + try visitor.visitSingularInt32Field(value: _storage._rxRssi, fieldNumber: 13) + } + if _storage._delayed != .noDelay { + try visitor.visitSingularEnumField(value: _storage._delayed, fieldNumber: 15) + } + if _storage._replyID != 0 { + try visitor.visitSingularFixed32Field(value: _storage._replyID, fieldNumber: 16) + } + if _storage._isTapback != false { + try visitor.visitSingularBoolField(value: _storage._isTapback, fieldNumber: 17) + } } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: MeshPacket, rhs: MeshPacket) -> Bool { - if lhs.from != rhs.from {return false} - if lhs.to != rhs.to {return false} - if lhs.channel != rhs.channel {return false} - if lhs.payloadVariant != rhs.payloadVariant {return false} - if lhs.id != rhs.id {return false} - if lhs.rxTime != rhs.rxTime {return false} - if lhs.rxSnr != rhs.rxSnr {return false} - if lhs.hopLimit != rhs.hopLimit {return false} - if lhs.wantAck != rhs.wantAck {return false} - if lhs.priority != rhs.priority {return false} - if lhs.rxRssi != rhs.rxRssi {return false} + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in + let _storage = _args.0 + let rhs_storage = _args.1 + if _storage._from != rhs_storage._from {return false} + if _storage._to != rhs_storage._to {return false} + if _storage._channel != rhs_storage._channel {return false} + if _storage._payloadVariant != rhs_storage._payloadVariant {return false} + if _storage._id != rhs_storage._id {return false} + if _storage._rxTime != rhs_storage._rxTime {return false} + if _storage._rxSnr != rhs_storage._rxSnr {return false} + if _storage._hopLimit != rhs_storage._hopLimit {return false} + if _storage._wantAck != rhs_storage._wantAck {return false} + if _storage._priority != rhs_storage._priority {return false} + if _storage._rxRssi != rhs_storage._rxRssi {return false} + if _storage._delayed != rhs_storage._delayed {return false} + if _storage._replyID != rhs_storage._replyID {return false} + if _storage._isTapback != rhs_storage._isTapback {return false} + return true + } + if !storagesAreEqual {return false} + } if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -2596,7 +2846,15 @@ extension MeshPacket.Priority: SwiftProtobuf._ProtoNameProviding { 64: .same(proto: "DEFAULT"), 70: .same(proto: "RELIABLE"), 120: .same(proto: "ACK"), - 127: .same(proto: "MAX") + 127: .same(proto: "MAX"), + ] +} + +extension MeshPacket.Delayed: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "NO_DELAY"), + 1: .same(proto: "DELAYED_BROADCAST"), + 2: .same(proto: "DELAYED_DIRECT"), ] } @@ -2607,7 +2865,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB 2: .same(proto: "user"), 3: .same(proto: "position"), 7: .same(proto: "snr"), - 4: .standard(proto: "last_heard") + 4: .standard(proto: "last_heard"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2627,19 +2885,15 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB } func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 if self.num != 0 { try visitor.visitSingularUInt32Field(value: self.num, fieldNumber: 1) } - try { if let v = self._user { + if let v = self._user { try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { if let v = self._position { + } + if let v = self._position { try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } }() + } if self.lastHeard != 0 { try visitor.visitSingularFixed32Field(value: self.lastHeard, fieldNumber: 4) } @@ -2674,91 +2928,187 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 8: .standard(proto: "error_address"), 9: .standard(proto: "error_count"), 10: .standard(proto: "reboot_count"), + 11: .same(proto: "bitrate"), 13: .standard(proto: "message_timeout_msec"), - 14: .standard(proto: "min_app_version") + 14: .standard(proto: "min_app_version"), + 16: .standard(proto: "air_period_tx"), + 17: .standard(proto: "air_period_rx"), + 18: .standard(proto: "has_wifi"), + 19: .standard(proto: "channel_utilization"), ] + fileprivate class _StorageClass { + var _myNodeNum: UInt32 = 0 + var _hasGps_p: Bool = false + var _numBands: UInt32 = 0 + var _maxChannels: UInt32 = 0 + var _region: String = String() + var _hwModelDeprecated: String = String() + var _firmwareVersion: String = String() + var _errorCode: CriticalErrorCode = .none + var _errorAddress: UInt32 = 0 + var _errorCount: UInt32 = 0 + var _rebootCount: UInt32 = 0 + var _bitrate: Float = 0 + var _messageTimeoutMsec: UInt32 = 0 + var _minAppVersion: UInt32 = 0 + var _airPeriodTx: [UInt32] = [] + var _airPeriodRx: [UInt32] = [] + var _hasWifi_p: Bool = false + var _channelUtilization: Float = 0 + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _myNodeNum = source._myNodeNum + _hasGps_p = source._hasGps_p + _numBands = source._numBands + _maxChannels = source._maxChannels + _region = source._region + _hwModelDeprecated = source._hwModelDeprecated + _firmwareVersion = source._firmwareVersion + _errorCode = source._errorCode + _errorAddress = source._errorAddress + _errorCount = source._errorCount + _rebootCount = source._rebootCount + _bitrate = source._bitrate + _messageTimeoutMsec = source._messageTimeoutMsec + _minAppVersion = source._minAppVersion + _airPeriodTx = source._airPeriodTx + _airPeriodRx = source._airPeriodRx + _hasWifi_p = source._hasWifi_p + _channelUtilization = source._channelUtilization + } + } + + fileprivate mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularUInt32Field(value: &self.myNodeNum) }() - case 2: try { try decoder.decodeSingularBoolField(value: &self.hasGps_p) }() - case 3: try { try decoder.decodeSingularUInt32Field(value: &self.numBands) }() - case 4: try { try decoder.decodeSingularStringField(value: &self.region) }() - case 5: try { try decoder.decodeSingularStringField(value: &self.hwModelDeprecated) }() - case 6: try { try decoder.decodeSingularStringField(value: &self.firmwareVersion) }() - case 7: try { try decoder.decodeSingularEnumField(value: &self.errorCode) }() - case 8: try { try decoder.decodeSingularUInt32Field(value: &self.errorAddress) }() - case 9: try { try decoder.decodeSingularUInt32Field(value: &self.errorCount) }() - case 10: try { try decoder.decodeSingularUInt32Field(value: &self.rebootCount) }() - case 13: try { try decoder.decodeSingularUInt32Field(value: &self.messageTimeoutMsec) }() - case 14: try { try decoder.decodeSingularUInt32Field(value: &self.minAppVersion) }() - case 15: try { try decoder.decodeSingularUInt32Field(value: &self.maxChannels) }() - default: break + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt32Field(value: &_storage._myNodeNum) }() + case 2: try { try decoder.decodeSingularBoolField(value: &_storage._hasGps_p) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &_storage._numBands) }() + case 4: try { try decoder.decodeSingularStringField(value: &_storage._region) }() + case 5: try { try decoder.decodeSingularStringField(value: &_storage._hwModelDeprecated) }() + case 6: try { try decoder.decodeSingularStringField(value: &_storage._firmwareVersion) }() + case 7: try { try decoder.decodeSingularEnumField(value: &_storage._errorCode) }() + case 8: try { try decoder.decodeSingularUInt32Field(value: &_storage._errorAddress) }() + case 9: try { try decoder.decodeSingularUInt32Field(value: &_storage._errorCount) }() + case 10: try { try decoder.decodeSingularUInt32Field(value: &_storage._rebootCount) }() + case 11: try { try decoder.decodeSingularFloatField(value: &_storage._bitrate) }() + case 13: try { try decoder.decodeSingularUInt32Field(value: &_storage._messageTimeoutMsec) }() + case 14: try { try decoder.decodeSingularUInt32Field(value: &_storage._minAppVersion) }() + case 15: try { try decoder.decodeSingularUInt32Field(value: &_storage._maxChannels) }() + case 16: try { try decoder.decodeRepeatedUInt32Field(value: &_storage._airPeriodTx) }() + case 17: try { try decoder.decodeRepeatedUInt32Field(value: &_storage._airPeriodRx) }() + case 18: try { try decoder.decodeSingularBoolField(value: &_storage._hasWifi_p) }() + case 19: try { try decoder.decodeSingularFloatField(value: &_storage._channelUtilization) }() + default: break + } } } } func traverse(visitor: inout V) throws { - if self.myNodeNum != 0 { - try visitor.visitSingularUInt32Field(value: self.myNodeNum, fieldNumber: 1) - } - if self.hasGps_p != false { - try visitor.visitSingularBoolField(value: self.hasGps_p, fieldNumber: 2) - } - if self.numBands != 0 { - try visitor.visitSingularUInt32Field(value: self.numBands, fieldNumber: 3) - } - if !self.region.isEmpty { - try visitor.visitSingularStringField(value: self.region, fieldNumber: 4) - } - if !self.hwModelDeprecated.isEmpty { - try visitor.visitSingularStringField(value: self.hwModelDeprecated, fieldNumber: 5) - } - if !self.firmwareVersion.isEmpty { - try visitor.visitSingularStringField(value: self.firmwareVersion, fieldNumber: 6) - } - if self.errorCode != .none { - try visitor.visitSingularEnumField(value: self.errorCode, fieldNumber: 7) - } - if self.errorAddress != 0 { - try visitor.visitSingularUInt32Field(value: self.errorAddress, fieldNumber: 8) - } - if self.errorCount != 0 { - try visitor.visitSingularUInt32Field(value: self.errorCount, fieldNumber: 9) - } - if self.rebootCount != 0 { - try visitor.visitSingularUInt32Field(value: self.rebootCount, fieldNumber: 10) - } - if self.messageTimeoutMsec != 0 { - try visitor.visitSingularUInt32Field(value: self.messageTimeoutMsec, fieldNumber: 13) - } - if self.minAppVersion != 0 { - try visitor.visitSingularUInt32Field(value: self.minAppVersion, fieldNumber: 14) - } - if self.maxChannels != 0 { - try visitor.visitSingularUInt32Field(value: self.maxChannels, fieldNumber: 15) + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + if _storage._myNodeNum != 0 { + try visitor.visitSingularUInt32Field(value: _storage._myNodeNum, fieldNumber: 1) + } + if _storage._hasGps_p != false { + try visitor.visitSingularBoolField(value: _storage._hasGps_p, fieldNumber: 2) + } + if _storage._numBands != 0 { + try visitor.visitSingularUInt32Field(value: _storage._numBands, fieldNumber: 3) + } + if !_storage._region.isEmpty { + try visitor.visitSingularStringField(value: _storage._region, fieldNumber: 4) + } + if !_storage._hwModelDeprecated.isEmpty { + try visitor.visitSingularStringField(value: _storage._hwModelDeprecated, fieldNumber: 5) + } + if !_storage._firmwareVersion.isEmpty { + try visitor.visitSingularStringField(value: _storage._firmwareVersion, fieldNumber: 6) + } + if _storage._errorCode != .none { + try visitor.visitSingularEnumField(value: _storage._errorCode, fieldNumber: 7) + } + if _storage._errorAddress != 0 { + try visitor.visitSingularUInt32Field(value: _storage._errorAddress, fieldNumber: 8) + } + if _storage._errorCount != 0 { + try visitor.visitSingularUInt32Field(value: _storage._errorCount, fieldNumber: 9) + } + if _storage._rebootCount != 0 { + try visitor.visitSingularUInt32Field(value: _storage._rebootCount, fieldNumber: 10) + } + if _storage._bitrate != 0 { + try visitor.visitSingularFloatField(value: _storage._bitrate, fieldNumber: 11) + } + if _storage._messageTimeoutMsec != 0 { + try visitor.visitSingularUInt32Field(value: _storage._messageTimeoutMsec, fieldNumber: 13) + } + if _storage._minAppVersion != 0 { + try visitor.visitSingularUInt32Field(value: _storage._minAppVersion, fieldNumber: 14) + } + if _storage._maxChannels != 0 { + try visitor.visitSingularUInt32Field(value: _storage._maxChannels, fieldNumber: 15) + } + if !_storage._airPeriodTx.isEmpty { + try visitor.visitPackedUInt32Field(value: _storage._airPeriodTx, fieldNumber: 16) + } + if !_storage._airPeriodRx.isEmpty { + try visitor.visitPackedUInt32Field(value: _storage._airPeriodRx, fieldNumber: 17) + } + if _storage._hasWifi_p != false { + try visitor.visitSingularBoolField(value: _storage._hasWifi_p, fieldNumber: 18) + } + if _storage._channelUtilization != 0 { + try visitor.visitSingularFloatField(value: _storage._channelUtilization, fieldNumber: 19) + } } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: MyNodeInfo, rhs: MyNodeInfo) -> Bool { - if lhs.myNodeNum != rhs.myNodeNum {return false} - if lhs.hasGps_p != rhs.hasGps_p {return false} - if lhs.numBands != rhs.numBands {return false} - if lhs.maxChannels != rhs.maxChannels {return false} - if lhs.region != rhs.region {return false} - if lhs.hwModelDeprecated != rhs.hwModelDeprecated {return false} - if lhs.firmwareVersion != rhs.firmwareVersion {return false} - if lhs.errorCode != rhs.errorCode {return false} - if lhs.errorAddress != rhs.errorAddress {return false} - if lhs.errorCount != rhs.errorCount {return false} - if lhs.rebootCount != rhs.rebootCount {return false} - if lhs.messageTimeoutMsec != rhs.messageTimeoutMsec {return false} - if lhs.minAppVersion != rhs.minAppVersion {return false} + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in + let _storage = _args.0 + let rhs_storage = _args.1 + if _storage._myNodeNum != rhs_storage._myNodeNum {return false} + if _storage._hasGps_p != rhs_storage._hasGps_p {return false} + if _storage._numBands != rhs_storage._numBands {return false} + if _storage._maxChannels != rhs_storage._maxChannels {return false} + if _storage._region != rhs_storage._region {return false} + if _storage._hwModelDeprecated != rhs_storage._hwModelDeprecated {return false} + if _storage._firmwareVersion != rhs_storage._firmwareVersion {return false} + if _storage._errorCode != rhs_storage._errorCode {return false} + if _storage._errorAddress != rhs_storage._errorAddress {return false} + if _storage._errorCount != rhs_storage._errorCount {return false} + if _storage._rebootCount != rhs_storage._rebootCount {return false} + if _storage._bitrate != rhs_storage._bitrate {return false} + if _storage._messageTimeoutMsec != rhs_storage._messageTimeoutMsec {return false} + if _storage._minAppVersion != rhs_storage._minAppVersion {return false} + if _storage._airPeriodTx != rhs_storage._airPeriodTx {return false} + if _storage._airPeriodRx != rhs_storage._airPeriodRx {return false} + if _storage._hasWifi_p != rhs_storage._hasWifi_p {return false} + if _storage._channelUtilization != rhs_storage._channelUtilization {return false} + return true + } + if !storagesAreEqual {return false} + } if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -2770,7 +3120,7 @@ extension LogRecord: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation 1: .same(proto: "message"), 2: .same(proto: "time"), 3: .same(proto: "source"), - 4: .same(proto: "level") + 4: .same(proto: "level"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2822,7 +3172,7 @@ extension LogRecord.Level: SwiftProtobuf._ProtoNameProviding { 20: .same(proto: "INFO"), 30: .same(proto: "WARNING"), 40: .same(proto: "ERROR"), - 50: .same(proto: "CRITICAL") + 50: .same(proto: "CRITICAL"), ] } @@ -2835,164 +3185,129 @@ extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation 4: .standard(proto: "node_info"), 7: .standard(proto: "log_record"), 8: .standard(proto: "config_complete_id"), - 9: .same(proto: "rebooted") + 9: .same(proto: "rebooted"), ] - fileprivate class _StorageClass { - var _num: UInt32 = 0 - var _payloadVariant: FromRadio.OneOf_PayloadVariant? - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _num = source._num - _payloadVariant = source._payloadVariant - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularUInt32Field(value: &_storage._num) }() - case 3: try { - var v: MyNodeInfo? - var hadOneofValue = false - if let current = _storage._payloadVariant { - hadOneofValue = true - if case .myInfo(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - _storage._payloadVariant = .myInfo(v) - } - }() - case 4: try { - var v: NodeInfo? - var hadOneofValue = false - if let current = _storage._payloadVariant { - hadOneofValue = true - if case .nodeInfo(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - _storage._payloadVariant = .nodeInfo(v) - } - }() - case 7: try { - var v: LogRecord? - var hadOneofValue = false - if let current = _storage._payloadVariant { - hadOneofValue = true - if case .logRecord(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - _storage._payloadVariant = .logRecord(v) - } - }() - case 8: try { - var v: UInt32? - try decoder.decodeSingularUInt32Field(value: &v) - if let v = v { - if _storage._payloadVariant != nil {try decoder.handleConflictingOneOf()} - _storage._payloadVariant = .configCompleteID(v) - } - }() - case 9: try { - var v: Bool? - try decoder.decodeSingularBoolField(value: &v) - if let v = v { - if _storage._payloadVariant != nil {try decoder.handleConflictingOneOf()} - _storage._payloadVariant = .rebooted(v) - } - }() - case 11: try { - var v: MeshPacket? - var hadOneofValue = false - if let current = _storage._payloadVariant { - hadOneofValue = true - if case .packet(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - _storage._payloadVariant = .packet(v) - } - }() - default: break + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt32Field(value: &self.num) }() + case 3: try { + var v: MyNodeInfo? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .myInfo(let m) = current {v = m} } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .myInfo(v) + } + }() + case 4: try { + var v: NodeInfo? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .nodeInfo(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .nodeInfo(v) + } + }() + case 7: try { + var v: LogRecord? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .logRecord(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .logRecord(v) + } + }() + case 8: try { + var v: UInt32? + try decoder.decodeSingularUInt32Field(value: &v) + if let v = v { + if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} + self.payloadVariant = .configCompleteID(v) + } + }() + case 9: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} + self.payloadVariant = .rebooted(v) + } + }() + case 11: try { + var v: MeshPacket? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .packet(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .packet(v) + } + }() + default: break } } } func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if _storage._num != 0 { - try visitor.visitSingularUInt32Field(value: _storage._num, fieldNumber: 1) - } - switch _storage._payloadVariant { - case .myInfo?: try { - guard case .myInfo(let v)? = _storage._payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - }() - case .nodeInfo?: try { - guard case .nodeInfo(let v)? = _storage._payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - }() - case .logRecord?: try { - guard case .logRecord(let v)? = _storage._payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - }() - case .configCompleteID?: try { - guard case .configCompleteID(let v)? = _storage._payloadVariant else { preconditionFailure() } - try visitor.visitSingularUInt32Field(value: v, fieldNumber: 8) - }() - case .rebooted?: try { - guard case .rebooted(let v)? = _storage._payloadVariant else { preconditionFailure() } - try visitor.visitSingularBoolField(value: v, fieldNumber: 9) - }() - case .packet?: try { - guard case .packet(let v)? = _storage._payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 11) - }() - case nil: break - } + if self.num != 0 { + try visitor.visitSingularUInt32Field(value: self.num, fieldNumber: 1) + } + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch self.payloadVariant { + case .myInfo?: try { + guard case .myInfo(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + }() + case .nodeInfo?: try { + guard case .nodeInfo(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + }() + case .logRecord?: try { + guard case .logRecord(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + }() + case .configCompleteID?: try { + guard case .configCompleteID(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularUInt32Field(value: v, fieldNumber: 8) + }() + case .rebooted?: try { + guard case .rebooted(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularBoolField(value: v, fieldNumber: 9) + }() + case .packet?: try { + guard case .packet(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 11) + }() + case nil: break } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: FromRadio, rhs: FromRadio) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._num != rhs_storage._num {return false} - if _storage._payloadVariant != rhs_storage._payloadVariant {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs.num != rhs.num {return false} + if lhs.payloadVariant != rhs.payloadVariant {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -3004,7 +3319,7 @@ extension ToRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa 2: .same(proto: "packet"), 3: .standard(proto: "peer_info"), 100: .standard(proto: "want_config_id"), - 104: .same(proto: "disconnect") + 104: .same(proto: "disconnect"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -3062,9 +3377,8 @@ extension ToRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa func traverse(visitor: inout V) throws { // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch self.payloadVariant { case .packet?: try { guard case .packet(let v)? = self.payloadVariant else { preconditionFailure() } @@ -3098,7 +3412,7 @@ extension ToRadio.PeerInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme static let protoMessageName: String = ToRadio.protoMessageName + ".PeerInfo" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .standard(proto: "app_version"), - 2: .standard(proto: "mqtt_gateway") + 2: .standard(proto: "mqtt_gateway"), ] mutating func decodeMessage(decoder: inout D) throws { diff --git a/MeshtasticClient/Protobufs/mqtt.pb.swift b/MeshtasticClient/Protobufs/mqtt.pb.swift index 1dca74e1..988140a4 100644 --- a/MeshtasticClient/Protobufs/mqtt.pb.swift +++ b/MeshtasticClient/Protobufs/mqtt.pb.swift @@ -15,7 +15,7 @@ import SwiftProtobuf // incompatible with the version of SwiftProtobuf to which you are linking. // Please ensure that you are building against the same version of the API // that was used to generate this file. -private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} typealias Version = _2 } @@ -30,35 +30,29 @@ struct ServiceEnvelope { /// /// The (probably encrypted) packet var packet: MeshPacket { - get {return _storage._packet ?? MeshPacket()} - set {_uniqueStorage()._packet = newValue} + get {return _packet ?? MeshPacket()} + set {_packet = newValue} } /// Returns true if `packet` has been explicitly set. - var hasPacket: Bool {return _storage._packet != nil} + var hasPacket: Bool {return self._packet != nil} /// Clears the value of `packet`. Subsequent reads from it will return its default value. - mutating func clearPacket() {_uniqueStorage()._packet = nil} + mutating func clearPacket() {self._packet = nil} /// /// The global channel ID it was sent on - var channelID: String { - get {return _storage._channelID} - set {_uniqueStorage()._channelID = newValue} - } + var channelID: String = String() /// /// The sending gateway node ID. Can we use this to authenticate/prevent fake /// nodeid impersonation for senders? - i.e. use gateway/mesh id (which is authenticated) + local node id as /// the globally trusted nodenum - var gatewayID: String { - get {return _storage._gatewayID} - set {_uniqueStorage()._gatewayID = newValue} - } + var gatewayID: String = String() var unknownFields = SwiftProtobuf.UnknownStorage() init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _packet: MeshPacket? = nil } // MARK: - Code below here is support for the SwiftProtobuf runtime. @@ -68,80 +62,40 @@ extension ServiceEnvelope: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .same(proto: "packet"), 2: .standard(proto: "channel_id"), - 3: .standard(proto: "gateway_id") + 3: .standard(proto: "gateway_id"), ] - fileprivate class _StorageClass { - var _packet: MeshPacket? - var _channelID: String = String() - var _gatewayID: String = String() - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _packet = source._packet - _channelID = source._channelID - _gatewayID = source._gatewayID - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularMessageField(value: &_storage._packet) }() - case 2: try { try decoder.decodeSingularStringField(value: &_storage._channelID) }() - case 3: try { try decoder.decodeSingularStringField(value: &_storage._gatewayID) }() - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._packet) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.channelID) }() + case 3: try { try decoder.decodeSingularStringField(value: &self.gatewayID) }() + default: break } } } func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = _storage._packet { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - if !_storage._channelID.isEmpty { - try visitor.visitSingularStringField(value: _storage._channelID, fieldNumber: 2) - } - if !_storage._gatewayID.isEmpty { - try visitor.visitSingularStringField(value: _storage._gatewayID, fieldNumber: 3) - } + if let v = self._packet { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } + if !self.channelID.isEmpty { + try visitor.visitSingularStringField(value: self.channelID, fieldNumber: 2) + } + if !self.gatewayID.isEmpty { + try visitor.visitSingularStringField(value: self.gatewayID, fieldNumber: 3) } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: ServiceEnvelope, rhs: ServiceEnvelope) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._packet != rhs_storage._packet {return false} - if _storage._channelID != rhs_storage._channelID {return false} - if _storage._gatewayID != rhs_storage._gatewayID {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs._packet != rhs._packet {return false} + if lhs.channelID != rhs.channelID {return false} + if lhs.gatewayID != rhs.gatewayID {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/MeshtasticClient/Protobufs/portnums.pb.swift b/MeshtasticClient/Protobufs/portnums.pb.swift index 89aea9f5..9d204a69 100644 --- a/MeshtasticClient/Protobufs/portnums.pb.swift +++ b/MeshtasticClient/Protobufs/portnums.pb.swift @@ -15,7 +15,7 @@ import SwiftProtobuf // incompatible with the version of SwiftProtobuf to which you are linking. // Please ensure that you are building against the same version of the API // that was used to generate this file. -private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} typealias Version = _2 } @@ -43,7 +43,7 @@ enum PortNum: SwiftProtobuf.Enum { /// /// Deprecated: do not use in new code (formerly called OPAQUE) - /// A message sent from a device outside of the mesh, in a form the mesh does not understand + /// A message sent from a device outside of the mesh, in a form the mesh does not understand /// NOTE: This must be 0, because it is documented in IMeshService.aidl to be so case unknownApp // = 0 @@ -206,7 +206,7 @@ extension PortNum: CaseIterable { .zpsApp, .privateApp, .atakForwarder, - .max + .max, ] } @@ -232,6 +232,6 @@ extension PortNum: SwiftProtobuf._ProtoNameProviding { 68: .same(proto: "ZPS_APP"), 256: .same(proto: "PRIVATE_APP"), 257: .same(proto: "ATAK_FORWARDER"), - 511: .same(proto: "MAX") + 511: .same(proto: "MAX"), ] } diff --git a/MeshtasticClient/Protobufs/radioconfig.pb.swift b/MeshtasticClient/Protobufs/radioconfig.pb.swift index 34fc6aa6..77770d3d 100644 --- a/MeshtasticClient/Protobufs/radioconfig.pb.swift +++ b/MeshtasticClient/Protobufs/radioconfig.pb.swift @@ -34,7 +34,7 @@ import SwiftProtobuf // incompatible with the version of SwiftProtobuf to which you are linking. // Please ensure that you are building against the same version of the API // that was used to generate this file. -private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} typealias Version = _2 } @@ -114,7 +114,7 @@ extension RegionCode: CaseIterable { .anz, .kr, .tw, - .ru + .ru, ] } @@ -217,7 +217,7 @@ extension ChargeCurrent: CaseIterable { .ma1080, .ma1160, .ma1240, - .ma1320 + .ma1320, ] } @@ -292,7 +292,7 @@ extension GpsOperation: CaseIterable { .gpsOpStationary, .gpsOpMobile, .gpsOpTimeOnly, - .gpsOpDisabled + .gpsOpDisabled, ] } @@ -304,23 +304,23 @@ enum GpsCoordinateFormat: SwiftProtobuf.Enum { typealias RawValue = Int /// - /// GPS coordinates are displayed in the normal decimal degrees format: + /// GPS coordinates are displayed in the normal decimal degrees format: /// DD.DDDDDD DDD.DDDDDD case gpsFormatDec // = 0 /// - /// GPS coordinates are displayed in the degrees minutes seconds format: + /// GPS coordinates are displayed in the degrees minutes seconds format: /// DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant case gpsFormatDms // = 1 /// - /// GPS coordinates are displayed in Universal Transverse Mercator format: + /// GPS coordinates are displayed in Universal Transverse Mercator format: /// ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing case gpsFormatUtm // = 2 /// - /// GPS coordinates are displayed in Military Grid Reference System format: - /// ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square, + /// GPS coordinates are displayed in Military Grid Reference System format: + /// ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square, /// E is easting, N is northing case gpsFormatMgrs // = 3 @@ -375,7 +375,7 @@ extension GpsCoordinateFormat: CaseIterable { .gpsFormatUtm, .gpsFormatMgrs, .gpsFormatOlc, - .gpsFormatOsgr + .gpsFormatOsgr, ] } @@ -430,14 +430,14 @@ extension LocationSharing: CaseIterable { static var allCases: [LocationSharing] = [ .locUnset, .locEnabled, - .locDisabled + .locDisabled, ] } #endif // swift(>=4.2) /// -/// Bit field of boolean configuration options, indicating which optional +/// Bit field of boolean configuration options, indicating which optional /// fields to include when assembling POSITION messages /// Longitude and latitude are always included (also time if GPS-synced) /// @@ -529,7 +529,7 @@ extension PositionFlags: CaseIterable { .posBattery, .posSatinview, .posSeqNos, - .posTimestamp + .posTimestamp, ] } @@ -556,7 +556,7 @@ struct RadioConfig { var unknownFields = SwiftProtobuf.UnknownStorage() /// - /// see [software design](/software/other/sw-design.md) for more information on these preferences + /// See [software design](/software/other/sw-design.md) for more information on these preferences struct UserPreferences { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -760,7 +760,7 @@ struct RadioConfig { /// How long should we try to get our position during each gps_update_interval attempt? (in seconds) /// Or if zero, use the default of 30 seconds. /// If we don't get a new gps fix in that time, the gps will be put into sleep until the next gps_update_rate - /// window. + /// window. var gpsAttemptTime: UInt32 { get {return _storage._gpsAttemptTime} set {_uniqueStorage()._gpsAttemptTime = newValue} @@ -798,7 +798,7 @@ struct RadioConfig { /// /// The server to use for our MQTT global message gateway feature. - /// If not set, the default server will be used + /// If not set, the default server will be used var mqttServer: String { get {return _storage._mqttServer} set {_uniqueStorage()._mqttServer = newValue} @@ -936,7 +936,7 @@ struct RadioConfig { /// /// Preferences for the StoreForwardPlugin - /// FIXME - Move this out of UserPreferences and into a section for plugin configuration. (was 136) + ///FIXME - Move this out of UserPreferences and into a section for plugin configuration. (was 136) var storeForwardPluginEnabled: Bool { get {return _storage._storeForwardPluginEnabled} set {_uniqueStorage()._storeForwardPluginEnabled = newValue} @@ -988,7 +988,7 @@ struct RadioConfig { } /// - /// Interval in seconds of how often we should try to send our + /// Interval in seconds of how often we should try to send our /// measurements to the mesh var environmentalMeasurementPluginUpdateInterval: UInt32 { get {return _storage._environmentalMeasurementPluginUpdateInterval} @@ -1035,7 +1035,7 @@ struct RadioConfig { } /// - /// Circumvents the logic block for determining whether the device is powered or not. + /// Circumvents the logic block for determining whether the device is powered or not. /// Useful for devices with finicky ADC issues on the battery sense pins. var isAlwaysPowered: Bool { get {return _storage._isAlwaysPowered} @@ -1043,13 +1043,45 @@ struct RadioConfig { } /// - /// Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds. + /// Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds. /// Potentially useful for devices without user buttons. var autoScreenCarouselSecs: UInt32 { get {return _storage._autoScreenCarouselSecs} set {_uniqueStorage()._autoScreenCarouselSecs = newValue} } + /// + /// If non-zero, the device will fully power off this many seconds after external power is removed. + var onBatteryShutdownAfterSecs: UInt32 { + get {return _storage._onBatteryShutdownAfterSecs} + set {_uniqueStorage()._onBatteryShutdownAfterSecs = newValue} + } + + /// + /// Overrides HOPS_RELIABLE and sets the maximum number of hops. This can't be greater than 7. + var hopLimit: UInt32 { + get {return _storage._hopLimit} + set {_uniqueStorage()._hopLimit = newValue} + } + + /// + /// MQTT username to use (most useful for a custom MQTT server). + /// If using a custom server, this will be honoured even if empty. + /// If using the default server, this will only be honoured if set, otherwise the device will use the default username + var mqttUsername: String { + get {return _storage._mqttUsername} + set {_uniqueStorage()._mqttUsername = newValue} + } + + /// + /// MQTT password to use (most useful for a custom MQTT server). + /// If using a custom server, this will be honoured even if empty. + /// If using the default server, this will only be honoured if set, otherwise the device will use the default password + var mqttPassword: String { + get {return _storage._mqttPassword} + set {_uniqueStorage()._mqttPassword = newValue} + } + var unknownFields = SwiftProtobuf.UnknownStorage() enum EnvironmentalMeasurementSensorType: SwiftProtobuf.Enum { @@ -1087,7 +1119,7 @@ struct RadioConfig { init() {} - fileprivate var _preferences: RadioConfig.UserPreferences? + fileprivate var _preferences: RadioConfig.UserPreferences? = nil } #if swift(>=4.2) @@ -1096,7 +1128,7 @@ extension RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType: CaseIt // The compiler won't synthesize support with the UNRECOGNIZED case. static var allCases: [RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType] = [ .dht11, - .ds18B20 + .ds18B20, ] } @@ -1115,7 +1147,7 @@ extension RegionCode: SwiftProtobuf._ProtoNameProviding { 6: .same(proto: "ANZ"), 7: .same(proto: "KR"), 8: .same(proto: "TW"), - 9: .same(proto: "RU") + 9: .same(proto: "RU"), ] } @@ -1137,7 +1169,7 @@ extension ChargeCurrent: SwiftProtobuf._ProtoNameProviding { 13: .same(proto: "MA1080"), 14: .same(proto: "MA1160"), 15: .same(proto: "MA1240"), - 16: .same(proto: "MA1320") + 16: .same(proto: "MA1320"), ] } @@ -1147,7 +1179,7 @@ extension GpsOperation: SwiftProtobuf._ProtoNameProviding { 1: .same(proto: "GpsOpStationary"), 2: .same(proto: "GpsOpMobile"), 3: .same(proto: "GpsOpTimeOnly"), - 4: .same(proto: "GpsOpDisabled") + 4: .same(proto: "GpsOpDisabled"), ] } @@ -1158,7 +1190,7 @@ extension GpsCoordinateFormat: SwiftProtobuf._ProtoNameProviding { 2: .same(proto: "GpsFormatUTM"), 3: .same(proto: "GpsFormatMGRS"), 4: .same(proto: "GpsFormatOLC"), - 5: .same(proto: "GpsFormatOSGR") + 5: .same(proto: "GpsFormatOSGR"), ] } @@ -1166,7 +1198,7 @@ extension LocationSharing: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 0: .same(proto: "LocUnset"), 1: .same(proto: "LocEnabled"), - 2: .same(proto: "LocDisabled") + 2: .same(proto: "LocDisabled"), ] } @@ -1181,14 +1213,14 @@ extension PositionFlags: SwiftProtobuf._ProtoNameProviding { 32: .same(proto: "POS_BATTERY"), 64: .same(proto: "POS_SATINVIEW"), 128: .same(proto: "POS_SEQ_NOS"), - 256: .same(proto: "POS_TIMESTAMP") + 256: .same(proto: "POS_TIMESTAMP"), ] } extension RadioConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "RadioConfig" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "preferences") + 1: .same(proto: "preferences"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -1204,13 +1236,9 @@ extension RadioConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati } func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._preferences { + if let v = self._preferences { try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() + } try unknownFields.traverse(visitor: &visitor) } @@ -1287,7 +1315,11 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes 147: .standard(proto: "environmental_measurement_plugin_sensor_pin"), 150: .standard(proto: "position_flags"), 151: .standard(proto: "is_always_powered"), - 152: .standard(proto: "auto_screen_carousel_secs") + 152: .standard(proto: "auto_screen_carousel_secs"), + 153: .standard(proto: "on_battery_shutdown_after_secs"), + 154: .standard(proto: "hop_limit"), + 155: .standard(proto: "mqtt_username"), + 156: .standard(proto: "mqtt_password"), ] fileprivate class _StorageClass { @@ -1355,6 +1387,10 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes var _positionFlags: UInt32 = 0 var _isAlwaysPowered: Bool = false var _autoScreenCarouselSecs: UInt32 = 0 + var _onBatteryShutdownAfterSecs: UInt32 = 0 + var _hopLimit: UInt32 = 0 + var _mqttUsername: String = String() + var _mqttPassword: String = String() static let defaultInstance = _StorageClass() @@ -1425,6 +1461,10 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes _positionFlags = source._positionFlags _isAlwaysPowered = source._isAlwaysPowered _autoScreenCarouselSecs = source._autoScreenCarouselSecs + _onBatteryShutdownAfterSecs = source._onBatteryShutdownAfterSecs + _hopLimit = source._hopLimit + _mqttUsername = source._mqttUsername + _mqttPassword = source._mqttPassword } } @@ -1507,6 +1547,10 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes case 150: try { try decoder.decodeSingularUInt32Field(value: &_storage._positionFlags) }() case 151: try { try decoder.decodeSingularBoolField(value: &_storage._isAlwaysPowered) }() case 152: try { try decoder.decodeSingularUInt32Field(value: &_storage._autoScreenCarouselSecs) }() + case 153: try { try decoder.decodeSingularUInt32Field(value: &_storage._onBatteryShutdownAfterSecs) }() + case 154: try { try decoder.decodeSingularUInt32Field(value: &_storage._hopLimit) }() + case 155: try { try decoder.decodeSingularStringField(value: &_storage._mqttUsername) }() + case 156: try { try decoder.decodeSingularStringField(value: &_storage._mqttPassword) }() default: break } } @@ -1707,6 +1751,18 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._autoScreenCarouselSecs != 0 { try visitor.visitSingularUInt32Field(value: _storage._autoScreenCarouselSecs, fieldNumber: 152) } + if _storage._onBatteryShutdownAfterSecs != 0 { + try visitor.visitSingularUInt32Field(value: _storage._onBatteryShutdownAfterSecs, fieldNumber: 153) + } + if _storage._hopLimit != 0 { + try visitor.visitSingularUInt32Field(value: _storage._hopLimit, fieldNumber: 154) + } + if !_storage._mqttUsername.isEmpty { + try visitor.visitSingularStringField(value: _storage._mqttUsername, fieldNumber: 155) + } + if !_storage._mqttPassword.isEmpty { + try visitor.visitSingularStringField(value: _storage._mqttPassword, fieldNumber: 156) + } } try unknownFields.traverse(visitor: &visitor) } @@ -1780,6 +1836,10 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._positionFlags != rhs_storage._positionFlags {return false} if _storage._isAlwaysPowered != rhs_storage._isAlwaysPowered {return false} if _storage._autoScreenCarouselSecs != rhs_storage._autoScreenCarouselSecs {return false} + if _storage._onBatteryShutdownAfterSecs != rhs_storage._onBatteryShutdownAfterSecs {return false} + if _storage._hopLimit != rhs_storage._hopLimit {return false} + if _storage._mqttUsername != rhs_storage._mqttUsername {return false} + if _storage._mqttPassword != rhs_storage._mqttPassword {return false} return true } if !storagesAreEqual {return false} @@ -1792,6 +1852,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes extension RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 0: .same(proto: "DHT11"), - 1: .same(proto: "DS18B20") + 1: .same(proto: "DS18B20"), ] } diff --git a/MeshtasticClient/Protobufs/remote_hardware.pb.swift b/MeshtasticClient/Protobufs/remote_hardware.pb.swift index 445db300..5a21328d 100644 --- a/MeshtasticClient/Protobufs/remote_hardware.pb.swift +++ b/MeshtasticClient/Protobufs/remote_hardware.pb.swift @@ -15,13 +15,13 @@ import SwiftProtobuf // incompatible with the version of SwiftProtobuf to which you are linking. // Please ensure that you are building against the same version of the API // that was used to generate this file. -private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} typealias Version = _2 } /// -/// An example app to show off the plugin system. This message is used for +/// An example app to show off the plugin system. This message is used for /// REMOTE_HARDWARE_APP PortNums. /// /// Also provides easy remote access to any GPIO. @@ -126,7 +126,7 @@ extension HardwareMessage.TypeEnum: CaseIterable { .watchGpios, .gpiosChanged, .readGpios, - .readGpiosReply + .readGpiosReply, ] } @@ -139,7 +139,7 @@ extension HardwareMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .same(proto: "typ"), 2: .standard(proto: "gpio_mask"), - 3: .standard(proto: "gpio_value") + 3: .standard(proto: "gpio_value"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -185,6 +185,6 @@ extension HardwareMessage.TypeEnum: SwiftProtobuf._ProtoNameProviding { 2: .same(proto: "WATCH_GPIOS"), 3: .same(proto: "GPIOS_CHANGED"), 4: .same(proto: "READ_GPIOS"), - 5: .same(proto: "READ_GPIOS_REPLY") + 5: .same(proto: "READ_GPIOS_REPLY"), ] } diff --git a/MeshtasticClient/Protobufs/storeforward.pb.swift b/MeshtasticClient/Protobufs/storeforward.pb.swift index 3c05a43d..ceb9d9f8 100644 --- a/MeshtasticClient/Protobufs/storeforward.pb.swift +++ b/MeshtasticClient/Protobufs/storeforward.pb.swift @@ -15,20 +15,20 @@ import SwiftProtobuf // incompatible with the version of SwiftProtobuf to which you are linking. // Please ensure that you are building against the same version of the API // that was used to generate this file. -private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} typealias Version = _2 } -struct StoreAndForwardMessage { +struct StoreAndForward { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. - var rr: StoreAndForwardMessage.RequestResponse = .unset + var rr: StoreAndForward.RequestResponse = .unset - var stats: StoreAndForwardMessage.Statistics { - get {return _stats ?? StoreAndForwardMessage.Statistics()} + var stats: StoreAndForward.Statistics { + get {return _stats ?? StoreAndForward.Statistics()} set {_stats = newValue} } /// Returns true if `stats` has been explicitly set. @@ -36,8 +36,8 @@ struct StoreAndForwardMessage { /// Clears the value of `stats`. Subsequent reads from it will return its default value. mutating func clearStats() {self._stats = nil} - var history: StoreAndForwardMessage.History { - get {return _history ?? StoreAndForwardMessage.History()} + var history: StoreAndForward.History { + get {return _history ?? StoreAndForward.History()} set {_history = newValue} } /// Returns true if `history` has been explicitly set. @@ -45,6 +45,15 @@ struct StoreAndForwardMessage { /// Clears the value of `history`. Subsequent reads from it will return its default value. mutating func clearHistory() {self._history = nil} + var heartbeat: StoreAndForward.Heartbeat { + get {return _heartbeat ?? StoreAndForward.Heartbeat()} + set {_heartbeat = newValue} + } + /// Returns true if `heartbeat` has been explicitly set. + var hasHeartbeat: Bool {return self._heartbeat != nil} + /// Clears the value of `heartbeat`. Subsequent reads from it will return its default value. + mutating func clearHeartbeat() {self._heartbeat = nil} + var unknownFields = SwiftProtobuf.UnknownStorage() /// @@ -56,7 +65,13 @@ struct StoreAndForwardMessage { /// /// Unset/unused case unset // = 0 + + /// + /// Router is an in error state. case routerError // = 1 + + /// + /// Router heartbeat case routerHeartbeat // = 2 /// @@ -71,6 +86,13 @@ struct StoreAndForwardMessage { /// /// Router is currently busy. Please try again later. case routerBusy // = 5 + + /// + /// Router is responding to a request for history. + case routerHistory // = 6 + + /// + /// Client is an in error state. case clientError // = 101 /// @@ -89,7 +111,10 @@ struct StoreAndForwardMessage { /// /// The response to a "Ping" case clientPong // = 105 - case max // = 255 + + /// + /// Client has requested that the router abort processing the client's request + case clientAbort // = 106 case UNRECOGNIZED(Int) init() { @@ -104,12 +129,13 @@ struct StoreAndForwardMessage { case 3: self = .routerPing case 4: self = .routerPong case 5: self = .routerBusy + case 6: self = .routerHistory case 101: self = .clientError case 102: self = .clientHistory case 103: self = .clientStats case 104: self = .clientPing case 105: self = .clientPong - case 255: self = .max + case 106: self = .clientAbort default: self = .UNRECOGNIZED(rawValue) } } @@ -122,12 +148,13 @@ struct StoreAndForwardMessage { case .routerPing: return 3 case .routerPong: return 4 case .routerBusy: return 5 + case .routerHistory: return 6 case .clientError: return 101 case .clientHistory: return 102 case .clientStats: return 103 case .clientPing: return 104 case .clientPong: return 105 - case .max: return 255 + case .clientAbort: return 106 case .UNRECOGNIZED(let i): return i } } @@ -193,6 +220,28 @@ struct StoreAndForwardMessage { /// The window of messages that was used to filter the history client requested var window: UInt32 = 0 + /// + /// The window of messages that was used to filter the history client requested + var lastRequest: UInt32 = 0 + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + struct Heartbeat { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// + /// Number of that will be sent to the client + var period: UInt32 = 0 + + /// + /// If set, this is not the primary Store & Forward router on the mesh + var secondary: UInt32 = 0 + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -200,27 +249,29 @@ struct StoreAndForwardMessage { init() {} - fileprivate var _stats: StoreAndForwardMessage.Statistics? - fileprivate var _history: StoreAndForwardMessage.History? + fileprivate var _stats: StoreAndForward.Statistics? = nil + fileprivate var _history: StoreAndForward.History? = nil + fileprivate var _heartbeat: StoreAndForward.Heartbeat? = nil } #if swift(>=4.2) -extension StoreAndForwardMessage.RequestResponse: CaseIterable { +extension StoreAndForward.RequestResponse: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. - static var allCases: [StoreAndForwardMessage.RequestResponse] = [ + static var allCases: [StoreAndForward.RequestResponse] = [ .unset, .routerError, .routerHeartbeat, .routerPing, .routerPong, .routerBusy, + .routerHistory, .clientError, .clientHistory, .clientStats, .clientPing, .clientPong, - .max + .clientAbort, ] } @@ -228,12 +279,13 @@ extension StoreAndForwardMessage.RequestResponse: CaseIterable { // MARK: - Code below here is support for the SwiftProtobuf runtime. -extension StoreAndForwardMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = "StoreAndForwardMessage" +extension StoreAndForward: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = "StoreAndForward" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .same(proto: "rr"), 2: .same(proto: "stats"), - 3: .same(proto: "history") + 3: .same(proto: "history"), + 4: .same(proto: "heartbeat"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -245,38 +297,39 @@ extension StoreAndForwardMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageI case 1: try { try decoder.decodeSingularEnumField(value: &self.rr) }() case 2: try { try decoder.decodeSingularMessageField(value: &self._stats) }() case 3: try { try decoder.decodeSingularMessageField(value: &self._history) }() + case 4: try { try decoder.decodeSingularMessageField(value: &self._heartbeat) }() default: break } } } func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 if self.rr != .unset { try visitor.visitSingularEnumField(value: self.rr, fieldNumber: 1) } - try { if let v = self._stats { + if let v = self._stats { try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { if let v = self._history { + } + if let v = self._history { try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } }() + } + if let v = self._heartbeat { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } try unknownFields.traverse(visitor: &visitor) } - static func ==(lhs: StoreAndForwardMessage, rhs: StoreAndForwardMessage) -> Bool { + static func ==(lhs: StoreAndForward, rhs: StoreAndForward) -> Bool { if lhs.rr != rhs.rr {return false} if lhs._stats != rhs._stats {return false} if lhs._history != rhs._history {return false} + if lhs._heartbeat != rhs._heartbeat {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } } -extension StoreAndForwardMessage.RequestResponse: SwiftProtobuf._ProtoNameProviding { +extension StoreAndForward.RequestResponse: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 0: .same(proto: "UNSET"), 1: .same(proto: "ROUTER_ERROR"), @@ -284,27 +337,28 @@ extension StoreAndForwardMessage.RequestResponse: SwiftProtobuf._ProtoNameProvid 3: .same(proto: "ROUTER_PING"), 4: .same(proto: "ROUTER_PONG"), 5: .same(proto: "ROUTER_BUSY"), + 6: .same(proto: "ROUTER_HISTORY"), 101: .same(proto: "CLIENT_ERROR"), 102: .same(proto: "CLIENT_HISTORY"), 103: .same(proto: "CLIENT_STATS"), 104: .same(proto: "CLIENT_PING"), 105: .same(proto: "CLIENT_PONG"), - 255: .same(proto: "MAX") + 106: .same(proto: "CLIENT_ABORT"), ] } -extension StoreAndForwardMessage.Statistics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = StoreAndForwardMessage.protoMessageName + ".Statistics" +extension StoreAndForward.Statistics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = StoreAndForward.protoMessageName + ".Statistics" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "MessagesTotal"), - 2: .same(proto: "MessagesSaved"), - 3: .same(proto: "MessagesMax"), - 4: .same(proto: "UpTime"), - 5: .same(proto: "Requests"), - 6: .same(proto: "RequestsHistory"), - 7: .same(proto: "Heartbeat"), - 8: .same(proto: "ReturnMax"), - 9: .same(proto: "ReturnWindow") + 1: .standard(proto: "messages_total"), + 2: .standard(proto: "messages_saved"), + 3: .standard(proto: "messages_max"), + 4: .standard(proto: "up_time"), + 5: .same(proto: "requests"), + 6: .standard(proto: "requests_history"), + 7: .same(proto: "heartbeat"), + 8: .standard(proto: "return_max"), + 9: .standard(proto: "return_window"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -358,7 +412,7 @@ extension StoreAndForwardMessage.Statistics: SwiftProtobuf.Message, SwiftProtobu try unknownFields.traverse(visitor: &visitor) } - static func ==(lhs: StoreAndForwardMessage.Statistics, rhs: StoreAndForwardMessage.Statistics) -> Bool { + static func ==(lhs: StoreAndForward.Statistics, rhs: StoreAndForward.Statistics) -> Bool { if lhs.messagesTotal != rhs.messagesTotal {return false} if lhs.messagesSaved != rhs.messagesSaved {return false} if lhs.messagesMax != rhs.messagesMax {return false} @@ -373,11 +427,12 @@ extension StoreAndForwardMessage.Statistics: SwiftProtobuf.Message, SwiftProtobu } } -extension StoreAndForwardMessage.History: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = StoreAndForwardMessage.protoMessageName + ".History" +extension StoreAndForward.History: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = StoreAndForward.protoMessageName + ".History" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "HistoryMessages"), - 2: .same(proto: "Window") + 1: .standard(proto: "history_messages"), + 2: .same(proto: "window"), + 3: .standard(proto: "last_request"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -388,6 +443,7 @@ extension StoreAndForwardMessage.History: SwiftProtobuf.Message, SwiftProtobuf._ switch fieldNumber { case 1: try { try decoder.decodeSingularUInt32Field(value: &self.historyMessages) }() case 2: try { try decoder.decodeSingularUInt32Field(value: &self.window) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self.lastRequest) }() default: break } } @@ -400,12 +456,54 @@ extension StoreAndForwardMessage.History: SwiftProtobuf.Message, SwiftProtobuf._ if self.window != 0 { try visitor.visitSingularUInt32Field(value: self.window, fieldNumber: 2) } + if self.lastRequest != 0 { + try visitor.visitSingularUInt32Field(value: self.lastRequest, fieldNumber: 3) + } try unknownFields.traverse(visitor: &visitor) } - static func ==(lhs: StoreAndForwardMessage.History, rhs: StoreAndForwardMessage.History) -> Bool { + static func ==(lhs: StoreAndForward.History, rhs: StoreAndForward.History) -> Bool { if lhs.historyMessages != rhs.historyMessages {return false} if lhs.window != rhs.window {return false} + if lhs.lastRequest != rhs.lastRequest {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension StoreAndForward.Heartbeat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = StoreAndForward.protoMessageName + ".Heartbeat" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "period"), + 2: .same(proto: "secondary"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt32Field(value: &self.period) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.secondary) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.period != 0 { + try visitor.visitSingularUInt32Field(value: self.period, fieldNumber: 1) + } + if self.secondary != 0 { + try visitor.visitSingularUInt32Field(value: self.secondary, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: StoreAndForward.Heartbeat, rhs: StoreAndForward.Heartbeat) -> Bool { + if lhs.period != rhs.period {return false} + if lhs.secondary != rhs.secondary {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/MeshtasticClient/Views/Messages/Channels.swift b/MeshtasticClient/Views/Messages/Channels.swift index 1d51c4d2..5055f10a 100644 --- a/MeshtasticClient/Views/Messages/Channels.swift +++ b/MeshtasticClient/Views/Messages/Channels.swift @@ -16,8 +16,8 @@ struct Channels: View { HStack { - Image(systemName: "dial.max.fill") - .font(.system(size: 62)) + Image(systemName: "megaphone.fill") + .font(.largeTitle) .symbolRenderingMode(.hierarchical) .padding(.trailing) .foregroundColor(.accentColor) diff --git a/MeshtasticClient/Views/Messages/Messages.swift b/MeshtasticClient/Views/Messages/Messages.swift index 05d26642..68cdfb72 100644 --- a/MeshtasticClient/Views/Messages/Messages.swift +++ b/MeshtasticClient/Views/Messages/Messages.swift @@ -175,19 +175,11 @@ struct Messages: View { .padding(.bottom, 15) Button(action: { - if bleManager.sendMessage(message: typingMessage, toUserNum: Int64(self.bleManager.broadcastNodeNum)) { + if self.bleManager.sendMessage(message: typingMessage, toUserNum: Int64(self.bleManager.broadcastNodeNum)) { typingMessage = "" focusedField = nil - } else { - - _ = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false) { (_) in - - if bleManager.sendMessage(message: typingMessage, toUserNum: Int64(self.bleManager.broadcastNodeNum)) { - typingMessage = "" - } - } } - + }) { Image(systemName: "arrow.up.circle.fill").font(.largeTitle).foregroundColor(.blue) } @@ -203,9 +195,9 @@ struct Messages: View { ZStack { ConnectedDevice( - bluetoothOn: bleManager.isSwitchedOn, - deviceConnected: bleManager.connectedPeripheral != nil, - name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???") + bluetoothOn: self.bleManager.isSwitchedOn, + deviceConnected: self.bleManager.connectedPeripheral != nil, + name: (self.bleManager.connectedPeripheral != nil) ? self.bleManager.connectedPeripheral.shortName : "???") } ) } diff --git a/MeshtasticClient/Views/Nodes/NodeMap.swift b/MeshtasticClient/Views/Nodes/NodeMap.swift index 552076c1..6fc93b3e 100644 --- a/MeshtasticClient/Views/Nodes/NodeMap.swift +++ b/MeshtasticClient/Views/Nodes/NodeMap.swift @@ -25,24 +25,15 @@ struct NodeMap: View { private var locationNodes: FetchedResults - var annotations: [MapLocation] = [MapLocation]() - var body: some View { let location = LocationHelper.currentLocation - let currentCoordinatePosition = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude) - let regionBinding = Binding( - get: { - MKCoordinateRegion(center: currentCoordinatePosition, span: MKCoordinateSpan(latitudeDelta: 0.0359, longitudeDelta: 0.0359)) - }, - set: { _ in } - ) NavigationView { ZStack { - MapView(nodes: self.locationNodes)// .environmentObject(userSettings) + MapView(nodes: self.locationNodes)//.environmentObject(bleManager) // } .frame(maxHeight: .infinity) .ignoresSafeArea(.all, edges: [.leading, .trailing])