From 9524405fbf99e580180c6e2f489aeae54e52a43f Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 29 Mar 2022 18:53:33 -0700 Subject: [PATCH 01/21] Update photos to 1.03 --- Meshtastic Client.xcodeproj/project.pbxproj | 8 +- MeshtasticClient/Helpers/BLEManager.swift | 16 +- MeshtasticClient/Protobufs/admin.pb.swift | 552 +++--- MeshtasticClient/Protobufs/apponly.pb.swift | 6 + .../Protobufs/cannedmessages.pb.swift | 253 +-- MeshtasticClient/Protobufs/channel.pb.swift | 109 +- .../Protobufs/deviceonly.pb.swift | 220 +-- .../environmental_measurement.pb.swift | 107 -- MeshtasticClient/Protobufs/mesh.pb.swift | 613 ++++-- MeshtasticClient/Protobufs/mqtt.pb.swift | 12 +- MeshtasticClient/Protobufs/portnums.pb.swift | 34 +- .../Protobufs/radioconfig.pb.swift | 1709 ++++++++++------- .../Protobufs/remote_hardware.pb.swift | 9 +- .../Protobufs/storeforward.pb.swift | 40 +- MeshtasticClient/Protobufs/telemetry.pb.swift | 352 ++++ gen_protos.sh | 2 +- 16 files changed, 2283 insertions(+), 1759 deletions(-) delete mode 100644 MeshtasticClient/Protobufs/environmental_measurement.pb.swift create mode 100644 MeshtasticClient/Protobufs/telemetry.pb.swift diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 74e34ea2..42d90624 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -43,8 +43,8 @@ DDAF8C6526ED0A490058C060 /* channel.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C6426ED0A490058C060 /* channel.pb.swift */; }; DDAF8C6726ED0C8C0058C060 /* remote_hardware.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C6626ED0C8C0058C060 /* remote_hardware.pb.swift */; }; DDAF8C6926ED0D070058C060 /* deviceonly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C6826ED0D070058C060 /* deviceonly.pb.swift */; }; - DDAF8C6B26ED0DD80058C060 /* environmental_measurement.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C6A26ED0DD80058C060 /* environmental_measurement.pb.swift */; }; DDAF8C6E26ED19040058C060 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C6D26ED19040058C060 /* Extensions.swift */; }; + DDB2CC6E27F3EB47009C5FCC /* telemetry.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB2CC6D27F3EB47009C5FCC /* telemetry.pb.swift */; }; DDC2E15826CE248E0042C5E4 /* MeshtasticClientApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E15726CE248E0042C5E4 /* MeshtasticClientApp.swift */; }; DDC2E15C26CE248F0042C5E4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */; }; DDC2E15F26CE248F0042C5E4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15E26CE248F0042C5E4 /* Preview Assets.xcassets */; }; @@ -110,8 +110,8 @@ DDAF8C6426ED0A490058C060 /* channel.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = channel.pb.swift; sourceTree = ""; }; DDAF8C6626ED0C8C0058C060 /* remote_hardware.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = remote_hardware.pb.swift; sourceTree = ""; }; DDAF8C6826ED0D070058C060 /* deviceonly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = deviceonly.pb.swift; sourceTree = ""; }; - DDAF8C6A26ED0DD80058C060 /* environmental_measurement.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = environmental_measurement.pb.swift; sourceTree = ""; }; DDAF8C6D26ED19040058C060 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; + DDB2CC6D27F3EB47009C5FCC /* telemetry.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = telemetry.pb.swift; sourceTree = ""; }; DDC2E15426CE248E0042C5E4 /* MeshtasticClient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeshtasticClient.app; sourceTree = BUILT_PRODUCTS_DIR; }; DDC2E15726CE248E0042C5E4 /* MeshtasticClientApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticClientApp.swift; sourceTree = ""; }; DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = ../Assets.xcassets; sourceTree = ""; }; @@ -213,12 +213,12 @@ DDAF8C5626ED07740058C060 /* Protobufs */ = { isa = PBXGroup; children = ( + DDB2CC6D27F3EB47009C5FCC /* telemetry.pb.swift */, DD4DED8F27AD2975004BA27E /* cannedmessages.pb.swift */, DDAF8C6126ED0A230058C060 /* admin.pb.swift */, C9A88B56278B559900BD810A /* apponly.pb.swift */, DDAF8C6426ED0A490058C060 /* channel.pb.swift */, DDAF8C6826ED0D070058C060 /* deviceonly.pb.swift */, - DDAF8C6A26ED0DD80058C060 /* environmental_measurement.pb.swift */, DDAF8C5726ED07FD0058C060 /* mesh.pb.swift */, DDAF8C6026ED0A230058C060 /* mqtt.pb.swift */, DDAF8C5C26ED09490058C060 /* portnums.pb.swift */, @@ -538,7 +538,6 @@ DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */, DD8169FF272476C700F4AB02 /* LogDocument.swift in Sources */, DDAF8C6926ED0D070058C060 /* deviceonly.pb.swift in Sources */, - DDAF8C6B26ED0DD80058C060 /* environmental_measurement.pb.swift in Sources */, DD90860C26F684AF00DC5189 /* BatteryIcon.swift in Sources */, DD4A911E2708C65400501B7E /* AppSettings.swift in Sources */, DDAF8C6226ED0A230058C060 /* mqtt.pb.swift in Sources */, @@ -546,6 +545,7 @@ DDAF8C5D26ED09490058C060 /* portnums.pb.swift in Sources */, DD9D8F2F2764403B00080993 /* Meshtastic.xcdatamodeld in Sources */, DD1BF2F92776FE2E008C8D2F /* UserMessageList.swift in Sources */, + DDB2CC6E27F3EB47009C5FCC /* telemetry.pb.swift in Sources */, DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */, C9A7BC1027759A9600760B50 /* PositionAnnotationView.swift in Sources */, DD882F5D2772E4640005BF05 /* Contacts.swift in Sources */, diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 1e611a16..551f9220 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -547,7 +547,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph position.longitudeI = decodedInfo.nodeInfo.position.longitudeI position.altitude = decodedInfo.nodeInfo.position.altitude - position.batteryLevel = decodedInfo.nodeInfo.position.batteryLevel if decodedInfo.nodeInfo.position.time > 0 { position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time))) @@ -614,7 +613,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph position.latitudeI = decodedInfo.nodeInfo.position.latitudeI position.longitudeI = decodedInfo.nodeInfo.position.longitudeI position.altitude = decodedInfo.nodeInfo.position.altitude - position.batteryLevel = decodedInfo.nodeInfo.position.batteryLevel + if decodedInfo.nodeInfo.position.time > 0 { position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time))) @@ -706,7 +705,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } newMessage.receivedACK = false newMessage.direction = "IN" - newMessage.isTapback = decodedInfo.packet.decoded.isTapback + newMessage.isTapback = decodedInfo.packet.decoded.emoji == 1 if decodedInfo.packet.decoded.replyID > 0 { @@ -843,7 +842,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph position.latitudeI = positionMessage.latitudeI position.longitudeI = positionMessage.longitudeI position.altitude = positionMessage.altitude - position.batteryLevel = positionMessage.batteryLevel if positionMessage.time == 0 { @@ -969,10 +967,10 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } } - } else if decodedInfo.packet.decoded.portnum == PortNum.environmentalMeasurementApp { + } else if decodedInfo.packet.decoded.portnum == PortNum.telemetryApp { - if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Environmental Measurement App UNHANDLED \(try decodedInfo.packet.jsonString())") } - print("ℹ️ MESH PACKET received for Environmental Measurement App UNHANDLED \(try decodedInfo.packet.jsonString())") + if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Telemetry App UNHANDLED \(try decodedInfo.packet.jsonString())") } + print("ℹ️ MESH PACKET received for Telemetry App UNHANDLED \(try decodedInfo.packet.jsonString())") } else if decodedInfo.packet.decoded.portnum == PortNum.storeForwardApp { @@ -1095,7 +1093,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph meshPacket.to = UInt32(toUserNum) meshPacket.from = UInt32(fromUserNum) meshPacket.decoded = dataMessage - meshPacket.decoded.isTapback = isTapback + meshPacket.decoded.emoji = isTapback ? 1 : 0 if replyID > 0 { meshPacket.decoded.replyID = UInt32(replyID) } @@ -1162,8 +1160,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph positionPacket.longitudeI = Int32(LocationHelper.currentLocation.longitude * 1e7) positionPacket.time = UInt32(Date().timeIntervalSince1970) positionPacket.altitude = Int32(LocationHelper.currentAltitude) - let mostRecentPosition = fetchedNode[0].positions?.lastObject as! PositionEntity - positionPacket.batteryLevel = mostRecentPosition.batteryLevel var meshPacket = MeshPacket() meshPacket.to = UInt32(destNum) diff --git a/MeshtasticClient/Protobufs/admin.pb.swift b/MeshtasticClient/Protobufs/admin.pb.swift index 62641e41..8bcd5fa1 100644 --- a/MeshtasticClient/Protobufs/admin.pb.swift +++ b/MeshtasticClient/Protobufs/admin.pb.swift @@ -21,7 +21,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP } /// -/// This message is handled by the Admin plugin and is responsible for all settings/channel read/write operations. +/// This message is handled by the Admin module and is responsible for all settings/channel read/write operations. /// This message is used to do settings operations to both remote AND local nodes. /// (Prior to 1.2 these operations were done via special ToRadio operations) struct AdminMessage { @@ -29,6 +29,8 @@ struct AdminMessage { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// TODO: REPLACE var variant: AdminMessage.OneOf_Variant? = nil /// @@ -75,6 +77,8 @@ struct AdminMessage { set {variant = .getRadioRequest(newValue)} } + /// + /// TODO: REPLACE var getRadioResponse: RadioConfig { get { if case .getRadioResponse(let v)? = variant {return v} @@ -94,6 +98,8 @@ struct AdminMessage { set {variant = .getChannelRequest(newValue)} } + /// + /// TODO: REPLACE var getChannelResponse: Channel { get { if case .getChannelResponse(let v)? = variant {return v} @@ -112,6 +118,8 @@ struct AdminMessage { set {variant = .getOwnerRequest(newValue)} } + /// + /// TODO: REPLACE var getOwnerResponse: User { get { if case .getOwnerResponse(let v)? = variant {return v} @@ -133,6 +141,8 @@ struct AdminMessage { set {variant = .confirmSetChannel(newValue)} } + /// + /// TODO: REPLACE var confirmSetRadio: Bool { get { if case .confirmSetRadio(let v)? = variant {return v} @@ -163,143 +173,123 @@ struct AdminMessage { } /// - /// Get the Canned Message Plugin message part1 in the response to this message. - var getCannedMessagePluginPart1Request: Bool { + /// Get the Canned Message Module message part1 in the response to this message. + var getCannedMessageModulePart1Request: Bool { get { - if case .getCannedMessagePluginPart1Request(let v)? = variant {return v} + if case .getCannedMessageModulePart1Request(let v)? = variant {return v} return false } - set {variant = .getCannedMessagePluginPart1Request(newValue)} - } - - var getCannedMessagePluginPart1Response: CannedMessagePluginMessagePart1 { - get { - if case .getCannedMessagePluginPart1Response(let v)? = variant {return v} - return CannedMessagePluginMessagePart1() - } - set {variant = .getCannedMessagePluginPart1Response(newValue)} + set {variant = .getCannedMessageModulePart1Request(newValue)} } /// - /// Get the Canned Message Plugin message part2 in the response to this message. - var getCannedMessagePluginPart2Request: Bool { + /// TODO: REPLACE + var getCannedMessageModulePart1Response: String { get { - if case .getCannedMessagePluginPart2Request(let v)? = variant {return v} + if case .getCannedMessageModulePart1Response(let v)? = variant {return v} + return String() + } + set {variant = .getCannedMessageModulePart1Response(newValue)} + } + + /// + /// Get the Canned Message Module message part2 in the response to this message. + var getCannedMessageModulePart2Request: Bool { + get { + if case .getCannedMessageModulePart2Request(let v)? = variant {return v} return false } - set {variant = .getCannedMessagePluginPart2Request(newValue)} - } - - var getCannedMessagePluginPart2Response: CannedMessagePluginMessagePart2 { - get { - if case .getCannedMessagePluginPart2Response(let v)? = variant {return v} - return CannedMessagePluginMessagePart2() - } - set {variant = .getCannedMessagePluginPart2Response(newValue)} + set {variant = .getCannedMessageModulePart2Request(newValue)} } /// - /// Get the Canned Message Plugin message part3 in the response to this message. - var getCannedMessagePluginPart3Request: Bool { + /// TODO: REPLACE + var getCannedMessageModulePart2Response: String { get { - if case .getCannedMessagePluginPart3Request(let v)? = variant {return v} + if case .getCannedMessageModulePart2Response(let v)? = variant {return v} + return String() + } + set {variant = .getCannedMessageModulePart2Response(newValue)} + } + + /// + /// Get the Canned Message Module message part3 in the response to this message. + var getCannedMessageModulePart3Request: Bool { + get { + if case .getCannedMessageModulePart3Request(let v)? = variant {return v} return false } - set {variant = .getCannedMessagePluginPart3Request(newValue)} - } - - var getCannedMessagePluginPart3Response: CannedMessagePluginMessagePart3 { - get { - if case .getCannedMessagePluginPart3Response(let v)? = variant {return v} - return CannedMessagePluginMessagePart3() - } - set {variant = .getCannedMessagePluginPart3Response(newValue)} + set {variant = .getCannedMessageModulePart3Request(newValue)} } /// - /// Get the Canned Message Plugin message part4 in the response to this message. - var getCannedMessagePluginPart4Request: Bool { + /// TODO: REPLACE + var getCannedMessageModulePart3Response: String { get { - if case .getCannedMessagePluginPart4Request(let v)? = variant {return v} + if case .getCannedMessageModulePart3Response(let v)? = variant {return v} + return String() + } + set {variant = .getCannedMessageModulePart3Response(newValue)} + } + + /// + /// Get the Canned Message Module message part4 in the response to this message. + var getCannedMessageModulePart4Request: Bool { + get { + if case .getCannedMessageModulePart4Request(let v)? = variant {return v} return false } - set {variant = .getCannedMessagePluginPart4Request(newValue)} - } - - var getCannedMessagePluginPart4Response: CannedMessagePluginMessagePart4 { - get { - if case .getCannedMessagePluginPart4Response(let v)? = variant {return v} - return CannedMessagePluginMessagePart4() - } - set {variant = .getCannedMessagePluginPart4Response(newValue)} + set {variant = .getCannedMessageModulePart4Request(newValue)} } /// - /// Get the Canned Message Plugin message part5 in the response to this message. - var getCannedMessagePluginPart5Request: Bool { + /// TODO: REPLACE + var getCannedMessageModulePart4Response: String { get { - if case .getCannedMessagePluginPart5Request(let v)? = variant {return v} - return false + if case .getCannedMessageModulePart4Response(let v)? = variant {return v} + return String() } - set {variant = .getCannedMessagePluginPart5Request(newValue)} - } - - var getCannedMessagePluginPart5Response: CannedMessagePluginMessagePart5 { - get { - if case .getCannedMessagePluginPart5Response(let v)? = variant {return v} - return CannedMessagePluginMessagePart5() - } - set {variant = .getCannedMessagePluginPart5Response(newValue)} + set {variant = .getCannedMessageModulePart4Response(newValue)} } /// - /// Set the canned message plugin part 1 text. - var setCannedMessagePluginPart1: CannedMessagePluginMessagePart1 { + /// Set the canned message module part 1 text. + var setCannedMessageModulePart1: String { get { - if case .setCannedMessagePluginPart1(let v)? = variant {return v} - return CannedMessagePluginMessagePart1() + if case .setCannedMessageModulePart1(let v)? = variant {return v} + return String() } - set {variant = .setCannedMessagePluginPart1(newValue)} + set {variant = .setCannedMessageModulePart1(newValue)} } /// - /// Set the canned message plugin part 2 text. - var setCannedMessagePluginPart2: CannedMessagePluginMessagePart2 { + /// Set the canned message module part 2 text. + var setCannedMessageModulePart2: String { get { - if case .setCannedMessagePluginPart2(let v)? = variant {return v} - return CannedMessagePluginMessagePart2() + if case .setCannedMessageModulePart2(let v)? = variant {return v} + return String() } - set {variant = .setCannedMessagePluginPart2(newValue)} + set {variant = .setCannedMessageModulePart2(newValue)} } /// - /// Set the canned message plugin part 3 text. - var setCannedMessagePluginPart3: CannedMessagePluginMessagePart3 { + /// Set the canned message module part 3 text. + var setCannedMessageModulePart3: String { get { - if case .setCannedMessagePluginPart3(let v)? = variant {return v} - return CannedMessagePluginMessagePart3() + if case .setCannedMessageModulePart3(let v)? = variant {return v} + return String() } - set {variant = .setCannedMessagePluginPart3(newValue)} + set {variant = .setCannedMessageModulePart3(newValue)} } /// - /// Set the canned message plugin part 4 text. - var setCannedMessagePluginPart4: CannedMessagePluginMessagePart4 { + /// Set the canned message module part 4 text. + var setCannedMessageModulePart4: String { get { - if case .setCannedMessagePluginPart4(let v)? = variant {return v} - return CannedMessagePluginMessagePart4() + if case .setCannedMessageModulePart4(let v)? = variant {return v} + return String() } - set {variant = .setCannedMessagePluginPart4(newValue)} - } - - /// - /// Set the canned message plugin part 5 text. - var setCannedMessagePluginPart5: CannedMessagePluginMessagePart5 { - get { - if case .setCannedMessagePluginPart5(let v)? = variant {return v} - return CannedMessagePluginMessagePart5() - } - set {variant = .setCannedMessagePluginPart5(newValue)} + set {variant = .setCannedMessageModulePart4(newValue)} } /// @@ -314,6 +304,8 @@ struct AdminMessage { var unknownFields = SwiftProtobuf.UnknownStorage() + /// + /// TODO: REPLACE enum OneOf_Variant: Equatable { /// /// Set the radio provisioning for this node @@ -331,15 +323,21 @@ struct AdminMessage { /// /// Send the current RadioConfig in the response to this message. case getRadioRequest(Bool) + /// + /// TODO: REPLACE case getRadioResponse(RadioConfig) /// /// 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) + /// + /// TODO: REPLACE case getChannelResponse(Channel) /// /// Send the current owner data in the response to this message. case getOwnerRequest(Bool) + /// + /// TODO: REPLACE 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. @@ -347,6 +345,8 @@ struct AdminMessage { /// If you fail to do so, the radio will assume loss of comms and revert your changes. /// These messages are optional when changing the local node. case confirmSetChannel(Bool) + /// + /// TODO: REPLACE case confirmSetRadio(Bool) /// /// This message is only supported for the simulator porduino build. @@ -356,40 +356,41 @@ struct AdminMessage { /// Tell the node to reboot in this many seconds (or <0 to cancel reboot) case rebootSeconds(Int32) /// - /// Get the Canned Message Plugin message part1 in the response to this message. - case getCannedMessagePluginPart1Request(Bool) - case getCannedMessagePluginPart1Response(CannedMessagePluginMessagePart1) + /// Get the Canned Message Module message part1 in the response to this message. + case getCannedMessageModulePart1Request(Bool) /// - /// Get the Canned Message Plugin message part2 in the response to this message. - case getCannedMessagePluginPart2Request(Bool) - case getCannedMessagePluginPart2Response(CannedMessagePluginMessagePart2) + /// TODO: REPLACE + case getCannedMessageModulePart1Response(String) /// - /// Get the Canned Message Plugin message part3 in the response to this message. - case getCannedMessagePluginPart3Request(Bool) - case getCannedMessagePluginPart3Response(CannedMessagePluginMessagePart3) + /// Get the Canned Message Module message part2 in the response to this message. + case getCannedMessageModulePart2Request(Bool) /// - /// Get the Canned Message Plugin message part4 in the response to this message. - case getCannedMessagePluginPart4Request(Bool) - case getCannedMessagePluginPart4Response(CannedMessagePluginMessagePart4) + /// TODO: REPLACE + case getCannedMessageModulePart2Response(String) /// - /// Get the Canned Message Plugin message part5 in the response to this message. - case getCannedMessagePluginPart5Request(Bool) - case getCannedMessagePluginPart5Response(CannedMessagePluginMessagePart5) + /// Get the Canned Message Module message part3 in the response to this message. + case getCannedMessageModulePart3Request(Bool) /// - /// Set the canned message plugin part 1 text. - case setCannedMessagePluginPart1(CannedMessagePluginMessagePart1) + /// TODO: REPLACE + case getCannedMessageModulePart3Response(String) /// - /// Set the canned message plugin part 2 text. - case setCannedMessagePluginPart2(CannedMessagePluginMessagePart2) + /// Get the Canned Message Module message part4 in the response to this message. + case getCannedMessageModulePart4Request(Bool) /// - /// Set the canned message plugin part 3 text. - case setCannedMessagePluginPart3(CannedMessagePluginMessagePart3) + /// TODO: REPLACE + case getCannedMessageModulePart4Response(String) /// - /// Set the canned message plugin part 4 text. - case setCannedMessagePluginPart4(CannedMessagePluginMessagePart4) + /// Set the canned message module part 1 text. + case setCannedMessageModulePart1(String) /// - /// Set the canned message plugin part 5 text. - case setCannedMessagePluginPart5(CannedMessagePluginMessagePart5) + /// Set the canned message module part 2 text. + case setCannedMessageModulePart2(String) + /// + /// Set the canned message module part 3 text. + case setCannedMessageModulePart3(String) + /// + /// Set the canned message module part 4 text. + case setCannedMessageModulePart4(String) /// /// Tell the node to shutdown in this many seconds (or <0 to cancel shutdown) case shutdownSeconds(Int32) @@ -452,64 +453,52 @@ struct AdminMessage { guard case .rebootSeconds(let l) = lhs, case .rebootSeconds(let r) = rhs else { preconditionFailure() } return l == r }() - case (.getCannedMessagePluginPart1Request, .getCannedMessagePluginPart1Request): return { - guard case .getCannedMessagePluginPart1Request(let l) = lhs, case .getCannedMessagePluginPart1Request(let r) = rhs else { preconditionFailure() } + case (.getCannedMessageModulePart1Request, .getCannedMessageModulePart1Request): return { + guard case .getCannedMessageModulePart1Request(let l) = lhs, case .getCannedMessageModulePart1Request(let r) = rhs else { preconditionFailure() } return l == r }() - case (.getCannedMessagePluginPart1Response, .getCannedMessagePluginPart1Response): return { - guard case .getCannedMessagePluginPart1Response(let l) = lhs, case .getCannedMessagePluginPart1Response(let r) = rhs else { preconditionFailure() } + case (.getCannedMessageModulePart1Response, .getCannedMessageModulePart1Response): return { + guard case .getCannedMessageModulePart1Response(let l) = lhs, case .getCannedMessageModulePart1Response(let r) = rhs else { preconditionFailure() } return l == r }() - case (.getCannedMessagePluginPart2Request, .getCannedMessagePluginPart2Request): return { - guard case .getCannedMessagePluginPart2Request(let l) = lhs, case .getCannedMessagePluginPart2Request(let r) = rhs else { preconditionFailure() } + case (.getCannedMessageModulePart2Request, .getCannedMessageModulePart2Request): return { + guard case .getCannedMessageModulePart2Request(let l) = lhs, case .getCannedMessageModulePart2Request(let r) = rhs else { preconditionFailure() } return l == r }() - case (.getCannedMessagePluginPart2Response, .getCannedMessagePluginPart2Response): return { - guard case .getCannedMessagePluginPart2Response(let l) = lhs, case .getCannedMessagePluginPart2Response(let r) = rhs else { preconditionFailure() } + case (.getCannedMessageModulePart2Response, .getCannedMessageModulePart2Response): return { + guard case .getCannedMessageModulePart2Response(let l) = lhs, case .getCannedMessageModulePart2Response(let r) = rhs else { preconditionFailure() } return l == r }() - case (.getCannedMessagePluginPart3Request, .getCannedMessagePluginPart3Request): return { - guard case .getCannedMessagePluginPart3Request(let l) = lhs, case .getCannedMessagePluginPart3Request(let r) = rhs else { preconditionFailure() } + case (.getCannedMessageModulePart3Request, .getCannedMessageModulePart3Request): return { + guard case .getCannedMessageModulePart3Request(let l) = lhs, case .getCannedMessageModulePart3Request(let r) = rhs else { preconditionFailure() } return l == r }() - case (.getCannedMessagePluginPart3Response, .getCannedMessagePluginPart3Response): return { - guard case .getCannedMessagePluginPart3Response(let l) = lhs, case .getCannedMessagePluginPart3Response(let r) = rhs else { preconditionFailure() } + case (.getCannedMessageModulePart3Response, .getCannedMessageModulePart3Response): return { + guard case .getCannedMessageModulePart3Response(let l) = lhs, case .getCannedMessageModulePart3Response(let r) = rhs else { preconditionFailure() } return l == r }() - case (.getCannedMessagePluginPart4Request, .getCannedMessagePluginPart4Request): return { - guard case .getCannedMessagePluginPart4Request(let l) = lhs, case .getCannedMessagePluginPart4Request(let r) = rhs else { preconditionFailure() } + case (.getCannedMessageModulePart4Request, .getCannedMessageModulePart4Request): return { + guard case .getCannedMessageModulePart4Request(let l) = lhs, case .getCannedMessageModulePart4Request(let r) = rhs else { preconditionFailure() } return l == r }() - case (.getCannedMessagePluginPart4Response, .getCannedMessagePluginPart4Response): return { - guard case .getCannedMessagePluginPart4Response(let l) = lhs, case .getCannedMessagePluginPart4Response(let r) = rhs else { preconditionFailure() } + case (.getCannedMessageModulePart4Response, .getCannedMessageModulePart4Response): return { + guard case .getCannedMessageModulePart4Response(let l) = lhs, case .getCannedMessageModulePart4Response(let r) = rhs else { preconditionFailure() } return l == r }() - case (.getCannedMessagePluginPart5Request, .getCannedMessagePluginPart5Request): return { - guard case .getCannedMessagePluginPart5Request(let l) = lhs, case .getCannedMessagePluginPart5Request(let r) = rhs else { preconditionFailure() } + case (.setCannedMessageModulePart1, .setCannedMessageModulePart1): return { + guard case .setCannedMessageModulePart1(let l) = lhs, case .setCannedMessageModulePart1(let r) = rhs else { preconditionFailure() } return l == r }() - case (.getCannedMessagePluginPart5Response, .getCannedMessagePluginPart5Response): return { - guard case .getCannedMessagePluginPart5Response(let l) = lhs, case .getCannedMessagePluginPart5Response(let r) = rhs else { preconditionFailure() } + case (.setCannedMessageModulePart2, .setCannedMessageModulePart2): return { + guard case .setCannedMessageModulePart2(let l) = lhs, case .setCannedMessageModulePart2(let r) = rhs else { preconditionFailure() } return l == r }() - case (.setCannedMessagePluginPart1, .setCannedMessagePluginPart1): return { - guard case .setCannedMessagePluginPart1(let l) = lhs, case .setCannedMessagePluginPart1(let r) = rhs else { preconditionFailure() } + case (.setCannedMessageModulePart3, .setCannedMessageModulePart3): return { + guard case .setCannedMessageModulePart3(let l) = lhs, case .setCannedMessageModulePart3(let r) = rhs else { preconditionFailure() } return l == r }() - case (.setCannedMessagePluginPart2, .setCannedMessagePluginPart2): return { - guard case .setCannedMessagePluginPart2(let l) = lhs, case .setCannedMessagePluginPart2(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setCannedMessagePluginPart3, .setCannedMessagePluginPart3): return { - guard case .setCannedMessagePluginPart3(let l) = lhs, case .setCannedMessagePluginPart3(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setCannedMessagePluginPart4, .setCannedMessagePluginPart4): return { - guard case .setCannedMessagePluginPart4(let l) = lhs, case .setCannedMessagePluginPart4(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setCannedMessagePluginPart5, .setCannedMessagePluginPart5): return { - guard case .setCannedMessagePluginPart5(let l) = lhs, case .setCannedMessagePluginPart5(let r) = rhs else { preconditionFailure() } + case (.setCannedMessageModulePart4, .setCannedMessageModulePart4): return { + guard case .setCannedMessageModulePart4(let l) = lhs, case .setCannedMessageModulePart4(let r) = rhs else { preconditionFailure() } return l == r }() case (.shutdownSeconds, .shutdownSeconds): return { @@ -525,6 +514,11 @@ struct AdminMessage { init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension AdminMessage: @unchecked Sendable {} +extension AdminMessage.OneOf_Variant: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { @@ -543,21 +537,18 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat 33: .standard(proto: "confirm_set_radio"), 34: .standard(proto: "exit_simulator"), 35: .standard(proto: "reboot_seconds"), - 36: .standard(proto: "get_canned_message_plugin_part1_request"), - 37: .standard(proto: "get_canned_message_plugin_part1_response"), - 38: .standard(proto: "get_canned_message_plugin_part2_request"), - 39: .standard(proto: "get_canned_message_plugin_part2_response"), - 40: .standard(proto: "get_canned_message_plugin_part3_request"), - 41: .standard(proto: "get_canned_message_plugin_part3_response"), - 42: .standard(proto: "get_canned_message_plugin_part4_request"), - 43: .standard(proto: "get_canned_message_plugin_part4_response"), - 44: .standard(proto: "get_canned_message_plugin_part5_request"), - 45: .standard(proto: "get_canned_message_plugin_part5_response"), - 46: .standard(proto: "set_canned_message_plugin_part1"), - 47: .standard(proto: "set_canned_message_plugin_part2"), - 48: .standard(proto: "set_canned_message_plugin_part3"), - 49: .standard(proto: "set_canned_message_plugin_part4"), - 50: .standard(proto: "set_canned_message_plugin_part5"), + 36: .standard(proto: "get_canned_message_module_part1_request"), + 37: .standard(proto: "get_canned_message_module_part1_response"), + 38: .standard(proto: "get_canned_message_module_part2_request"), + 39: .standard(proto: "get_canned_message_module_part2_response"), + 40: .standard(proto: "get_canned_message_module_part3_request"), + 41: .standard(proto: "get_canned_message_module_part3_response"), + 42: .standard(proto: "get_canned_message_module_part4_request"), + 43: .standard(proto: "get_canned_message_module_part4_response"), + 44: .standard(proto: "set_canned_message_module_part1"), + 45: .standard(proto: "set_canned_message_module_part2"), + 46: .standard(proto: "set_canned_message_module_part3"), + 47: .standard(proto: "set_canned_message_module_part4"), 51: .standard(proto: "shutdown_seconds"), ] @@ -706,20 +697,15 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat try decoder.decodeSingularBoolField(value: &v) if let v = v { if self.variant != nil {try decoder.handleConflictingOneOf()} - self.variant = .getCannedMessagePluginPart1Request(v) + self.variant = .getCannedMessageModulePart1Request(v) } }() case 37: try { - var v: CannedMessagePluginMessagePart1? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .getCannedMessagePluginPart1Response(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) + var v: String? + try decoder.decodeSingularStringField(value: &v) if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .getCannedMessagePluginPart1Response(v) + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessageModulePart1Response(v) } }() case 38: try { @@ -727,20 +713,15 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat try decoder.decodeSingularBoolField(value: &v) if let v = v { if self.variant != nil {try decoder.handleConflictingOneOf()} - self.variant = .getCannedMessagePluginPart2Request(v) + self.variant = .getCannedMessageModulePart2Request(v) } }() case 39: try { - var v: CannedMessagePluginMessagePart2? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .getCannedMessagePluginPart2Response(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) + var v: String? + try decoder.decodeSingularStringField(value: &v) if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .getCannedMessagePluginPart2Response(v) + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessageModulePart2Response(v) } }() case 40: try { @@ -748,20 +729,15 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat try decoder.decodeSingularBoolField(value: &v) if let v = v { if self.variant != nil {try decoder.handleConflictingOneOf()} - self.variant = .getCannedMessagePluginPart3Request(v) + self.variant = .getCannedMessageModulePart3Request(v) } }() case 41: try { - var v: CannedMessagePluginMessagePart3? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .getCannedMessagePluginPart3Response(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) + var v: String? + try decoder.decodeSingularStringField(value: &v) if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .getCannedMessagePluginPart3Response(v) + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessageModulePart3Response(v) } }() case 42: try { @@ -769,106 +745,47 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat try decoder.decodeSingularBoolField(value: &v) if let v = v { if self.variant != nil {try decoder.handleConflictingOneOf()} - self.variant = .getCannedMessagePluginPart4Request(v) + self.variant = .getCannedMessageModulePart4Request(v) } }() case 43: try { - var v: CannedMessagePluginMessagePart4? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .getCannedMessagePluginPart4Response(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) + var v: String? + try decoder.decodeSingularStringField(value: &v) if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .getCannedMessagePluginPart4Response(v) + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessageModulePart4Response(v) } }() case 44: try { - var v: Bool? - try decoder.decodeSingularBoolField(value: &v) + var v: String? + try decoder.decodeSingularStringField(value: &v) if let v = v { if self.variant != nil {try decoder.handleConflictingOneOf()} - self.variant = .getCannedMessagePluginPart5Request(v) + self.variant = .setCannedMessageModulePart1(v) } }() case 45: try { - var v: CannedMessagePluginMessagePart5? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .getCannedMessagePluginPart5Response(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) + var v: String? + try decoder.decodeSingularStringField(value: &v) if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .getCannedMessagePluginPart5Response(v) + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .setCannedMessageModulePart2(v) } }() case 46: try { - var v: CannedMessagePluginMessagePart1? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .setCannedMessagePluginPart1(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) + var v: String? + try decoder.decodeSingularStringField(value: &v) if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .setCannedMessagePluginPart1(v) + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .setCannedMessageModulePart3(v) } }() case 47: try { - var v: CannedMessagePluginMessagePart2? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .setCannedMessagePluginPart2(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) + var v: String? + try decoder.decodeSingularStringField(value: &v) if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .setCannedMessagePluginPart2(v) - } - }() - case 48: try { - var v: CannedMessagePluginMessagePart3? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .setCannedMessagePluginPart3(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .setCannedMessagePluginPart3(v) - } - }() - case 49: try { - var v: CannedMessagePluginMessagePart4? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .setCannedMessagePluginPart4(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .setCannedMessagePluginPart4(v) - } - }() - case 50: try { - var v: CannedMessagePluginMessagePart5? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .setCannedMessagePluginPart5(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .setCannedMessagePluginPart5(v) + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .setCannedMessageModulePart4(v) } }() case 51: try { @@ -886,8 +803,9 @@ 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 case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 + // 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 switch self.variant { case .setRadio?: try { guard case .setRadio(let v)? = self.variant else { preconditionFailure() } @@ -941,65 +859,53 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat guard case .rebootSeconds(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularInt32Field(value: v, fieldNumber: 35) }() - case .getCannedMessagePluginPart1Request?: try { - guard case .getCannedMessagePluginPart1Request(let v)? = self.variant else { preconditionFailure() } + case .getCannedMessageModulePart1Request?: try { + guard case .getCannedMessageModulePart1Request(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularBoolField(value: v, fieldNumber: 36) }() - case .getCannedMessagePluginPart1Response?: try { - guard case .getCannedMessagePluginPart1Response(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 37) + case .getCannedMessageModulePart1Response?: try { + guard case .getCannedMessageModulePart1Response(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 37) }() - case .getCannedMessagePluginPart2Request?: try { - guard case .getCannedMessagePluginPart2Request(let v)? = self.variant else { preconditionFailure() } + case .getCannedMessageModulePart2Request?: try { + guard case .getCannedMessageModulePart2Request(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularBoolField(value: v, fieldNumber: 38) }() - case .getCannedMessagePluginPart2Response?: try { - guard case .getCannedMessagePluginPart2Response(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 39) + case .getCannedMessageModulePart2Response?: try { + guard case .getCannedMessageModulePart2Response(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 39) }() - case .getCannedMessagePluginPart3Request?: try { - guard case .getCannedMessagePluginPart3Request(let v)? = self.variant else { preconditionFailure() } + case .getCannedMessageModulePart3Request?: try { + guard case .getCannedMessageModulePart3Request(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularBoolField(value: v, fieldNumber: 40) }() - case .getCannedMessagePluginPart3Response?: try { - guard case .getCannedMessagePluginPart3Response(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 41) + case .getCannedMessageModulePart3Response?: try { + guard case .getCannedMessageModulePart3Response(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 41) }() - case .getCannedMessagePluginPart4Request?: try { - guard case .getCannedMessagePluginPart4Request(let v)? = self.variant else { preconditionFailure() } + case .getCannedMessageModulePart4Request?: try { + guard case .getCannedMessageModulePart4Request(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularBoolField(value: v, fieldNumber: 42) }() - case .getCannedMessagePluginPart4Response?: try { - guard case .getCannedMessagePluginPart4Response(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 43) + case .getCannedMessageModulePart4Response?: try { + guard case .getCannedMessageModulePart4Response(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 43) }() - case .getCannedMessagePluginPart5Request?: try { - guard case .getCannedMessagePluginPart5Request(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularBoolField(value: v, fieldNumber: 44) + case .setCannedMessageModulePart1?: try { + guard case .setCannedMessageModulePart1(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 44) }() - case .getCannedMessagePluginPart5Response?: try { - guard case .getCannedMessagePluginPart5Response(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 45) + case .setCannedMessageModulePart2?: try { + guard case .setCannedMessageModulePart2(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 45) }() - case .setCannedMessagePluginPart1?: try { - guard case .setCannedMessagePluginPart1(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 46) + case .setCannedMessageModulePart3?: try { + guard case .setCannedMessageModulePart3(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 46) }() - case .setCannedMessagePluginPart2?: try { - guard case .setCannedMessagePluginPart2(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 47) - }() - case .setCannedMessagePluginPart3?: try { - guard case .setCannedMessagePluginPart3(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 48) - }() - case .setCannedMessagePluginPart4?: try { - guard case .setCannedMessagePluginPart4(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 49) - }() - case .setCannedMessagePluginPart5?: try { - guard case .setCannedMessagePluginPart5(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 50) + case .setCannedMessageModulePart4?: try { + guard case .setCannedMessageModulePart4(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 47) }() case .shutdownSeconds?: try { guard case .shutdownSeconds(let v)? = self.variant else { preconditionFailure() } diff --git a/MeshtasticClient/Protobufs/apponly.pb.swift b/MeshtasticClient/Protobufs/apponly.pb.swift index 5c3b13ed..687030b7 100644 --- a/MeshtasticClient/Protobufs/apponly.pb.swift +++ b/MeshtasticClient/Protobufs/apponly.pb.swift @@ -31,6 +31,8 @@ struct ChannelSet { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// TODO: REPLACE var settings: [ChannelSettings] = [] var unknownFields = SwiftProtobuf.UnknownStorage() @@ -38,6 +40,10 @@ struct ChannelSet { init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension ChannelSet: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. extension ChannelSet: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { diff --git a/MeshtasticClient/Protobufs/cannedmessages.pb.swift b/MeshtasticClient/Protobufs/cannedmessages.pb.swift index 9b6068b8..dc943c33 100644 --- a/MeshtasticClient/Protobufs/cannedmessages.pb.swift +++ b/MeshtasticClient/Protobufs/cannedmessages.pb.swift @@ -40,96 +40,46 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP } /// -/// Canned message plugin part 1 -struct CannedMessagePluginMessagePart1 { +/// Canned message module configuration. +struct CannedMessageModuleConfig { // 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. /// - /// Predefined messages for canned message plugin separated by '|' characters. - /// This is part 1. - var text: String = String() + /// Predefined messages for canned message module separated by '|' characters. + var messagesPart1: String = String() + + /// + /// TODO: REPLACE + var messagesPart2: String = String() + + /// + /// TODO: REPLACE + var messagesPart3: String = String() + + /// + /// TODO: REPLACE + var messagesPart4: String = String() var unknownFields = SwiftProtobuf.UnknownStorage() init() {} } -/// -/// Canned message plugin part 2 -struct CannedMessagePluginMessagePart2 { - // 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. - - /// - /// Predefined messages for canned message plugin separated by '|' characters. - /// This is part 2. - var text: String = String() - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} - -/// -/// Canned message plugin part 3 -struct CannedMessagePluginMessagePart3 { - // 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. - - /// - /// Predefined messages for canned message plugin separated by '|' characters. - /// This is part 3. - var text: String = String() - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} - -/// -/// Canned message plugin part 4 -struct CannedMessagePluginMessagePart4 { - // 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. - - /// - /// Predefined messages for canned message plugin separated by '|' characters. - /// This is part 4. - var text: String = String() - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} - -/// -/// Canned message plugin part 5 -struct CannedMessagePluginMessagePart5 { - // 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. - - /// - /// Predefined messages for canned message plugin separated by '|' characters. - /// This is part 5. - var text: String = String() - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} +#if swift(>=5.5) && canImport(_Concurrency) +extension CannedMessageModuleConfig: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) // MARK: - Code below here is support for the SwiftProtobuf runtime. -extension CannedMessagePluginMessagePart1: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = "CannedMessagePluginMessagePart1" +extension CannedMessageModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = "CannedMessageModuleConfig" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "text"), + 11: .same(proto: "messagesPart1"), + 12: .same(proto: "messagesPart2"), + 13: .same(proto: "messagesPart3"), + 14: .same(proto: "messagesPart4"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -138,149 +88,36 @@ extension CannedMessagePluginMessagePart1: SwiftProtobuf.Message, SwiftProtobuf. // 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.decodeSingularStringField(value: &self.text) }() + case 11: try { try decoder.decodeSingularStringField(value: &self.messagesPart1) }() + case 12: try { try decoder.decodeSingularStringField(value: &self.messagesPart2) }() + case 13: try { try decoder.decodeSingularStringField(value: &self.messagesPart3) }() + case 14: try { try decoder.decodeSingularStringField(value: &self.messagesPart4) }() default: break } } } func traverse(visitor: inout V) throws { - if !self.text.isEmpty { - try visitor.visitSingularStringField(value: self.text, fieldNumber: 1) + if !self.messagesPart1.isEmpty { + try visitor.visitSingularStringField(value: self.messagesPart1, fieldNumber: 11) + } + if !self.messagesPart2.isEmpty { + try visitor.visitSingularStringField(value: self.messagesPart2, fieldNumber: 12) + } + if !self.messagesPart3.isEmpty { + try visitor.visitSingularStringField(value: self.messagesPart3, fieldNumber: 13) + } + if !self.messagesPart4.isEmpty { + try visitor.visitSingularStringField(value: self.messagesPart4, fieldNumber: 14) } try unknownFields.traverse(visitor: &visitor) } - static func ==(lhs: CannedMessagePluginMessagePart1, rhs: CannedMessagePluginMessagePart1) -> Bool { - if lhs.text != rhs.text {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension CannedMessagePluginMessagePart2: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = "CannedMessagePluginMessagePart2" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "text"), - ] - - 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.decodeSingularStringField(value: &self.text) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if !self.text.isEmpty { - try visitor.visitSingularStringField(value: self.text, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: CannedMessagePluginMessagePart2, rhs: CannedMessagePluginMessagePart2) -> Bool { - if lhs.text != rhs.text {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension CannedMessagePluginMessagePart3: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = "CannedMessagePluginMessagePart3" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "text"), - ] - - 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.decodeSingularStringField(value: &self.text) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if !self.text.isEmpty { - try visitor.visitSingularStringField(value: self.text, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: CannedMessagePluginMessagePart3, rhs: CannedMessagePluginMessagePart3) -> Bool { - if lhs.text != rhs.text {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension CannedMessagePluginMessagePart4: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = "CannedMessagePluginMessagePart4" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "text"), - ] - - 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.decodeSingularStringField(value: &self.text) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if !self.text.isEmpty { - try visitor.visitSingularStringField(value: self.text, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: CannedMessagePluginMessagePart4, rhs: CannedMessagePluginMessagePart4) -> Bool { - if lhs.text != rhs.text {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension CannedMessagePluginMessagePart5: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = "CannedMessagePluginMessagePart5" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "text"), - ] - - 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.decodeSingularStringField(value: &self.text) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if !self.text.isEmpty { - try visitor.visitSingularStringField(value: self.text, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: CannedMessagePluginMessagePart5, rhs: CannedMessagePluginMessagePart5) -> Bool { - if lhs.text != rhs.text {return false} + static func ==(lhs: CannedMessageModuleConfig, rhs: CannedMessageModuleConfig) -> Bool { + if lhs.messagesPart1 != rhs.messagesPart1 {return false} + if lhs.messagesPart2 != rhs.messagesPart2 {return false} + if lhs.messagesPart3 != rhs.messagesPart3 {return false} + if lhs.messagesPart4 != rhs.messagesPart4 {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/MeshtasticClient/Protobufs/channel.pb.swift b/MeshtasticClient/Protobufs/channel.pb.swift index 81b35faf..187de7b2 100644 --- a/MeshtasticClient/Protobufs/channel.pb.swift +++ b/MeshtasticClient/Protobufs/channel.pb.swift @@ -79,7 +79,7 @@ struct ChannelSettings { /// Because protobufs take ZERO space when the value is zero this works out nicely. /// This value is replaced by bandwidth/spread_factor/coding_rate. /// If you'd like to experiment with other options add them to MeshRadio.cpp in the device code. - var modemConfig: ChannelSettings.ModemConfig = .bw125Cr45Sf128 + var modemConfig: ChannelSettings.ModemConfig = .vlongSlow /// /// Bandwidth in MHz @@ -173,60 +173,60 @@ struct ChannelSettings { typealias RawValue = Int /// - /// < Bw = 125 kHz, Cr = 4/5, Sf(7) = 128chips/symbol, CRC - /// < on. ShortSlow | Short Range / Slow (5.469 kbps) - case bw125Cr45Sf128 // = 0 + /// TODO: REPLACE + case vlongSlow // = 0 /// - /// < Bw = 500 kHz, Cr = 4/5, Sf(7) = 128chips/symbol, CRC - /// < on. ShortFast | Short Range / Fast (21.875 kbps) - case bw500Cr45Sf128 // = 1 + /// TODO: REPLACE + case longSlow // = 1 /// - /// < Bw = 31.25 kHz, Cr = 4/8, Sf(9) = 512chips/symbol, - /// < CRC on. LongFast | Long Range / Fast (275 bps) - case bw3125Cr48Sf512 // = 2 + /// TODO: REPLACE + case longFast // = 2 /// - /// < Bw = 125 kHz, Cr = 4/8, Sf(12) = 4096chips/symbol, CRC - /// < on. LongSlow | Long Range / Slow (183 bps) - case bw125Cr48Sf4096 // = 3 + /// TODO: REPLACE + case midSlow // = 3 /// - /// < Bw = 250 kHz, Cr = 4/6, Sf(11) = 2048chips/symbol, CRC - /// < on. MediumSlow | Medium Range / Slow (895 bps) - case bw250Cr46Sf2048 // = 4 + /// TODO: REPLACE + case midFast // = 4 /// - /// < Bw = 250 kHz, Cr = 4/7, Sf(10) = 1024chips/symbol, CRC - /// < on. MediumFast | Medium Range / Fast (1400 bps) - case bw250Cr47Sf1024 // = 5 + /// TODO: REPLACE + case shortSlow // = 5 + + /// + /// TODO: REPLACE + case shortFast // = 6 case UNRECOGNIZED(Int) init() { - self = .bw125Cr45Sf128 + self = .vlongSlow } init?(rawValue: Int) { switch rawValue { - case 0: self = .bw125Cr45Sf128 - case 1: self = .bw500Cr45Sf128 - case 2: self = .bw3125Cr48Sf512 - case 3: self = .bw125Cr48Sf4096 - case 4: self = .bw250Cr46Sf2048 - case 5: self = .bw250Cr47Sf1024 + case 0: self = .vlongSlow + case 1: self = .longSlow + case 2: self = .longFast + case 3: self = .midSlow + case 4: self = .midFast + case 5: self = .shortSlow + case 6: self = .shortFast default: self = .UNRECOGNIZED(rawValue) } } var rawValue: Int { switch self { - case .bw125Cr45Sf128: return 0 - case .bw500Cr45Sf128: return 1 - case .bw3125Cr48Sf512: return 2 - case .bw125Cr48Sf4096: return 3 - case .bw250Cr46Sf2048: return 4 - case .bw250Cr47Sf1024: return 5 + case .vlongSlow: return 0 + case .longSlow: return 1 + case .longFast: return 2 + case .midSlow: return 3 + case .midFast: return 4 + case .shortSlow: return 5 + case .shortFast: return 6 case .UNRECOGNIZED(let i): return i } } @@ -241,12 +241,13 @@ struct ChannelSettings { extension ChannelSettings.ModemConfig: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. static var allCases: [ChannelSettings.ModemConfig] = [ - .bw125Cr45Sf128, - .bw500Cr45Sf128, - .bw3125Cr48Sf512, - .bw125Cr48Sf4096, - .bw250Cr46Sf2048, - .bw250Cr47Sf1024, + .vlongSlow, + .longSlow, + .longFast, + .midSlow, + .midFast, + .shortSlow, + .shortFast, ] } @@ -276,6 +277,8 @@ struct Channel { /// Clears the value of `settings`. Subsequent reads from it will return its default value. mutating func clearSettings() {self._settings = nil} + /// + /// TODO: REPLACE var role: Channel.Role = .disabled var unknownFields = SwiftProtobuf.UnknownStorage() @@ -351,6 +354,13 @@ extension Channel.Role: CaseIterable { #endif // swift(>=4.2) +#if swift(>=5.5) && canImport(_Concurrency) +extension ChannelSettings: @unchecked Sendable {} +extension ChannelSettings.ModemConfig: @unchecked Sendable {} +extension Channel: @unchecked Sendable {} +extension Channel.Role: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { @@ -395,7 +405,7 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen if self.txPower != 0 { try visitor.visitSingularInt32Field(value: self.txPower, fieldNumber: 1) } - if self.modemConfig != .bw125Cr45Sf128 { + if self.modemConfig != .vlongSlow { try visitor.visitSingularEnumField(value: self.modemConfig, fieldNumber: 3) } if !self.psk.isEmpty { @@ -447,12 +457,13 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen extension ChannelSettings.ModemConfig: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "Bw125Cr45Sf128"), - 1: .same(proto: "Bw500Cr45Sf128"), - 2: .same(proto: "Bw31_25Cr48Sf512"), - 3: .same(proto: "Bw125Cr48Sf4096"), - 4: .same(proto: "Bw250Cr46Sf2048"), - 5: .same(proto: "Bw250Cr47Sf1024"), + 0: .same(proto: "VLongSlow"), + 1: .same(proto: "LongSlow"), + 2: .same(proto: "LongFast"), + 3: .same(proto: "MidSlow"), + 4: .same(proto: "MidFast"), + 5: .same(proto: "ShortSlow"), + 6: .same(proto: "ShortFast"), ] } @@ -479,12 +490,16 @@ 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) } - if let v = self._settings { + try { if let v = self._settings { try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } + } }() if self.role != .disabled { try visitor.visitSingularEnumField(value: self.role, fieldNumber: 3) } diff --git a/MeshtasticClient/Protobufs/deviceonly.pb.swift b/MeshtasticClient/Protobufs/deviceonly.pb.swift index db92de38..9311b664 100644 --- a/MeshtasticClient/Protobufs/deviceonly.pb.swift +++ b/MeshtasticClient/Protobufs/deviceonly.pb.swift @@ -20,45 +20,6 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -/// -/// This is a stub version of the old 1.1 representation of RadioConfig. -/// But only keeping the region info. -/// The device firmware uses this stub while migrating old nodes to the new preferences system. -struct LegacyRadioConfig { - // 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 preferences: LegacyRadioConfig.LegacyPreferences { - get {return _preferences ?? LegacyRadioConfig.LegacyPreferences()} - set {_preferences = newValue} - } - /// Returns true if `preferences` has been explicitly set. - var hasPreferences: Bool {return self._preferences != nil} - /// Clears the value of `preferences`. Subsequent reads from it will return its default value. - mutating func clearPreferences() {self._preferences = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - struct LegacyPreferences { - // 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. - - /// - /// The region code for my radio (US, CN, EU433, etc...) - var region: RegionCode = .unset - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - } - - init() {} - - fileprivate var _preferences: LegacyRadioConfig.LegacyPreferences? = nil -} - /// /// This message is never sent over the wire, but it is used for serializing DB /// state to flash in the device code @@ -70,17 +31,6 @@ struct DeviceState { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. - /// - /// Moved to its own file, but we keep this here so we can automatically migrate old radio.region settings - var legacyRadio: LegacyRadioConfig { - get {return _storage._legacyRadio ?? LegacyRadioConfig()} - set {_uniqueStorage()._legacyRadio = newValue} - } - /// Returns true if `legacyRadio` has been explicitly set. - var hasLegacyRadio: Bool {return _storage._legacyRadio != nil} - /// Clears the value of `legacyRadio`. Subsequent reads from it will return its default value. - mutating func clearLegacyRadio() {_uniqueStorage()._legacyRadio = nil} - /// /// Read only settings/info about this node var myNode: MyNodeInfo { @@ -103,6 +53,8 @@ struct DeviceState { /// Clears the value of `owner`. Subsequent reads from it will return its default value. mutating func clearOwner() {_uniqueStorage()._owner = nil} + /// + /// TODO: REPLACE var nodeDb: [NodeInfo] { get {return _storage._nodeDb} set {_uniqueStorage()._nodeDb = newValue} @@ -152,41 +104,6 @@ struct DeviceState { set {_uniqueStorage()._didGpsReset = newValue} } - /// - /// Canned Message Plugin message part1. - var cannedMessagePluginMessagePart1: String { - get {return _storage._cannedMessagePluginMessagePart1} - set {_uniqueStorage()._cannedMessagePluginMessagePart1 = newValue} - } - - /// - /// Canned Message Plugin message part2. - var cannedMessagePluginMessagePart2: String { - get {return _storage._cannedMessagePluginMessagePart2} - set {_uniqueStorage()._cannedMessagePluginMessagePart2 = newValue} - } - - /// - /// Canned Message Plugin message part3. - var cannedMessagePluginMessagePart3: String { - get {return _storage._cannedMessagePluginMessagePart3} - set {_uniqueStorage()._cannedMessagePluginMessagePart3 = newValue} - } - - /// - /// Canned Message Plugin message part4. - var cannedMessagePluginMessagePart4: String { - get {return _storage._cannedMessagePluginMessagePart4} - set {_uniqueStorage()._cannedMessagePluginMessagePart4 = newValue} - } - - /// - /// Canned Message Plugin message part5. - var cannedMessagePluginMessagePart5: String { - get {return _storage._cannedMessagePluginMessagePart5} - set {_uniqueStorage()._cannedMessagePluginMessagePart5 = newValue} - } - var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -210,76 +127,16 @@ struct ChannelFile { init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension DeviceState: @unchecked Sendable {} +extension ChannelFile: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. -extension LegacyRadioConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = "LegacyRadioConfig" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "preferences"), - ] - - 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.decodeSingularMessageField(value: &self._preferences) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if let v = self._preferences { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: LegacyRadioConfig, rhs: LegacyRadioConfig) -> Bool { - if lhs._preferences != rhs._preferences {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -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"), - ] - - 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 15: try { try decoder.decodeSingularEnumField(value: &self.region) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if self.region != .unset { - try visitor.visitSingularEnumField(value: self.region, fieldNumber: 15) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: LegacyRadioConfig.LegacyPreferences, rhs: LegacyRadioConfig.LegacyPreferences) -> Bool { - if lhs.region != rhs.region {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "DeviceState" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "legacyRadio"), 2: .standard(proto: "my_node"), 3: .same(proto: "owner"), 4: .standard(proto: "node_db"), @@ -288,15 +145,9 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati 7: .standard(proto: "rx_text_message"), 9: .standard(proto: "no_save"), 11: .standard(proto: "did_gps_reset"), - 13: .standard(proto: "canned_message_plugin_message_part1"), - 14: .standard(proto: "canned_message_plugin_message_part2"), - 15: .standard(proto: "canned_message_plugin_message_part3"), - 16: .standard(proto: "canned_message_plugin_message_part4"), - 17: .standard(proto: "canned_message_plugin_message_part5"), ] fileprivate class _StorageClass { - var _legacyRadio: LegacyRadioConfig? = nil var _myNode: MyNodeInfo? = nil var _owner: User? = nil var _nodeDb: [NodeInfo] = [] @@ -305,18 +156,12 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati var _rxTextMessage: MeshPacket? = nil var _noSave: Bool = false var _didGpsReset: Bool = false - var _cannedMessagePluginMessagePart1: String = String() - var _cannedMessagePluginMessagePart2: String = String() - var _cannedMessagePluginMessagePart3: String = String() - var _cannedMessagePluginMessagePart4: String = String() - var _cannedMessagePluginMessagePart5: String = String() static let defaultInstance = _StorageClass() private init() {} init(copying source: _StorageClass) { - _legacyRadio = source._legacyRadio _myNode = source._myNode _owner = source._owner _nodeDb = source._nodeDb @@ -325,11 +170,6 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati _rxTextMessage = source._rxTextMessage _noSave = source._noSave _didGpsReset = source._didGpsReset - _cannedMessagePluginMessagePart1 = source._cannedMessagePluginMessagePart1 - _cannedMessagePluginMessagePart2 = source._cannedMessagePluginMessagePart2 - _cannedMessagePluginMessagePart3 = source._cannedMessagePluginMessagePart3 - _cannedMessagePluginMessagePart4 = source._cannedMessagePluginMessagePart4 - _cannedMessagePluginMessagePart5 = source._cannedMessagePluginMessagePart5 } } @@ -348,7 +188,6 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati // 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._legacyRadio) }() case 2: try { try decoder.decodeSingularMessageField(value: &_storage._myNode) }() case 3: try { try decoder.decodeSingularMessageField(value: &_storage._owner) }() case 4: try { try decoder.decodeRepeatedMessageField(value: &_storage._nodeDb) }() @@ -357,11 +196,6 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati case 8: try { try decoder.decodeSingularUInt32Field(value: &_storage._version) }() case 9: try { try decoder.decodeSingularBoolField(value: &_storage._noSave) }() case 11: try { try decoder.decodeSingularBoolField(value: &_storage._didGpsReset) }() - case 13: try { try decoder.decodeSingularStringField(value: &_storage._cannedMessagePluginMessagePart1) }() - case 14: try { try decoder.decodeSingularStringField(value: &_storage._cannedMessagePluginMessagePart2) }() - case 15: try { try decoder.decodeSingularStringField(value: &_storage._cannedMessagePluginMessagePart3) }() - case 16: try { try decoder.decodeSingularStringField(value: &_storage._cannedMessagePluginMessagePart4) }() - case 17: try { try decoder.decodeSingularStringField(value: &_storage._cannedMessagePluginMessagePart5) }() default: break } } @@ -370,24 +204,25 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati func traverse(visitor: inout V) throws { try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if let v = _storage._legacyRadio { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } - if let v = _storage._myNode { + // 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._myNode { try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } - if let v = _storage._owner { + } }() + try { 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) } - if let v = _storage._rxTextMessage { + try { if let v = _storage._rxTextMessage { try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - } + } }() if _storage._version != 0 { try visitor.visitSingularUInt32Field(value: _storage._version, fieldNumber: 8) } @@ -397,21 +232,6 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati if _storage._didGpsReset != false { try visitor.visitSingularBoolField(value: _storage._didGpsReset, fieldNumber: 11) } - if !_storage._cannedMessagePluginMessagePart1.isEmpty { - try visitor.visitSingularStringField(value: _storage._cannedMessagePluginMessagePart1, fieldNumber: 13) - } - if !_storage._cannedMessagePluginMessagePart2.isEmpty { - try visitor.visitSingularStringField(value: _storage._cannedMessagePluginMessagePart2, fieldNumber: 14) - } - if !_storage._cannedMessagePluginMessagePart3.isEmpty { - try visitor.visitSingularStringField(value: _storage._cannedMessagePluginMessagePart3, fieldNumber: 15) - } - if !_storage._cannedMessagePluginMessagePart4.isEmpty { - try visitor.visitSingularStringField(value: _storage._cannedMessagePluginMessagePart4, fieldNumber: 16) - } - if !_storage._cannedMessagePluginMessagePart5.isEmpty { - try visitor.visitSingularStringField(value: _storage._cannedMessagePluginMessagePart5, fieldNumber: 17) - } } try unknownFields.traverse(visitor: &visitor) } @@ -421,7 +241,6 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in let _storage = _args.0 let rhs_storage = _args.1 - if _storage._legacyRadio != rhs_storage._legacyRadio {return false} if _storage._myNode != rhs_storage._myNode {return false} if _storage._owner != rhs_storage._owner {return false} if _storage._nodeDb != rhs_storage._nodeDb {return false} @@ -430,11 +249,6 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati if _storage._rxTextMessage != rhs_storage._rxTextMessage {return false} if _storage._noSave != rhs_storage._noSave {return false} if _storage._didGpsReset != rhs_storage._didGpsReset {return false} - if _storage._cannedMessagePluginMessagePart1 != rhs_storage._cannedMessagePluginMessagePart1 {return false} - if _storage._cannedMessagePluginMessagePart2 != rhs_storage._cannedMessagePluginMessagePart2 {return false} - if _storage._cannedMessagePluginMessagePart3 != rhs_storage._cannedMessagePluginMessagePart3 {return false} - if _storage._cannedMessagePluginMessagePart4 != rhs_storage._cannedMessagePluginMessagePart4 {return false} - if _storage._cannedMessagePluginMessagePart5 != rhs_storage._cannedMessagePluginMessagePart5 {return false} return true } if !storagesAreEqual {return false} diff --git a/MeshtasticClient/Protobufs/environmental_measurement.pb.swift b/MeshtasticClient/Protobufs/environmental_measurement.pb.swift deleted file mode 100644 index 76533a31..00000000 --- a/MeshtasticClient/Protobufs/environmental_measurement.pb.swift +++ /dev/null @@ -1,107 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: environmental_measurement.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -import Foundation -import SwiftProtobuf - -// If the compiler emits an error on this type, it is because this file -// was generated by a version of the `protoc` Swift plug-in that is -// 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. -fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { - struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} - typealias Version = _2 -} - -struct EnvironmentalMeasurement { - // 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 temperature: Float = 0 - - var relativeHumidity: Float = 0 - - var barometricPressure: Float = 0 - - var gasResistance: Float = 0 - - var voltage: Float = 0 - - var current: Float = 0 - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -extension EnvironmentalMeasurement: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = "EnvironmentalMeasurement" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "temperature"), - 2: .standard(proto: "relative_humidity"), - 3: .standard(proto: "barometric_pressure"), - 4: .standard(proto: "gas_resistance"), - 5: .same(proto: "voltage"), - 6: .same(proto: "current"), - ] - - 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.decodeSingularFloatField(value: &self.temperature) }() - case 2: try { try decoder.decodeSingularFloatField(value: &self.relativeHumidity) }() - case 3: try { try decoder.decodeSingularFloatField(value: &self.barometricPressure) }() - case 4: try { try decoder.decodeSingularFloatField(value: &self.gasResistance) }() - case 5: try { try decoder.decodeSingularFloatField(value: &self.voltage) }() - case 6: try { try decoder.decodeSingularFloatField(value: &self.current) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if self.temperature != 0 { - try visitor.visitSingularFloatField(value: self.temperature, fieldNumber: 1) - } - if self.relativeHumidity != 0 { - try visitor.visitSingularFloatField(value: self.relativeHumidity, fieldNumber: 2) - } - if self.barometricPressure != 0 { - try visitor.visitSingularFloatField(value: self.barometricPressure, fieldNumber: 3) - } - if self.gasResistance != 0 { - try visitor.visitSingularFloatField(value: self.gasResistance, fieldNumber: 4) - } - if self.voltage != 0 { - try visitor.visitSingularFloatField(value: self.voltage, fieldNumber: 5) - } - if self.current != 0 { - try visitor.visitSingularFloatField(value: self.current, fieldNumber: 6) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: EnvironmentalMeasurement, rhs: EnvironmentalMeasurement) -> Bool { - if lhs.temperature != rhs.temperature {return false} - if lhs.relativeHumidity != rhs.relativeHumidity {return false} - if lhs.barometricPressure != rhs.barometricPressure {return false} - if lhs.gasResistance != rhs.gasResistance {return false} - if lhs.voltage != rhs.voltage {return false} - if lhs.current != rhs.current {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/MeshtasticClient/Protobufs/mesh.pb.swift b/MeshtasticClient/Protobufs/mesh.pb.swift index 9f6370a3..bf18f8ca 100644 --- a/MeshtasticClient/Protobufs/mesh.pb.swift +++ b/MeshtasticClient/Protobufs/mesh.pb.swift @@ -46,32 +46,79 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// To match the old style filenames, _ is converted to -, p is converted to . enum HardwareModel: SwiftProtobuf.Enum { typealias RawValue = Int + + /// + /// TODO: REPLACE case unset // = 0 + + /// + /// TODO: REPLACE case tloraV2 // = 1 + + /// + /// TODO: REPLACE case tloraV1 // = 2 + + /// + /// TODO: REPLACE case tloraV211P6 // = 3 + + /// + /// TODO: REPLACE 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 + + /// + /// TODO: REPLACE case tbeam0P7 // = 6 + + /// + /// TODO: REPLACE case tEcho // = 7 + + /// + /// TODO: REPLACE case tloraV11P3 // = 8 + + /// + /// TODO: REPLACE case rak4631 // = 9 - /// The new version of the heltec WiFi_Lora_32_V2 board that has battery sensing hooked to GPIO 37. Sadly they did not update anything on the silkscreen to identify this board + /// + /// The new version of the heltec WiFi_Lora_32_V2 board that has battery sensing hooked to GPIO 37. + /// Sadly they did not update anything on the silkscreen to identify this board case heltecV21 // = 10 - /// Ancient heltec WiFi_Lora_32 board + /// + /// Ancient heltec WiFi_Lora_32 board case heltecV1 // = 11 /// /// Less common/prototype boards listed here (needs one more byte over the air) case loraRelayV1 // = 32 + + /// + /// TODO: REPLACE case nrf52840Dk // = 33 + + /// + /// TODO: REPLACE case ppr // = 34 + + /// + /// TODO: REPLACE case genieblocks // = 35 + + /// + /// TODO: REPLACE case nrf52Unknown // = 36 + + /// + /// TODO: REPLACE case portduino // = 37 /// @@ -191,21 +238,64 @@ extension HardwareModel: CaseIterable { enum Team: SwiftProtobuf.Enum { typealias RawValue = Int - /// the default (unset) is "achromatic" (unaffiliated) + /// + /// the default (unset) is "achromatic" (unaffiliated) case clear // = 0 + + /// + /// TODO: REPLACE case cyan // = 1 + + /// + /// TODO: REPLACE case white // = 2 + + /// + /// TODO: REPLACE case yellow // = 3 + + /// + /// TODO: REPLACE case orange // = 4 + + /// + /// TODO: REPLACE case magenta // = 5 + + /// + /// TODO: REPLACE case red // = 6 + + /// + /// TODO: REPLACE case maroon // = 7 + + /// + /// TODO: REPLACE case purple // = 8 + + /// + /// TODO: REPLACE case darkBlue // = 9 + + /// + /// TODO: REPLACE case blue // = 10 + + /// + /// TODO: REPLACE case teal // = 11 + + /// + /// TODO: REPLACE case green // = 12 + + /// + /// TODO: REPLACE case darkGreen // = 13 + + /// + /// TODO: REPLACE case brown // = 14 case UNRECOGNIZED(Int) @@ -341,6 +431,9 @@ extension Constants: CaseIterable { /// and we'll try to help. enum CriticalErrorCode: SwiftProtobuf.Enum { typealias RawValue = Int + + /// + /// TODO: REPLACE case none // = 0 /// @@ -384,8 +477,9 @@ enum CriticalErrorCode: SwiftProtobuf.Enum { /// Selftest of SX1262 radio chip failed 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 + /// + /// 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 case radioSpiBug // = 11 case UNRECOGNIZED(Int) @@ -468,6 +562,8 @@ struct Position { set {_uniqueStorage()._latitudeI = newValue} } + /// + /// TODO: REPLACE var longitudeI: Int32 { get {return _storage._longitudeI} set {_uniqueStorage()._longitudeI = newValue} @@ -480,13 +576,6 @@ struct Position { set {_uniqueStorage()._altitude = newValue} } - /// - /// 1-100 (0 means not provided) - var batteryLevel: Int32 { - get {return _storage._batteryLevel} - set {_uniqueStorage()._batteryLevel = newValue} - } - /// /// This is usually not sent over the mesh (to save space), but it is sent /// from the phone so that the local device can set its RTC If it is sent over @@ -498,11 +587,15 @@ struct Position { set {_uniqueStorage()._time = newValue} } + /// + /// TODO: REPLACE var locationSource: Position.LocSource { get {return _storage._locationSource} set {_uniqueStorage()._locationSource = newValue} } + /// + /// TODO: REPLACE var altitudeSource: Position.AltSource { get {return _storage._altitudeSource} set {_uniqueStorage()._altitudeSource = newValue} @@ -541,16 +634,21 @@ struct Position { /// - PDOP is sufficient for most cases /// - for higher precision scenarios, HDOP and VDOP can be used instead, /// in which case PDOP becomes redundant (PDOP=sqrt(HDOP^2 + VDOP^2)) + /// TODO: REMOVE/INTEGRATE var pdop: UInt32 { get {return _storage._pdop} set {_uniqueStorage()._pdop = newValue} } + /// + /// TODO: REPLACE var hdop: UInt32 { get {return _storage._hdop} set {_uniqueStorage()._hdop = newValue} } + /// + /// TODO: REPLACE var vdop: UInt32 { get {return _storage._vdop} set {_uniqueStorage()._vdop = newValue} @@ -572,11 +670,14 @@ struct Position { /// - "track" is the direction of motion (measured in horizontal plane) /// - "heading" is where the fuselage points (measured in horizontal plane) /// - "yaw" indicates a relative rotation about the vertical axis + /// TODO: REMOVE/INTEGRATE var groundSpeed: UInt32 { get {return _storage._groundSpeed} set {_uniqueStorage()._groundSpeed = newValue} } + /// + /// TODO: REPLACE var groundTrack: UInt32 { get {return _storage._groundTrack} set {_uniqueStorage()._groundTrack = newValue} @@ -634,13 +735,21 @@ struct Position { /// How the location was acquired: manual, onboard GPS, external (EUD) GPS enum LocSource: SwiftProtobuf.Enum { typealias RawValue = Int + + /// + /// TODO: REPLACE case locsrcUnspecified // = 0 + + /// + /// TODO: REPLACE case locsrcManualEntry // = 1 + + /// + /// TODO: REPLACE case locsrcGpsInternal // = 2 /// - /// More location sources can be added here when available: - /// GSM, radio beacons (BLE etc), location fingerprinting etc + /// TODO: REPLACE case locsrcGpsExternal // = 3 case UNRECOGNIZED(Int) @@ -675,10 +784,25 @@ struct Position { /// Default: same as location_source if present enum AltSource: SwiftProtobuf.Enum { typealias RawValue = Int + + /// + /// TODO: REPLACE case altsrcUnspecified // = 0 + + /// + /// TODO: REPLACE case altsrcManualEntry // = 1 + + /// + /// TODO: REPLACE case altsrcGpsInternal // = 2 + + /// + /// TODO: REPLACE case altsrcGpsExternal // = 3 + + /// + /// TODO: REPLACE case altsrcBarometric // = 4 case UNRECOGNIZED(Int) @@ -851,7 +975,7 @@ struct RouteDiscovery { } /// -/// A Routing control Data packet handled by the routing plugin +/// A Routing control Data packet handled by the routing module struct Routing { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -945,6 +1069,9 @@ struct Routing { /// /// We received a nak while trying to forward on your behalf case gotNak // = 2 + + /// + /// TODO: REPLACE case timeout // = 3 /// @@ -973,8 +1100,8 @@ struct Routing { case badRequest // = 32 /// - /// The application layer service on the remote node received your request, but considered your request not authorized (i.e you did not - /// send the request on the required bound channel) + /// The application layer service on the remote node received your request, but considered your request not authorized + /// (i.e you did not send the request on the required bound channel) case notAuthorized // = 33 case UNRECOGNIZED(Int) @@ -1056,7 +1183,7 @@ struct DataMessage { var portnum: PortNum = .unknownApp /// - /// Required + /// TODO: REPLACE var payload: Data = Data() /// @@ -1091,7 +1218,52 @@ struct DataMessage { /// /// 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 = false + var emoji: UInt32 = 0 + + /// + /// Location structure + var location: Location { + get {return _location ?? Location()} + set {_location = newValue} + } + /// Returns true if `location` has been explicitly set. + var hasLocation: Bool {return self._location != nil} + /// Clears the value of `location`. Subsequent reads from it will return its default value. + mutating func clearLocation() {self._location = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _location: Location? = nil +} + +/// +/// Location of a waypoint to associate with a message +struct Location { + // 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. + + /// + /// Id of the location + var id: UInt32 = 0 + + /// + /// latitude_i + var latitudeI: Int32 = 0 + + /// + /// longitude_i + var longitudeI: Int32 = 0 + + /// + /// Time the location is to expire (epoch) + var expire: UInt32 = 0 + + /// + /// If true, only allow the original sender to update the location. + var locked: Bool = false var unknownFields = SwiftProtobuf.UnknownStorage() @@ -1110,7 +1282,7 @@ struct MeshPacket { /// /// The sending node number. /// Note: Our crypto implementation uses this field as well. - /// See [crypto](/developers/device/encryption.md) for details. + /// See [crypto](/docs/developers/firmware/encryption) for details. /// FIXME - really should be fixed32 instead, this encoding only hurts the ble link though. var from: UInt32 { get {return _storage._from} @@ -1143,6 +1315,8 @@ struct MeshPacket { set {_uniqueStorage()._payloadVariant = newValue} } + /// + /// TODO: REPLACE var decoded: DataMessage { get { if case .decoded(let v)? = _storage._payloadVariant {return v} @@ -1151,6 +1325,8 @@ struct MeshPacket { set {_uniqueStorage()._payloadVariant = .decoded(newValue)} } + /// + /// TODO: REPLACE var encrypted: Data { get { if case .encrypted(let v)? = _storage._payloadVariant {return v} @@ -1167,7 +1343,7 @@ struct MeshPacket { /// needs to be unique for a few minutes (long enough to last for the length of /// any ACK or the completion of a mesh broadcast flood). /// Note: Our crypto implementation uses this id as well. - /// See [crypto](/developers/device/encryption.md) for details. + /// See [crypto](/docs/developers/firmware/encryption) for details. /// FIXME - really should be fixed32 instead, this encoding only /// hurts the ble link though. var id: UInt32 { @@ -1244,7 +1420,11 @@ struct MeshPacket { var unknownFields = SwiftProtobuf.UnknownStorage() enum OneOf_PayloadVariant: Equatable { + /// + /// TODO: REPLACE case decoded(DataMessage) + /// + /// TODO: REPLACE case encrypted(Data) #if !swift(>=4.1) @@ -1296,6 +1476,9 @@ struct MeshPacket { /// /// Treated as Priority.DEFAULT case unset // = 0 + + /// + /// TODO: REPLACE case min // = 1 /// @@ -1316,6 +1499,9 @@ struct MeshPacket { /// Ack/naks are sent with very high priority to ensure that retransmission /// stops as soon as possible case ack // = 120 + + /// + /// TODO: REPLACE case max // = 127 case UNRECOGNIZED(Int) @@ -1453,46 +1639,65 @@ struct NodeInfo { /// /// The node number - var num: UInt32 = 0 + var num: UInt32 { + get {return _storage._num} + set {_uniqueStorage()._num = newValue} + } /// /// The user info for this node var user: User { - get {return _user ?? User()} - set {_user = newValue} + get {return _storage._user ?? User()} + set {_uniqueStorage()._user = newValue} } /// Returns true if `user` has been explicitly set. - var hasUser: Bool {return self._user != nil} + var hasUser: Bool {return _storage._user != nil} /// Clears the value of `user`. Subsequent reads from it will return its default value. - mutating func clearUser() {self._user = nil} + mutating func clearUser() {_uniqueStorage()._user = nil} /// /// This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true. /// Position.time now indicates the last time we received a POSITION from that node. var position: Position { - get {return _position ?? Position()} - set {_position = newValue} + get {return _storage._position ?? Position()} + set {_uniqueStorage()._position = newValue} } /// Returns true if `position` has been explicitly set. - var hasPosition: Bool {return self._position != nil} + var hasPosition: Bool {return _storage._position != nil} /// Clears the value of `position`. Subsequent reads from it will return its default value. - mutating func clearPosition() {self._position = nil} + mutating func clearPosition() {_uniqueStorage()._position = nil} /// /// Returns the Signal-to-noise ratio (SNR) of the last received message, /// as measured by the receiver. Return SNR of the last received message in dB - var snr: Float = 0 + var snr: Float { + get {return _storage._snr} + set {_uniqueStorage()._snr = newValue} + } /// /// Set to indicate the last time we received a packet from this node - var lastHeard: UInt32 = 0 + var lastHeard: UInt32 { + get {return _storage._lastHeard} + set {_uniqueStorage()._lastHeard = newValue} + } + + /// + /// The latest device telemetry data for the node. + var telemetry: Telemetry { + get {return _storage._telemetry ?? Telemetry()} + set {_uniqueStorage()._telemetry = newValue} + } + /// Returns true if `telemetry` has been explicitly set. + var hasTelemetry: Bool {return _storage._telemetry != nil} + /// Clears the value of `telemetry`. Subsequent reads from it will return its default value. + mutating func clearTelemetry() {_uniqueStorage()._telemetry = nil} var unknownFields = SwiftProtobuf.UnknownStorage() init() {} - fileprivate var _user: User? = nil - fileprivate var _position: Position? = nil + fileprivate var _storage = _StorageClass.defaultInstance } /// @@ -1520,15 +1725,6 @@ struct MyNodeInfo { 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 { - get {return _storage._numBands} - set {_uniqueStorage()._numBands = newValue} - } - /// /// The maximum number of 'software' channels that can be set on this node. var maxChannels: UInt32 { @@ -1549,16 +1745,6 @@ struct MyNodeInfo { 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 { - get {return _storage._hwModelDeprecated} - set {_uniqueStorage()._hwModelDeprecated = newValue} - } - /// /// 0.0.5 etc... var firmwareVersion: String { @@ -1680,6 +1866,8 @@ struct LogRecord { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// Log levels, chosen to match python logging conventions. var message: String = String() /// @@ -1700,12 +1888,33 @@ struct LogRecord { /// Log levels, chosen to match python logging conventions. enum Level: SwiftProtobuf.Enum { typealias RawValue = Int + + /// + /// Log levels, chosen to match python logging conventions. case unset // = 0 + + /// + /// Log levels, chosen to match python logging conventions. case critical // = 50 + + /// + /// Log levels, chosen to match python logging conventions. case error // = 40 + + /// + /// Log levels, chosen to match python logging conventions. case warning // = 30 + + /// + /// Log levels, chosen to match python logging conventions. case info // = 20 + + /// + /// Log levels, chosen to match python logging conventions. case debug // = 10 + + /// + /// Log levels, chosen to match python logging conventions. case trace // = 5 case UNRECOGNIZED(Int) @@ -1772,12 +1981,16 @@ struct FromRadio { // methods supported on all messages. /// - /// The packet num, used to allow the phone to request missing read packets from the FIFO, + /// The packet id, used to allow the phone to request missing read packets from the FIFO, /// see our bluetooth docs - var num: UInt32 = 0 + var id: UInt32 = 0 + /// + /// Log levels, chosen to match python logging conventions. var payloadVariant: FromRadio.OneOf_PayloadVariant? = nil + /// + /// Log levels, chosen to match python logging conventions. var packet: MeshPacket { get { if case .packet(let v)? = payloadVariant {return v} @@ -1846,7 +2059,11 @@ struct FromRadio { var unknownFields = SwiftProtobuf.UnknownStorage() + /// + /// Log levels, chosen to match python logging conventions. enum OneOf_PayloadVariant: Equatable { + /// + /// Log levels, chosen to match python logging conventions. case packet(MeshPacket) /// /// Tells the phone what our node number is, can be -1 if we've not yet joined a mesh. @@ -1919,6 +2136,8 @@ struct ToRadio { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// Log levels, chosen to match python logging conventions. var payloadVariant: ToRadio.OneOf_PayloadVariant? = nil /// @@ -1973,6 +2192,8 @@ struct ToRadio { var unknownFields = SwiftProtobuf.UnknownStorage() + /// + /// Log levels, chosen to match python logging conventions. enum OneOf_PayloadVariant: Equatable { /// /// Send this packet on the mesh @@ -2052,6 +2273,36 @@ struct ToRadio { init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension HardwareModel: @unchecked Sendable {} +extension Team: @unchecked Sendable {} +extension Constants: @unchecked Sendable {} +extension CriticalErrorCode: @unchecked Sendable {} +extension Position: @unchecked Sendable {} +extension Position.LocSource: @unchecked Sendable {} +extension Position.AltSource: @unchecked Sendable {} +extension User: @unchecked Sendable {} +extension RouteDiscovery: @unchecked Sendable {} +extension Routing: @unchecked Sendable {} +extension Routing.OneOf_Variant: @unchecked Sendable {} +extension Routing.Error: @unchecked Sendable {} +extension DataMessage: @unchecked Sendable {} +extension Location: @unchecked Sendable {} +extension MeshPacket: @unchecked Sendable {} +extension MeshPacket.OneOf_PayloadVariant: @unchecked Sendable {} +extension MeshPacket.Priority: @unchecked Sendable {} +extension MeshPacket.Delayed: @unchecked Sendable {} +extension NodeInfo: @unchecked Sendable {} +extension MyNodeInfo: @unchecked Sendable {} +extension LogRecord: @unchecked Sendable {} +extension LogRecord.Level: @unchecked Sendable {} +extension FromRadio: @unchecked Sendable {} +extension FromRadio.OneOf_PayloadVariant: @unchecked Sendable {} +extension ToRadio: @unchecked Sendable {} +extension ToRadio.OneOf_PayloadVariant: @unchecked Sendable {} +extension ToRadio.PeerInfo: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. extension HardwareModel: SwiftProtobuf._ProtoNameProviding { @@ -2131,7 +2382,6 @@ extension Position: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB 1: .standard(proto: "latitude_i"), 2: .standard(proto: "longitude_i"), 3: .same(proto: "altitude"), - 4: .standard(proto: "battery_level"), 9: .same(proto: "time"), 10: .standard(proto: "location_source"), 11: .standard(proto: "altitude_source"), @@ -2157,7 +2407,6 @@ extension Position: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB var _latitudeI: Int32 = 0 var _longitudeI: Int32 = 0 var _altitude: Int32 = 0 - var _batteryLevel: Int32 = 0 var _time: UInt32 = 0 var _locationSource: Position.LocSource = .locsrcUnspecified var _altitudeSource: Position.AltSource = .altsrcUnspecified @@ -2186,7 +2435,6 @@ extension Position: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB _latitudeI = source._latitudeI _longitudeI = source._longitudeI _altitude = source._altitude - _batteryLevel = source._batteryLevel _time = source._time _locationSource = source._locationSource _altitudeSource = source._altitudeSource @@ -2227,7 +2475,6 @@ extension Position: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB case 1: try { try decoder.decodeSingularSFixed32Field(value: &_storage._latitudeI) }() case 2: try { try decoder.decodeSingularSFixed32Field(value: &_storage._longitudeI) }() case 3: try { try decoder.decodeSingularInt32Field(value: &_storage._altitude) }() - case 4: try { try decoder.decodeSingularInt32Field(value: &_storage._batteryLevel) }() case 9: try { try decoder.decodeSingularFixed32Field(value: &_storage._time) }() case 10: try { try decoder.decodeSingularEnumField(value: &_storage._locationSource) }() case 11: try { try decoder.decodeSingularEnumField(value: &_storage._altitudeSource) }() @@ -2264,9 +2511,6 @@ extension Position: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB if _storage._altitude != 0 { try visitor.visitSingularInt32Field(value: _storage._altitude, fieldNumber: 3) } - if _storage._batteryLevel != 0 { - try visitor.visitSingularInt32Field(value: _storage._batteryLevel, fieldNumber: 4) - } if _storage._time != 0 { try visitor.visitSingularFixed32Field(value: _storage._time, fieldNumber: 9) } @@ -2336,7 +2580,6 @@ extension Position: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB if _storage._latitudeI != rhs_storage._latitudeI {return false} if _storage._longitudeI != rhs_storage._longitudeI {return false} if _storage._altitude != rhs_storage._altitude {return false} - if _storage._batteryLevel != rhs_storage._batteryLevel {return false} if _storage._time != rhs_storage._time {return false} if _storage._locationSource != rhs_storage._locationSource {return false} if _storage._altitudeSource != rhs_storage._altitudeSource {return false} @@ -2557,8 +2800,9 @@ 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 case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 + // 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 switch self.variant { case .routeRequest?: try { guard case .routeRequest(let v)? = self.variant else { preconditionFailure() } @@ -2610,7 +2854,8 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati 5: .same(proto: "source"), 6: .standard(proto: "request_id"), 7: .standard(proto: "reply_id"), - 8: .standard(proto: "is_tapback"), + 8: .same(proto: "emoji"), + 9: .same(proto: "location"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2626,13 +2871,18 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati case 5: try { try decoder.decodeSingularFixed32Field(value: &self.source) }() case 6: try { try decoder.decodeSingularFixed32Field(value: &self.requestID) }() case 7: try { try decoder.decodeSingularFixed32Field(value: &self.replyID) }() - case 8: try { try decoder.decodeSingularBoolField(value: &self.isTapback) }() + case 8: try { try decoder.decodeSingularFixed32Field(value: &self.emoji) }() + case 9: try { try decoder.decodeSingularMessageField(value: &self._location) }() 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.portnum != .unknownApp { try visitor.visitSingularEnumField(value: self.portnum, fieldNumber: 1) } @@ -2654,9 +2904,12 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati if self.replyID != 0 { try visitor.visitSingularFixed32Field(value: self.replyID, fieldNumber: 7) } - if self.isTapback != false { - try visitor.visitSingularBoolField(value: self.isTapback, fieldNumber: 8) + if self.emoji != 0 { + try visitor.visitSingularFixed32Field(value: self.emoji, fieldNumber: 8) } + try { if let v = self._location { + try visitor.visitSingularMessageField(value: v, fieldNumber: 9) + } }() try unknownFields.traverse(visitor: &visitor) } @@ -2668,7 +2921,64 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati if lhs.source != rhs.source {return false} if lhs.requestID != rhs.requestID {return false} if lhs.replyID != rhs.replyID {return false} - if lhs.isTapback != rhs.isTapback {return false} + if lhs.emoji != rhs.emoji {return false} + if lhs._location != rhs._location {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = "Location" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + 2: .standard(proto: "latitude_i"), + 3: .standard(proto: "longitude_i"), + 4: .same(proto: "expire"), + 5: .same(proto: "locked"), + ] + + 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.id) }() + case 2: try { try decoder.decodeSingularSFixed32Field(value: &self.latitudeI) }() + case 3: try { try decoder.decodeSingularSFixed32Field(value: &self.longitudeI) }() + case 4: try { try decoder.decodeSingularUInt32Field(value: &self.expire) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self.locked) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.id != 0 { + try visitor.visitSingularUInt32Field(value: self.id, fieldNumber: 1) + } + if self.latitudeI != 0 { + try visitor.visitSingularSFixed32Field(value: self.latitudeI, fieldNumber: 2) + } + if self.longitudeI != 0 { + try visitor.visitSingularSFixed32Field(value: self.longitudeI, fieldNumber: 3) + } + if self.expire != 0 { + try visitor.visitSingularUInt32Field(value: self.expire, fieldNumber: 4) + } + if self.locked != false { + try visitor.visitSingularBoolField(value: self.locked, fieldNumber: 5) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location, rhs: Location) -> Bool { + if lhs.id != rhs.id {return false} + if lhs.latitudeI != rhs.latitudeI {return false} + if lhs.longitudeI != rhs.longitudeI {return false} + if lhs.expire != rhs.expire {return false} + if lhs.locked != rhs.locked {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -2781,6 +3091,10 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 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._from != 0 { try visitor.visitSingularFixed32Field(value: _storage._from, fieldNumber: 1) } @@ -2790,9 +3104,6 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 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() } @@ -2884,51 +3195,103 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB 1: .same(proto: "num"), 2: .same(proto: "user"), 3: .same(proto: "position"), - 7: .same(proto: "snr"), - 4: .standard(proto: "last_heard"), + 4: .same(proto: "snr"), + 5: .standard(proto: "last_heard"), + 6: .same(proto: "telemetry"), ] + fileprivate class _StorageClass { + var _num: UInt32 = 0 + var _user: User? = nil + var _position: Position? = nil + var _snr: Float = 0 + var _lastHeard: UInt32 = 0 + var _telemetry: Telemetry? = nil + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _num = source._num + _user = source._user + _position = source._position + _snr = source._snr + _lastHeard = source._lastHeard + _telemetry = source._telemetry + } + } + + 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.num) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._user) }() - case 3: try { try decoder.decodeSingularMessageField(value: &self._position) }() - case 4: try { try decoder.decodeSingularFixed32Field(value: &self.lastHeard) }() - case 7: try { try decoder.decodeSingularFloatField(value: &self.snr) }() - 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._num) }() + case 2: try { try decoder.decodeSingularMessageField(value: &_storage._user) }() + case 3: try { try decoder.decodeSingularMessageField(value: &_storage._position) }() + case 4: try { try decoder.decodeSingularFloatField(value: &_storage._snr) }() + case 5: try { try decoder.decodeSingularFixed32Field(value: &_storage._lastHeard) }() + case 6: try { try decoder.decodeSingularMessageField(value: &_storage._telemetry) }() + default: break + } } } } func traverse(visitor: inout V) throws { - if self.num != 0 { - try visitor.visitSingularUInt32Field(value: self.num, fieldNumber: 1) - } - if let v = self._user { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } - if let v = self._position { - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } - if self.lastHeard != 0 { - try visitor.visitSingularFixed32Field(value: self.lastHeard, fieldNumber: 4) - } - if self.snr != 0 { - try visitor.visitSingularFloatField(value: self.snr, fieldNumber: 7) + 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) + } + try { if let v = _storage._user { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try { if let v = _storage._position { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + if _storage._snr != 0 { + try visitor.visitSingularFloatField(value: _storage._snr, fieldNumber: 4) + } + if _storage._lastHeard != 0 { + try visitor.visitSingularFixed32Field(value: _storage._lastHeard, fieldNumber: 5) + } + try { if let v = _storage._telemetry { + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + } }() } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: NodeInfo, rhs: NodeInfo) -> Bool { - if lhs.num != rhs.num {return false} - if lhs._user != rhs._user {return false} - if lhs._position != rhs._position {return false} - if lhs.snr != rhs.snr {return false} - if lhs.lastHeard != rhs.lastHeard {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._num != rhs_storage._num {return false} + if _storage._user != rhs_storage._user {return false} + if _storage._position != rhs_storage._position {return false} + if _storage._snr != rhs_storage._snr {return false} + if _storage._lastHeard != rhs_storage._lastHeard {return false} + if _storage._telemetry != rhs_storage._telemetry {return false} + return true + } + if !storagesAreEqual {return false} + } if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -2939,10 +3302,8 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .standard(proto: "my_node_num"), 2: .standard(proto: "has_gps"), - 3: .standard(proto: "num_bands"), 15: .standard(proto: "max_channels"), 4: .same(proto: "region"), - 5: .standard(proto: "hw_model_deprecated"), 6: .standard(proto: "firmware_version"), 7: .standard(proto: "error_code"), 8: .standard(proto: "error_address"), @@ -2961,10 +3322,8 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 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 @@ -2986,10 +3345,8 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 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 @@ -3023,9 +3380,7 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 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) }() @@ -3054,15 +3409,9 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 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) } @@ -3116,10 +3465,8 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 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} @@ -3207,7 +3554,7 @@ extension LogRecord.Level: SwiftProtobuf._ProtoNameProviding { extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "FromRadio" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "num"), + 1: .same(proto: "id"), 11: .same(proto: "packet"), 3: .standard(proto: "my_info"), 4: .standard(proto: "node_info"), @@ -3222,7 +3569,7 @@ extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation // 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 1: try { try decoder.decodeSingularUInt32Field(value: &self.id) }() case 3: try { var v: MyNodeInfo? var hadOneofValue = false @@ -3297,12 +3644,13 @@ extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation } func traverse(visitor: inout V) throws { - 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 + // 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.id != 0 { + try visitor.visitSingularUInt32Field(value: self.id, fieldNumber: 1) + } switch self.payloadVariant { case .myInfo?: try { guard case .myInfo(let v)? = self.payloadVariant else { preconditionFailure() } @@ -3334,7 +3682,7 @@ extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation } static func ==(lhs: FromRadio, rhs: FromRadio) -> Bool { - if lhs.num != rhs.num {return false} + if lhs.id != rhs.id {return false} if lhs.payloadVariant != rhs.payloadVariant {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true @@ -3405,8 +3753,9 @@ 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 case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 + // 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 switch self.payloadVariant { case .packet?: try { guard case .packet(let v)? = self.payloadVariant else { preconditionFailure() } diff --git a/MeshtasticClient/Protobufs/mqtt.pb.swift b/MeshtasticClient/Protobufs/mqtt.pb.swift index 988140a4..0f347c87 100644 --- a/MeshtasticClient/Protobufs/mqtt.pb.swift +++ b/MeshtasticClient/Protobufs/mqtt.pb.swift @@ -55,6 +55,10 @@ struct ServiceEnvelope { fileprivate var _packet: MeshPacket? = nil } +#if swift(>=5.5) && canImport(_Concurrency) +extension ServiceEnvelope: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. extension ServiceEnvelope: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { @@ -80,9 +84,13 @@ extension ServiceEnvelope: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen } func traverse(visitor: inout V) throws { - if let v = self._packet { + // 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._packet { try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } + } }() if !self.channelID.isEmpty { try visitor.visitSingularStringField(value: self.channelID, fieldNumber: 2) } diff --git a/MeshtasticClient/Protobufs/portnums.pb.swift b/MeshtasticClient/Protobufs/portnums.pb.swift index 9d204a69..175c4f66 100644 --- a/MeshtasticClient/Protobufs/portnums.pb.swift +++ b/MeshtasticClient/Protobufs/portnums.pb.swift @@ -61,27 +61,27 @@ enum PortNum: SwiftProtobuf.Enum { /// /// The built-in position messaging app. - /// Payload is a [Position](/developers/protobufs/api.md#position) message + /// Payload is a [Position](/docs/developers/protobufs/api#position) message case positionApp // = 3 /// /// The built-in user info app. - /// Payload is a [User](/developers/protobufs/api.md#user) message + /// Payload is a [User](/docs/developers/protobufs/api#user) message case nodeinfoApp // = 4 /// /// Protocol control packets for mesh protocol use. - /// Payload is a [Routing](/developers/protobufs/api.md#routing) message + /// Payload is a [Routing](/docs/developers/protobufs/api#routing) message case routingApp // = 5 /// /// Admin control packets. - /// Payload is a [AdminMessage](/developers/protobufs/api.md#adminmessage) message + /// Payload is a [AdminMessage](/docs/developers/protobufs/api#adminmessage) message case adminApp // = 6 /// /// Provides a 'ping' service that replies to any packet it receives. - /// Also serves as a small example plugin. + /// Also serves as a small example module. case replyApp // = 32 /// @@ -93,8 +93,7 @@ enum PortNum: SwiftProtobuf.Enum { /// Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic /// network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network. /// Maximum packet size of 240 bytes. - /// Plugin is disabled by default can be turned on by setting SERIALPLUGIN_ENABLED = 1 in SerialPlugh.cpp. - /// Maintained by Jm Casler (MC Hamster) : jm@casler.org + /// Module is disabled by default can be turned on by setting SERIAL_MODULE_ENABLED = 1 in SerialPlugh.cpp. case serialApp // = 64 /// @@ -103,14 +102,13 @@ enum PortNum: SwiftProtobuf.Enum { case storeForwardApp // = 65 /// - /// STORE_FORWARD_APP (Work in Progress) - /// Maintained by Jm Casler (MC Hamster) : jm@casler.org + /// Optional port for messages for the range test module. case rangeTestApp // = 66 /// - /// Provides a format to send and receive environmental data from the Meshtastic network. + /// Provides a format to send and receive telemetry data from the Meshtastic network. /// Maintained by Charles Crossan (crossan007) : crossan007@gmail.com - case environmentalMeasurementApp // = 67 + case telemetryApp // = 67 /// /// Experimental tools for estimating node position without a GPS @@ -125,7 +123,7 @@ enum PortNum: SwiftProtobuf.Enum { case privateApp // = 256 /// - /// ATAK Forwarder Plugin https://github.com/paulmandal/atak-forwarder + /// ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder case atakForwarder // = 257 /// @@ -151,7 +149,7 @@ enum PortNum: SwiftProtobuf.Enum { case 64: self = .serialApp case 65: self = .storeForwardApp case 66: self = .rangeTestApp - case 67: self = .environmentalMeasurementApp + case 67: self = .telemetryApp case 68: self = .zpsApp case 256: self = .privateApp case 257: self = .atakForwarder @@ -174,7 +172,7 @@ enum PortNum: SwiftProtobuf.Enum { case .serialApp: return 64 case .storeForwardApp: return 65 case .rangeTestApp: return 66 - case .environmentalMeasurementApp: return 67 + case .telemetryApp: return 67 case .zpsApp: return 68 case .privateApp: return 256 case .atakForwarder: return 257 @@ -202,7 +200,7 @@ extension PortNum: CaseIterable { .serialApp, .storeForwardApp, .rangeTestApp, - .environmentalMeasurementApp, + .telemetryApp, .zpsApp, .privateApp, .atakForwarder, @@ -212,6 +210,10 @@ extension PortNum: CaseIterable { #endif // swift(>=4.2) +#if swift(>=5.5) && canImport(_Concurrency) +extension PortNum: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. extension PortNum: SwiftProtobuf._ProtoNameProviding { @@ -228,7 +230,7 @@ extension PortNum: SwiftProtobuf._ProtoNameProviding { 64: .same(proto: "SERIAL_APP"), 65: .same(proto: "STORE_FORWARD_APP"), 66: .same(proto: "RANGE_TEST_APP"), - 67: .same(proto: "ENVIRONMENTAL_MEASUREMENT_APP"), + 67: .same(proto: "TELEMETRY_APP"), 68: .same(proto: "ZPS_APP"), 256: .same(proto: "PRIVATE_APP"), 257: .same(proto: "ATAK_FORWARDER"), diff --git a/MeshtasticClient/Protobufs/radioconfig.pb.swift b/MeshtasticClient/Protobufs/radioconfig.pb.swift index 5ea36075..2d77364f 100644 --- a/MeshtasticClient/Protobufs/radioconfig.pb.swift +++ b/MeshtasticClient/Protobufs/radioconfig.pb.swift @@ -50,16 +50,58 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// old value will be no longer set. enum RegionCode: SwiftProtobuf.Enum { typealias RawValue = Int + + /// + /// TODO: REPLACE case unset // = 0 + + /// + /// TODO: REPLACE case us // = 1 + + /// + /// TODO: REPLACE case eu433 // = 2 - case eu865 // = 3 + + /// + /// TODO: REPLACE + case eu868 // = 3 + + /// + /// TODO: REPLACE case cn // = 4 + + /// + /// TODO: REPLACE case jp // = 5 + + /// + /// TODO: REPLACE case anz // = 6 + + /// + /// TODO: REPLACE case kr // = 7 + + /// + /// TODO: REPLACE case tw // = 8 + + /// + /// TODO: REPLACE case ru // = 9 + + /// + /// TODO: REPLACE + case `in` // = 10 + + /// + /// TODO: REPLACE + case nz865 // = 11 + + /// + /// TODO: REPLACE + case th // = 12 case UNRECOGNIZED(Int) init() { @@ -71,13 +113,16 @@ enum RegionCode: SwiftProtobuf.Enum { case 0: self = .unset case 1: self = .us case 2: self = .eu433 - case 3: self = .eu865 + case 3: self = .eu868 case 4: self = .cn case 5: self = .jp case 6: self = .anz case 7: self = .kr case 8: self = .tw case 9: self = .ru + case 10: self = .in + case 11: self = .nz865 + case 12: self = .th default: self = .UNRECOGNIZED(rawValue) } } @@ -87,13 +132,16 @@ enum RegionCode: SwiftProtobuf.Enum { case .unset: return 0 case .us: return 1 case .eu433: return 2 - case .eu865: return 3 + case .eu868: return 3 case .cn: return 4 case .jp: return 5 case .anz: return 6 case .kr: return 7 case .tw: return 8 case .ru: return 9 + case .in: return 10 + case .nz865: return 11 + case .th: return 12 case .UNRECOGNIZED(let i): return i } } @@ -108,13 +156,69 @@ extension RegionCode: CaseIterable { .unset, .us, .eu433, - .eu865, + .eu868, .cn, .jp, .anz, .kr, .tw, .ru, + .in, + .nz865, + .th, + ] +} + +#endif // swift(>=4.2) + +/// +/// Defines the device's role on the Mesh network +/// unset +/// Behave normally. +/// +/// Router +/// Functions as a router +enum Role: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// Default device role + case `default` // = 0 + + /// + /// Router device role + case router // = 1 + case UNRECOGNIZED(Int) + + init() { + self = .default + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .default + case 1: self = .router + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .default: return 0 + case .router: return 1 + case .UNRECOGNIZED(let i): return i + } + } + +} + +#if swift(>=4.2) + +extension Role: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [Role] = [ + .default, + .router, ] } @@ -125,22 +229,73 @@ extension RegionCode: CaseIterable { /// configured. This is passed into the axp power management chip like on the tbeam. enum ChargeCurrent: SwiftProtobuf.Enum { typealias RawValue = Int + + /// + /// TODO: REPLACE case maunset // = 0 + + /// + /// TODO: REPLACE case ma100 // = 1 + + /// + /// TODO: REPLACE case ma190 // = 2 + + /// + /// TODO: REPLACE case ma280 // = 3 + + /// + /// TODO: REPLACE case ma360 // = 4 + + /// + /// TODO: REPLACE case ma450 // = 5 + + /// + /// TODO: REPLACE case ma550 // = 6 + + /// + /// TODO: REPLACE case ma630 // = 7 + + /// + /// TODO: REPLACE case ma700 // = 8 + + /// + /// TODO: REPLACE case ma780 // = 9 + + /// + /// TODO: REPLACE case ma880 // = 10 + + /// + /// TODO: REPLACE case ma960 // = 11 + + /// + /// TODO: REPLACE case ma1000 // = 12 + + /// + /// TODO: REPLACE case ma1080 // = 13 + + /// + /// TODO: REPLACE case ma1160 // = 14 + + /// + /// TODO: REPLACE case ma1240 // = 15 + + /// + /// TODO: REPLACE case ma1320 // = 16 case UNRECOGNIZED(Int) @@ -223,81 +378,6 @@ extension ChargeCurrent: CaseIterable { #endif // swift(>=4.2) -/// -/// How the GPS hardware in this unit is operated. -/// Note: This is independent of how our location is shared with other devices. -/// For that see LocationSharing -enum GpsOperation: SwiftProtobuf.Enum { - typealias RawValue = Int - - /// - /// This is treated as GpsOpMobile - it is the default setting - case gpsOpUnset // = 0 - - /// - /// Note: This mode was removed, because it is identical go GpsOpMobile with a gps_update_rate of once per day - /// This node is mostly stationary, we should try to get location only once per day, - /// Once we have that position we should turn the GPS to sleep mode - /// This is the recommended configuration for stationary 'router' nodes - case gpsOpStationary // = 1 - - /// - /// This node is mobile and we should get GPS position at a rate governed by gps_update_rate - case gpsOpMobile // = 2 - - /// - /// We should only use the GPS to get time (no location data should be acquired/stored) - /// Once we have the time we treat gps_update_interval as MAXINT (i.e. sleep forever) - case gpsOpTimeOnly // = 3 - - /// - /// GPS is always turned off - this mode is not recommended - use GpsOpTimeOnly instead - case gpsOpDisabled // = 4 - case UNRECOGNIZED(Int) - - init() { - self = .gpsOpUnset - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .gpsOpUnset - case 1: self = .gpsOpStationary - case 2: self = .gpsOpMobile - case 3: self = .gpsOpTimeOnly - case 4: self = .gpsOpDisabled - default: self = .UNRECOGNIZED(rawValue) - } - } - - var rawValue: Int { - switch self { - case .gpsOpUnset: return 0 - case .gpsOpStationary: return 1 - case .gpsOpMobile: return 2 - case .gpsOpTimeOnly: return 3 - case .gpsOpDisabled: return 4 - case .UNRECOGNIZED(let i): return i - } - } - -} - -#if swift(>=4.2) - -extension GpsOperation: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - static var allCases: [GpsOperation] = [ - .gpsOpUnset, - .gpsOpStationary, - .gpsOpMobile, - .gpsOpTimeOnly, - .gpsOpDisabled, - ] -} - -#endif // swift(>=4.2) - /// /// How the GPS coordinates are displayed on the OLED screen. enum GpsCoordinateFormat: SwiftProtobuf.Enum { @@ -381,61 +461,6 @@ extension GpsCoordinateFormat: CaseIterable { #endif // swift(>=4.2) -/// -/// How our location is shared with other nodes (or the local phone) -enum LocationSharing: SwiftProtobuf.Enum { - typealias RawValue = Int - - /// - /// This is the default and treated as LocEnabled. - case locUnset // = 0 - - /// - /// We are sharing our location - case locEnabled // = 1 - - /// - /// We are not sharing our location (if the unit has a GPS it will default to only get time - i.e. GpsOpTimeOnly) - case locDisabled // = 2 - case UNRECOGNIZED(Int) - - init() { - self = .locUnset - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .locUnset - case 1: self = .locEnabled - case 2: self = .locDisabled - default: self = .UNRECOGNIZED(rawValue) - } - } - - var rawValue: Int { - switch self { - case .locUnset: return 0 - case .locEnabled: return 1 - case .locDisabled: return 2 - case .UNRECOGNIZED(let i): return i - } - } - -} - -#if swift(>=4.2) - -extension LocationSharing: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - static var allCases: [LocationSharing] = [ - .locUnset, - .locEnabled, - .locDisabled, - ] -} - -#endif // swift(>=4.2) - /// /// Bit field of boolean configuration options, indicating which optional /// fields to include when assembling POSITION messages @@ -446,34 +471,44 @@ extension LocationSharing: CaseIterable { enum PositionFlags: SwiftProtobuf.Enum { typealias RawValue = Int - /// Required for compilation + /// + /// Required for compilation case posUndefined // = 0 - /// Include an altitude value (if available) + /// + /// Include an altitude value (if available) case posAltitude // = 1 - /// Altitude value is MSL + /// + /// Altitude value is MSL case posAltMsl // = 2 - /// Include geoidal separation + /// + /// Include geoidal separation case posGeoSep // = 4 - /// Include the DOP value ; PDOP used by default, see below + /// + /// Include the DOP value ; PDOP used by default, see below case posDop // = 8 - /// If POS_DOP set, send separate HDOP / VDOP values instead of PDOP + /// + /// If POS_DOP set, send separate HDOP / VDOP values instead of PDOP case posHvdop // = 16 - /// Include battery level + /// + /// Include battery level case posBattery // = 32 - /// Include number of "satellites in view" + /// + /// Include number of "satellites in view" case posSatinview // = 64 - /// Include a sequence number incremented per packet + /// + /// Include a sequence number incremented per packet case posSeqNos // = 128 - /// Include positional timestamp (from GPS solution) + /// + /// Include positional timestamp (from GPS solution) case posTimestamp // = 256 case UNRECOGNIZED(Int) @@ -535,17 +570,41 @@ extension PositionFlags: CaseIterable { #endif // swift(>=4.2) +/// +/// TODO: REPLACE enum InputEventChar: SwiftProtobuf.Enum { typealias RawValue = Int + + /// + /// TODO: REPLACE case keyNone // = 0 + + /// + /// TODO: REPLACE case keyUp // = 17 + + /// + /// TODO: REPLACE case keyDown // = 18 + + /// + /// TODO: REPLACE case keyLeft // = 19 + + /// + /// TODO: REPLACE case keyRight // = 20 - /// '\n' + /// + /// '\n' case keySelect // = 10 + + /// + /// TODO: REPLACE case keyBack // = 27 + + /// + /// TODO: REPLACE case keyCancel // = 24 case UNRECOGNIZED(Int) @@ -610,6 +669,8 @@ struct RadioConfig { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// TODO: REPLACE var preferences: RadioConfig.UserPreferences { get {return _preferences ?? RadioConfig.UserPreferences()} set {_preferences = newValue} @@ -622,7 +683,7 @@ struct RadioConfig { var unknownFields = SwiftProtobuf.UnknownStorage() /// - /// See [software design](/software/other/sw-design.md) for more information on these preferences + /// See [software design](/docs/software/other/sw-design) 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 @@ -638,10 +699,9 @@ struct RadioConfig { /// /// We should send our position this often (but only if it has changed significantly) - /// Defaults to 15 minutes - var positionBroadcastSmart: Bool { - get {return _storage._positionBroadcastSmart} - set {_uniqueStorage()._positionBroadcastSmart = newValue} + var positionBroadcastSmartDisabled: Bool { + get {return _storage._positionBroadcastSmartDisabled} + set {_uniqueStorage()._positionBroadcastSmartDisabled = newValue} } /// @@ -653,7 +713,7 @@ struct RadioConfig { /// /// Power management state machine option. - /// See [power management](/software/other/power.md) for details. + /// See [power management](/docs/software/other/power) for details. /// 0 for default of 1 minute var waitBluetoothSecs: UInt32 { get {return _storage._waitBluetoothSecs} @@ -662,7 +722,7 @@ struct RadioConfig { /// /// Power management state machine option. - /// See [power management](/software/other/power.md) for details. + /// See [power management](/docs/software/other/power) for details. /// 0 for default of one minute var screenOnSecs: UInt32 { get {return _storage._screenOnSecs} @@ -671,7 +731,7 @@ struct RadioConfig { /// /// Power management state machine option. - /// See [power management](/software/other/power.md) for details. + /// See [power management](/docs/software/other/power) for details. /// 0 for default of 15 minutes /// IMPORTANT NOTE FOR DEVICE CLIENTS: YOU MUST SEND SOME SORT OF PACKET TO THE PHONE AT LEAST THIS OFTEN OR THE DEVICE WILL DECIDE YOU ARE GONE! var phoneTimeoutSecs: UInt32 { @@ -681,7 +741,7 @@ struct RadioConfig { /// /// Power management state machine option. - /// See [power management](/software/other/power.md) for details. + /// See [power management](/docs/software/other/power) for details. /// 0 for default of two hours, MAXUINT for disabled var phoneSdsTimeoutSec: UInt32 { get {return _storage._phoneSdsTimeoutSec} @@ -690,7 +750,7 @@ struct RadioConfig { /// /// Power management state machine option. - /// See [power management](/software/other/power.md) for details. + /// See [power management](/docs/software/other/power) for details. /// 0 for default of two hours, MAXUINT for disabled var meshSdsTimeoutSecs: UInt32 { get {return _storage._meshSdsTimeoutSecs} @@ -699,7 +759,7 @@ struct RadioConfig { /// /// Power management state machine option. - /// See [power management](/software/other/power.md) for details. + /// See [power management](/docs/software/other/power) for details. /// 0 for default of one year var sdsSecs: UInt32 { get {return _storage._sdsSecs} @@ -708,7 +768,7 @@ struct RadioConfig { /// /// Power management state machine option. - /// See [power management](/software/other/power.md) for details. + /// See [power management](/docs/software/other/power) for details. /// 0 for default of 3600 var lsSecs: UInt32 { get {return _storage._lsSecs} @@ -717,7 +777,7 @@ struct RadioConfig { /// /// Power management state machine option. - /// See [power management](/software/other/power.md) for details. + /// See [power management](/docs/software/other/power) for details. /// 0 for default of 10 seconds var minWakeSecs: UInt32 { get {return _storage._minWakeSecs} @@ -762,14 +822,10 @@ struct RadioConfig { } /// - /// Are we operating as a router. - /// Changes behavior in the following ways: - /// The device will only sleep for critically low battery level (i.e. always tries to stay alive for the mesh) - /// In the future routing decisions will preferentially route packets through nodes with this attribute (because assumed - /// good line of sight) - var isRouter: Bool { - get {return _storage._isRouter} - set {_uniqueStorage()._isRouter = newValue} + /// Sets the role of node + var role: Role { + get {return _storage._role} + set {_uniqueStorage()._role = newValue} } /// @@ -798,23 +854,21 @@ struct RadioConfig { } /// - /// How our location is shared with other nodes (or the local phone) - var locationShare: LocationSharing { - get {return _storage._locationShare} - set {_uniqueStorage()._locationShare = newValue} + /// Should we disbale location sharing with other nodes (or the local phone) + var locationShareDisabled: Bool { + get {return _storage._locationShareDisabled} + set {_uniqueStorage()._locationShareDisabled = newValue} } /// - /// How the GPS hardware in this unit is operated. - /// Note: This is independent of how our location is shared with other devices. - /// For that see LocationSharing - var gpsOperation: GpsOperation { - get {return _storage._gpsOperation} - set {_uniqueStorage()._gpsOperation = newValue} + /// Should the GPS be disabled for this node? + var gpsDisabled: Bool { + get {return _storage._gpsDisabled} + set {_uniqueStorage()._gpsDisabled = newValue} } /// - /// How often should we try to get GPS position (in seconds) when we are in GpsOpMobile mode? + /// How often should we try to get GPS position (in seconds) /// or zero for the default of once every 30 seconds /// or a very large value (maxint) to update only once at boot. var gpsUpdateInterval: UInt32 { @@ -916,179 +970,218 @@ struct RadioConfig { } /// - /// Preferences for the SerialPlugin - /// FIXME - Move this out of UserPreferences and into a section for plugin configuration. - var serialpluginEnabled: Bool { - get {return _storage._serialpluginEnabled} - set {_uniqueStorage()._serialpluginEnabled = newValue} - } - - var serialpluginEcho: Bool { - get {return _storage._serialpluginEcho} - set {_uniqueStorage()._serialpluginEcho = newValue} - } - - var serialpluginRxd: UInt32 { - get {return _storage._serialpluginRxd} - set {_uniqueStorage()._serialpluginRxd = newValue} - } - - var serialpluginTxd: UInt32 { - get {return _storage._serialpluginTxd} - set {_uniqueStorage()._serialpluginTxd = newValue} - } - - var serialpluginTimeout: UInt32 { - get {return _storage._serialpluginTimeout} - set {_uniqueStorage()._serialpluginTimeout = newValue} - } - - var serialpluginMode: UInt32 { - get {return _storage._serialpluginMode} - set {_uniqueStorage()._serialpluginMode = newValue} + /// Preferences for the SerialModule + /// FIXME - Move this out of UserPreferences and into a section for module configuration. + var serialModuleEnabled: Bool { + get {return _storage._serialModuleEnabled} + set {_uniqueStorage()._serialModuleEnabled = newValue} } /// - /// Preferences for the ExternalNotificationPlugin - /// FIXME - Move this out of UserPreferences and into a section for plugin configuration. - var extNotificationPluginEnabled: Bool { - get {return _storage._extNotificationPluginEnabled} - set {_uniqueStorage()._extNotificationPluginEnabled = newValue} - } - - var extNotificationPluginOutputMs: UInt32 { - get {return _storage._extNotificationPluginOutputMs} - set {_uniqueStorage()._extNotificationPluginOutputMs = newValue} - } - - var extNotificationPluginOutput: UInt32 { - get {return _storage._extNotificationPluginOutput} - set {_uniqueStorage()._extNotificationPluginOutput = newValue} - } - - var extNotificationPluginActive: Bool { - get {return _storage._extNotificationPluginActive} - set {_uniqueStorage()._extNotificationPluginActive = newValue} - } - - var extNotificationPluginAlertMessage: Bool { - get {return _storage._extNotificationPluginAlertMessage} - set {_uniqueStorage()._extNotificationPluginAlertMessage = newValue} - } - - var extNotificationPluginAlertBell: Bool { - get {return _storage._extNotificationPluginAlertBell} - set {_uniqueStorage()._extNotificationPluginAlertBell = newValue} + /// TODO: REPLACE + var serialModuleEcho: Bool { + get {return _storage._serialModuleEcho} + set {_uniqueStorage()._serialModuleEcho = newValue} } /// - /// Preferences for the RangeTestPlugin - /// FIXME - Move this out of UserPreferences and into a section for plugin configuration. - var rangeTestPluginEnabled: Bool { - get {return _storage._rangeTestPluginEnabled} - set {_uniqueStorage()._rangeTestPluginEnabled = newValue} - } - - var rangeTestPluginSender: UInt32 { - get {return _storage._rangeTestPluginSender} - set {_uniqueStorage()._rangeTestPluginSender = newValue} - } - - var rangeTestPluginSave: Bool { - get {return _storage._rangeTestPluginSave} - set {_uniqueStorage()._rangeTestPluginSave = newValue} + /// TODO: REPLACE + var serialModuleRxd: UInt32 { + get {return _storage._serialModuleRxd} + set {_uniqueStorage()._serialModuleRxd = newValue} } /// - /// Preferences for the StoreForwardPlugin - ///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} - } - - var storeForwardPluginHeartbeat: Bool { - get {return _storage._storeForwardPluginHeartbeat} - set {_uniqueStorage()._storeForwardPluginHeartbeat = newValue} - } - - var storeForwardPluginRecords: UInt32 { - get {return _storage._storeForwardPluginRecords} - set {_uniqueStorage()._storeForwardPluginRecords = newValue} - } - - var storeForwardPluginHistoryReturnMax: UInt32 { - get {return _storage._storeForwardPluginHistoryReturnMax} - set {_uniqueStorage()._storeForwardPluginHistoryReturnMax = newValue} - } - - var storeForwardPluginHistoryReturnWindow: UInt32 { - get {return _storage._storeForwardPluginHistoryReturnWindow} - set {_uniqueStorage()._storeForwardPluginHistoryReturnWindow = newValue} + /// TODO: REPLACE + var serialModuleTxd: UInt32 { + get {return _storage._serialModuleTxd} + set {_uniqueStorage()._serialModuleTxd = newValue} } /// - /// Preferences for the EnvironmentalMeasurement Plugin - /// FIXME - Move this out of UserPreferences and into a section for plugin configuration. - /// Enable/Disable the environmental measurement plugin measurement collection - var environmentalMeasurementPluginMeasurementEnabled: Bool { - get {return _storage._environmentalMeasurementPluginMeasurementEnabled} - set {_uniqueStorage()._environmentalMeasurementPluginMeasurementEnabled = newValue} + /// TODO: REPLACE + var serialModuleBaud: RadioConfig.UserPreferences.Serial_Baud { + get {return _storage._serialModuleBaud} + set {_uniqueStorage()._serialModuleBaud = newValue} } /// - /// Enable/Disable the environmental measurement plugin on-device display - var environmentalMeasurementPluginScreenEnabled: Bool { - get {return _storage._environmentalMeasurementPluginScreenEnabled} - set {_uniqueStorage()._environmentalMeasurementPluginScreenEnabled = newValue} + /// TODO: REPLACE + var serialModuleTimeout: UInt32 { + get {return _storage._serialModuleTimeout} + set {_uniqueStorage()._serialModuleTimeout = newValue} + } + + /// + /// TODO: REPLACE + var serialModuleMode: RadioConfig.UserPreferences.Serial_Mode { + get {return _storage._serialModuleMode} + set {_uniqueStorage()._serialModuleMode = newValue} + } + + /// + /// Preferences for the ExternalNotificationModule + /// FIXME - Move this out of UserPreferences and into a section for module configuration. + var extNotificationModuleEnabled: Bool { + get {return _storage._extNotificationModuleEnabled} + set {_uniqueStorage()._extNotificationModuleEnabled = newValue} + } + + /// + /// TODO: REPLACE + var extNotificationModuleOutputMs: UInt32 { + get {return _storage._extNotificationModuleOutputMs} + set {_uniqueStorage()._extNotificationModuleOutputMs = newValue} + } + + /// + /// TODO: REPLACE + var extNotificationModuleOutput: UInt32 { + get {return _storage._extNotificationModuleOutput} + set {_uniqueStorage()._extNotificationModuleOutput = newValue} + } + + /// + /// TODO: REPLACE + var extNotificationModuleActive: Bool { + get {return _storage._extNotificationModuleActive} + set {_uniqueStorage()._extNotificationModuleActive = newValue} + } + + /// + /// TODO: REPLACE + var extNotificationModuleAlertMessage: Bool { + get {return _storage._extNotificationModuleAlertMessage} + set {_uniqueStorage()._extNotificationModuleAlertMessage = newValue} + } + + /// + /// TODO: REPLACE + var extNotificationModuleAlertBell: Bool { + get {return _storage._extNotificationModuleAlertBell} + set {_uniqueStorage()._extNotificationModuleAlertBell = newValue} + } + + /// + /// Preferences for the RangeTestModule + /// FIXME - Move this out of UserPreferences and into a section for module configuration. + var rangeTestModuleEnabled: Bool { + get {return _storage._rangeTestModuleEnabled} + set {_uniqueStorage()._rangeTestModuleEnabled = newValue} + } + + /// + /// TODO: REPLACE + var rangeTestModuleSender: UInt32 { + get {return _storage._rangeTestModuleSender} + set {_uniqueStorage()._rangeTestModuleSender = newValue} + } + + /// + /// TODO: REPLACE + var rangeTestModuleSave: Bool { + get {return _storage._rangeTestModuleSave} + set {_uniqueStorage()._rangeTestModuleSave = newValue} + } + + /// + /// Preferences for the StoreForwardModule + ///FIXME - Move this out of UserPreferences and into a section for module configuration. (was 136) + var storeForwardModuleEnabled: Bool { + get {return _storage._storeForwardModuleEnabled} + set {_uniqueStorage()._storeForwardModuleEnabled = newValue} + } + + /// + /// TODO: REPLACE + var storeForwardModuleHeartbeat: Bool { + get {return _storage._storeForwardModuleHeartbeat} + set {_uniqueStorage()._storeForwardModuleHeartbeat = newValue} + } + + /// + /// TODO: REPLACE + var storeForwardModuleRecords: UInt32 { + get {return _storage._storeForwardModuleRecords} + set {_uniqueStorage()._storeForwardModuleRecords = newValue} + } + + /// + /// TODO: REPLACE + var storeForwardModuleHistoryReturnMax: UInt32 { + get {return _storage._storeForwardModuleHistoryReturnMax} + set {_uniqueStorage()._storeForwardModuleHistoryReturnMax = newValue} + } + + /// + /// TODO: REPLACE + var storeForwardModuleHistoryReturnWindow: UInt32 { + get {return _storage._storeForwardModuleHistoryReturnWindow} + set {_uniqueStorage()._storeForwardModuleHistoryReturnWindow = newValue} + } + + /// + /// Preferences for the Telemetry Module (Environment) + /// FIXME - Move this out of UserPreferences and into a section for module configuration. + /// Enable/Disable the telemetry measurement module measurement collection + var telemetryModuleEnvironmentMeasurementEnabled: Bool { + get {return _storage._telemetryModuleEnvironmentMeasurementEnabled} + set {_uniqueStorage()._telemetryModuleEnvironmentMeasurementEnabled = newValue} + } + + /// + /// Enable/Disable the telemetry measurement module on-device display + var telemetryModuleEnvironmentScreenEnabled: Bool { + get {return _storage._telemetryModuleEnvironmentScreenEnabled} + set {_uniqueStorage()._telemetryModuleEnvironmentScreenEnabled = newValue} } /// /// Sometimes sensor reads can fail. /// If this happens, we will retry a configurable number of attempts, /// each attempt will be delayed by the minimum required refresh rate for that sensor - var environmentalMeasurementPluginReadErrorCountThreshold: UInt32 { - get {return _storage._environmentalMeasurementPluginReadErrorCountThreshold} - set {_uniqueStorage()._environmentalMeasurementPluginReadErrorCountThreshold = newValue} + var telemetryModuleEnvironmentReadErrorCountThreshold: UInt32 { + get {return _storage._telemetryModuleEnvironmentReadErrorCountThreshold} + set {_uniqueStorage()._telemetryModuleEnvironmentReadErrorCountThreshold = newValue} } /// /// Interval in seconds of how often we should try to send our /// measurements to the mesh - var environmentalMeasurementPluginUpdateInterval: UInt32 { - get {return _storage._environmentalMeasurementPluginUpdateInterval} - set {_uniqueStorage()._environmentalMeasurementPluginUpdateInterval = newValue} + var telemetryModuleDeviceUpdateInterval: UInt32 { + get {return _storage._telemetryModuleDeviceUpdateInterval} + set {_uniqueStorage()._telemetryModuleDeviceUpdateInterval = newValue} } /// /// Sometimes we can end up with more than read_error_count_threshold failures. /// In this case, we will stop trying to read from the sensor for a while. /// Wait this long until trying to read from the sensor again - var environmentalMeasurementPluginRecoveryInterval: UInt32 { - get {return _storage._environmentalMeasurementPluginRecoveryInterval} - set {_uniqueStorage()._environmentalMeasurementPluginRecoveryInterval = newValue} + var telemetryModuleEnvironmentRecoveryInterval: UInt32 { + get {return _storage._telemetryModuleEnvironmentRecoveryInterval} + set {_uniqueStorage()._telemetryModuleEnvironmentRecoveryInterval = newValue} } /// /// We'll always read the sensor in Celsius, but sometimes we might want to - /// display the results in Farenheit as a "user preference". - var environmentalMeasurementPluginDisplayFarenheit: Bool { - get {return _storage._environmentalMeasurementPluginDisplayFarenheit} - set {_uniqueStorage()._environmentalMeasurementPluginDisplayFarenheit = newValue} + /// display the results in Fahrenheit as a "user preference". + var telemetryModuleEnvironmentDisplayFahrenheit: Bool { + get {return _storage._telemetryModuleEnvironmentDisplayFahrenheit} + set {_uniqueStorage()._telemetryModuleEnvironmentDisplayFahrenheit = newValue} } /// /// Specify the sensor type - var environmentalMeasurementPluginSensorType: RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType { - get {return _storage._environmentalMeasurementPluginSensorType} - set {_uniqueStorage()._environmentalMeasurementPluginSensorType = newValue} + var telemetryModuleEnvironmentSensorType: RadioConfig.UserPreferences.TelemetrySensorType { + get {return _storage._telemetryModuleEnvironmentSensorType} + set {_uniqueStorage()._telemetryModuleEnvironmentSensorType = newValue} } /// /// Specify the peferred GPIO Pin for sensor readings - var environmentalMeasurementPluginSensorPin: UInt32 { - get {return _storage._environmentalMeasurementPluginSensorPin} - set {_uniqueStorage()._environmentalMeasurementPluginSensorPin = newValue} + var telemetryModuleEnvironmentSensorPin: UInt32 { + get {return _storage._telemetryModuleEnvironmentSensorPin} + set {_uniqueStorage()._telemetryModuleEnvironmentSensorPin = newValue} } /// @@ -1163,7 +1256,7 @@ struct RadioConfig { } /// - /// Enable the rotary encoder #1 + /// Enable the rotary encoder #1. This is a 'dumb' encoder sending pulses on both A and B pins while rotating. var rotary1Enabled: Bool { get {return _storage._rotary1Enabled} set {_uniqueStorage()._rotary1Enabled = newValue} @@ -1171,77 +1264,74 @@ struct RadioConfig { /// /// GPIO pin for rotary encoder A port. - var rotary1PinA: UInt32 { - get {return _storage._rotary1PinA} - set {_uniqueStorage()._rotary1PinA = newValue} + var inputbrokerPinA: UInt32 { + get {return _storage._inputbrokerPinA} + set {_uniqueStorage()._inputbrokerPinA = newValue} } /// /// GPIO pin for rotary encoder B port. - var rotary1PinB: UInt32 { - get {return _storage._rotary1PinB} - set {_uniqueStorage()._rotary1PinB = newValue} + var inputbrokerPinB: UInt32 { + get {return _storage._inputbrokerPinB} + set {_uniqueStorage()._inputbrokerPinB = newValue} } /// /// GPIO pin for rotary encoder Press port. - var rotary1PinPress: UInt32 { - get {return _storage._rotary1PinPress} - set {_uniqueStorage()._rotary1PinPress = newValue} + var inputbrokerPinPress: UInt32 { + get {return _storage._inputbrokerPinPress} + set {_uniqueStorage()._inputbrokerPinPress = newValue} } /// /// Generate input event on CW of this kind. - var rotary1EventCw: InputEventChar { - get {return _storage._rotary1EventCw} - set {_uniqueStorage()._rotary1EventCw = newValue} + var inputbrokerEventCw: InputEventChar { + get {return _storage._inputbrokerEventCw} + set {_uniqueStorage()._inputbrokerEventCw = newValue} } /// /// Generate input event on CCW of this kind. - var rotary1EventCcw: InputEventChar { - get {return _storage._rotary1EventCcw} - set {_uniqueStorage()._rotary1EventCcw = newValue} + var inputbrokerEventCcw: InputEventChar { + get {return _storage._inputbrokerEventCcw} + set {_uniqueStorage()._inputbrokerEventCcw = newValue} } /// /// Generate input event on Press of this kind. - var rotary1EventPress: InputEventChar { - get {return _storage._rotary1EventPress} - set {_uniqueStorage()._rotary1EventPress = newValue} + var inputbrokerEventPress: InputEventChar { + get {return _storage._inputbrokerEventPress} + set {_uniqueStorage()._inputbrokerEventPress = newValue} } /// - /// Enable/disable CannedMessagePlugin. - var cannedMessagePluginEnabled: Bool { - get {return _storage._cannedMessagePluginEnabled} - set {_uniqueStorage()._cannedMessagePluginEnabled = newValue} + /// Enable the Up/Down/Select input device. Can be RAK rotary encoder or 3 buttons. Uses the a/b/press definitions from inputbroker. + var updown1Enabled: Bool { + get {return _storage._updown1Enabled} + set {_uniqueStorage()._updown1Enabled = newValue} } /// - /// Input event origin accepted by the canned message plugin. - /// Can be e.g. "rotEnc1" or keyword "_any" - var cannedMessagePluginAllowInputSource: String { - get {return _storage._cannedMessagePluginAllowInputSource} - set {_uniqueStorage()._cannedMessagePluginAllowInputSource = newValue} + /// Enable/disable CannedMessageModule. + var cannedMessageModuleEnabled: Bool { + get {return _storage._cannedMessageModuleEnabled} + set {_uniqueStorage()._cannedMessageModuleEnabled = newValue} } /// - /// Predefined messages for CannedMessagePlugin separated by '|' characters. - /// Note: Split out the messages out to their own messages because we want to store 1,000 characters. - /// and the entire message must fit within 256 bytes. - /// Not sure if we should deprecate this or just remove it since we're in dev phase. - var cannedMessagePluginMessages: String { - get {return _storage._cannedMessagePluginMessages} - set {_uniqueStorage()._cannedMessagePluginMessages = newValue} + /// Input event origin accepted by the canned message module. + /// Can be e.g. "rotEnc1", "upDownEnc1" or keyword "_any" + var cannedMessageModuleAllowInputSource: String { + get {return _storage._cannedMessageModuleAllowInputSource} + set {_uniqueStorage()._cannedMessageModuleAllowInputSource = newValue} } /// - /// CannedMessagePlugin also sends a bell character with the messages. - /// ExternalNotificationPlugin can benefit from this feature. - var cannedMessagePluginSendBell: Bool { - get {return _storage._cannedMessagePluginSendBell} - set {_uniqueStorage()._cannedMessagePluginSendBell = newValue} + /// CannedMessageModule also sends a bell character with the messages. + /// ExternalNotificationModule can benefit from this feature. + var cannedMessageModuleSendBell: Bool { + get {return _storage._cannedMessageModuleSendBell} + set {_uniqueStorage()._cannedMessageModuleSendBell = newValue} } /// @@ -1263,48 +1353,187 @@ struct RadioConfig { set {_uniqueStorage()._adcMultiplierOverride = newValue} } + /// + /// Interval in seconds of how often we should try to send our + /// environent measurements to the mesh + var telemetryModuleEnvironmentUpdateInterval: UInt32 { + get {return _storage._telemetryModuleEnvironmentUpdateInterval} + set {_uniqueStorage()._telemetryModuleEnvironmentUpdateInterval = newValue} + } + var unknownFields = SwiftProtobuf.UnknownStorage() - enum EnvironmentalMeasurementSensorType: SwiftProtobuf.Enum { + /// + /// TODO: REPLACE + enum Serial_Baud: SwiftProtobuf.Enum { typealias RawValue = Int - case dht11 // = 0 - case ds18B20 // = 1 - case dht12 // = 2 - case dht21 // = 3 - case dht22 // = 4 - case bme280 // = 5 - case bme680 // = 6 - case mcp9808 // = 7 + case baudDefault // = 0 + case baud2400 // = 1 + case baud4800 // = 2 + case baud9600 // = 3 + case baud19200 // = 4 + case baud38400 // = 5 + case baud57600 // = 6 + case baud115200 // = 7 + case baud230400 // = 8 + case baud460800 // = 9 + case baud576000 // = 10 + case baud921600 // = 11 case UNRECOGNIZED(Int) init() { - self = .dht11 + self = .baudDefault } init?(rawValue: Int) { switch rawValue { - case 0: self = .dht11 - case 1: self = .ds18B20 - case 2: self = .dht12 - case 3: self = .dht21 - case 4: self = .dht22 - case 5: self = .bme280 - case 6: self = .bme680 - case 7: self = .mcp9808 + case 0: self = .baudDefault + case 1: self = .baud2400 + case 2: self = .baud4800 + case 3: self = .baud9600 + case 4: self = .baud19200 + case 5: self = .baud38400 + case 6: self = .baud57600 + case 7: self = .baud115200 + case 8: self = .baud230400 + case 9: self = .baud460800 + case 10: self = .baud576000 + case 11: self = .baud921600 default: self = .UNRECOGNIZED(rawValue) } } var rawValue: Int { switch self { - case .dht11: return 0 - case .ds18B20: return 1 - case .dht12: return 2 - case .dht21: return 3 - case .dht22: return 4 - case .bme280: return 5 - case .bme680: return 6 - case .mcp9808: return 7 + case .baudDefault: return 0 + case .baud2400: return 1 + case .baud4800: return 2 + case .baud9600: return 3 + case .baud19200: return 4 + case .baud38400: return 5 + case .baud57600: return 6 + case .baud115200: return 7 + case .baud230400: return 8 + case .baud460800: return 9 + case .baud576000: return 10 + case .baud921600: return 11 + case .UNRECOGNIZED(let i): return i + } + } + + } + + /// + /// TODO: REPLACE + enum Serial_Mode: SwiftProtobuf.Enum { + typealias RawValue = Int + case modeDefault // = 0 + case modeSimple // = 1 + case modeProto // = 2 + case UNRECOGNIZED(Int) + + init() { + self = .modeDefault + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .modeDefault + case 1: self = .modeSimple + case 2: self = .modeProto + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .modeDefault: return 0 + case .modeSimple: return 1 + case .modeProto: return 2 + case .UNRECOGNIZED(let i): return i + } + } + + } + + /// + /// TODO: REPLACE + enum TelemetrySensorType: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// No external telemetry sensor + case none // = 0 + + /// + /// TODO: REPLACE + case dht11 // = 1 + + /// + /// TODO: REPLACE + case ds18B20 // = 2 + + /// + /// TODO: REPLACE + case dht12 // = 3 + + /// + /// TODO: REPLACE + case dht21 // = 4 + + /// + /// TODO: REPLACE + case dht22 // = 5 + + /// + /// TODO: REPLACE + case bme280 // = 6 + + /// + /// TODO: REPLACE + case bme680 // = 7 + + /// + /// TODO: REPLACE + case mcp9808 // = 8 + + /// + /// TODO: REPLACE + case shtc3 // = 9 + case UNRECOGNIZED(Int) + + init() { + self = .none + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .none + case 1: self = .dht11 + case 2: self = .ds18B20 + case 3: self = .dht12 + case 4: self = .dht21 + case 5: self = .dht22 + case 6: self = .bme280 + case 7: self = .bme680 + case 8: self = .mcp9808 + case 9: self = .shtc3 + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .none: return 0 + case .dht11: return 1 + case .ds18B20: return 2 + case .dht12: return 3 + case .dht21: return 4 + case .dht22: return 5 + case .bme280: return 6 + case .bme680: return 7 + case .mcp9808: return 8 + case .shtc3: return 9 case .UNRECOGNIZED(let i): return i } } @@ -1323,9 +1552,37 @@ struct RadioConfig { #if swift(>=4.2) -extension RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType: CaseIterable { +extension RadioConfig.UserPreferences.Serial_Baud: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. - static var allCases: [RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType] = [ + static var allCases: [RadioConfig.UserPreferences.Serial_Baud] = [ + .baudDefault, + .baud2400, + .baud4800, + .baud9600, + .baud19200, + .baud38400, + .baud57600, + .baud115200, + .baud230400, + .baud460800, + .baud576000, + .baud921600, + ] +} + +extension RadioConfig.UserPreferences.Serial_Mode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [RadioConfig.UserPreferences.Serial_Mode] = [ + .modeDefault, + .modeSimple, + .modeProto, + ] +} + +extension RadioConfig.UserPreferences.TelemetrySensorType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [RadioConfig.UserPreferences.TelemetrySensorType] = [ + .none, .dht11, .ds18B20, .dht12, @@ -1334,11 +1591,26 @@ extension RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType: CaseIt .bme280, .bme680, .mcp9808, + .shtc3, ] } #endif // swift(>=4.2) +#if swift(>=5.5) && canImport(_Concurrency) +extension RegionCode: @unchecked Sendable {} +extension Role: @unchecked Sendable {} +extension ChargeCurrent: @unchecked Sendable {} +extension GpsCoordinateFormat: @unchecked Sendable {} +extension PositionFlags: @unchecked Sendable {} +extension InputEventChar: @unchecked Sendable {} +extension RadioConfig: @unchecked Sendable {} +extension RadioConfig.UserPreferences: @unchecked Sendable {} +extension RadioConfig.UserPreferences.Serial_Baud: @unchecked Sendable {} +extension RadioConfig.UserPreferences.Serial_Mode: @unchecked Sendable {} +extension RadioConfig.UserPreferences.TelemetrySensorType: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. extension RegionCode: SwiftProtobuf._ProtoNameProviding { @@ -1346,13 +1618,23 @@ extension RegionCode: SwiftProtobuf._ProtoNameProviding { 0: .same(proto: "Unset"), 1: .same(proto: "US"), 2: .same(proto: "EU433"), - 3: .same(proto: "EU865"), + 3: .same(proto: "EU868"), 4: .same(proto: "CN"), 5: .same(proto: "JP"), 6: .same(proto: "ANZ"), 7: .same(proto: "KR"), 8: .same(proto: "TW"), 9: .same(proto: "RU"), + 10: .same(proto: "IN"), + 11: .same(proto: "NZ865"), + 12: .same(proto: "TH"), + ] +} + +extension Role: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "Default"), + 1: .same(proto: "Router"), ] } @@ -1378,16 +1660,6 @@ extension ChargeCurrent: SwiftProtobuf._ProtoNameProviding { ] } -extension GpsOperation: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "GpsOpUnset"), - 1: .same(proto: "GpsOpStationary"), - 2: .same(proto: "GpsOpMobile"), - 3: .same(proto: "GpsOpTimeOnly"), - 4: .same(proto: "GpsOpDisabled"), - ] -} - extension GpsCoordinateFormat: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 0: .same(proto: "GpsFormatDec"), @@ -1399,14 +1671,6 @@ extension GpsCoordinateFormat: SwiftProtobuf._ProtoNameProviding { ] } -extension LocationSharing: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "LocUnset"), - 1: .same(proto: "LocEnabled"), - 2: .same(proto: "LocDisabled"), - ] -} - extension PositionFlags: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 0: .same(proto: "POS_UNDEFINED"), @@ -1454,9 +1718,13 @@ extension RadioConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati } func traverse(visitor: inout V) throws { - if let v = self._preferences { + // 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 { try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } + } }() try unknownFields.traverse(visitor: &visitor) } @@ -1471,7 +1739,7 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes static let protoMessageName: String = RadioConfig.protoMessageName + ".UserPreferences" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .standard(proto: "position_broadcast_secs"), - 17: .standard(proto: "position_broadcast_smart"), + 17: .standard(proto: "position_broadcast_smart_disabled"), 2: .standard(proto: "send_owner_interval"), 4: .standard(proto: "wait_bluetooth_secs"), 5: .standard(proto: "screen_on_secs"), @@ -1486,12 +1754,12 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes 14: .standard(proto: "wifi_ap_mode"), 15: .same(proto: "region"), 16: .standard(proto: "charge_current"), - 37: .standard(proto: "is_router"), + 18: .same(proto: "role"), 38: .standard(proto: "is_low_power"), 39: .standard(proto: "fixed_position"), 40: .standard(proto: "serial_disabled"), - 32: .standard(proto: "location_share"), - 33: .standard(proto: "gps_operation"), + 32: .standard(proto: "location_share_disabled"), + 33: .standard(proto: "gps_disabled"), 34: .standard(proto: "gps_update_interval"), 36: .standard(proto: "gps_attempt_time"), 45: .standard(proto: "gps_accept_2d"), @@ -1503,34 +1771,35 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes 100: .standard(proto: "factory_reset"), 101: .standard(proto: "debug_log_enabled"), 103: .standard(proto: "ignore_incoming"), - 120: .standard(proto: "serialplugin_enabled"), - 121: .standard(proto: "serialplugin_echo"), - 122: .standard(proto: "serialplugin_rxd"), - 123: .standard(proto: "serialplugin_txd"), - 124: .standard(proto: "serialplugin_timeout"), - 125: .standard(proto: "serialplugin_mode"), - 126: .standard(proto: "ext_notification_plugin_enabled"), - 127: .standard(proto: "ext_notification_plugin_output_ms"), - 128: .standard(proto: "ext_notification_plugin_output"), - 129: .standard(proto: "ext_notification_plugin_active"), - 130: .standard(proto: "ext_notification_plugin_alert_message"), - 131: .standard(proto: "ext_notification_plugin_alert_bell"), - 132: .standard(proto: "range_test_plugin_enabled"), - 133: .standard(proto: "range_test_plugin_sender"), - 134: .standard(proto: "range_test_plugin_save"), - 148: .standard(proto: "store_forward_plugin_enabled"), - 149: .standard(proto: "store_forward_plugin_heartbeat"), - 137: .standard(proto: "store_forward_plugin_records"), - 138: .standard(proto: "store_forward_plugin_history_return_max"), - 139: .standard(proto: "store_forward_plugin_history_return_window"), - 140: .standard(proto: "environmental_measurement_plugin_measurement_enabled"), - 141: .standard(proto: "environmental_measurement_plugin_screen_enabled"), - 142: .standard(proto: "environmental_measurement_plugin_read_error_count_threshold"), - 143: .standard(proto: "environmental_measurement_plugin_update_interval"), - 144: .standard(proto: "environmental_measurement_plugin_recovery_interval"), - 145: .standard(proto: "environmental_measurement_plugin_display_farenheit"), - 146: .standard(proto: "environmental_measurement_plugin_sensor_type"), - 147: .standard(proto: "environmental_measurement_plugin_sensor_pin"), + 120: .standard(proto: "serial_module_enabled"), + 121: .standard(proto: "serial_module_echo"), + 122: .standard(proto: "serial_module_rxd"), + 123: .standard(proto: "serial_module_txd"), + 176: .standard(proto: "serial_module_baud"), + 124: .standard(proto: "serial_module_timeout"), + 125: .standard(proto: "serial_module_mode"), + 126: .standard(proto: "ext_notification_module_enabled"), + 127: .standard(proto: "ext_notification_module_output_ms"), + 128: .standard(proto: "ext_notification_module_output"), + 129: .standard(proto: "ext_notification_module_active"), + 130: .standard(proto: "ext_notification_module_alert_message"), + 131: .standard(proto: "ext_notification_module_alert_bell"), + 132: .standard(proto: "range_test_module_enabled"), + 133: .standard(proto: "range_test_module_sender"), + 134: .standard(proto: "range_test_module_save"), + 148: .standard(proto: "store_forward_module_enabled"), + 149: .standard(proto: "store_forward_module_heartbeat"), + 137: .standard(proto: "store_forward_module_records"), + 138: .standard(proto: "store_forward_module_history_return_max"), + 139: .standard(proto: "store_forward_module_history_return_window"), + 140: .standard(proto: "telemetry_module_environment_measurement_enabled"), + 141: .standard(proto: "telemetry_module_environment_screen_enabled"), + 142: .standard(proto: "telemetry_module_environment_read_error_count_threshold"), + 143: .standard(proto: "telemetry_module_device_update_interval"), + 144: .standard(proto: "telemetry_module_environment_recovery_interval"), + 145: .standard(proto: "telemetry_module_environment_display_fahrenheit"), + 146: .standard(proto: "telemetry_module_environment_sensor_type"), + 147: .standard(proto: "telemetry_module_environment_sensor_pin"), 150: .standard(proto: "position_flags"), 151: .standard(proto: "is_always_powered"), 152: .standard(proto: "auto_screen_carousel_secs"), @@ -1541,23 +1810,24 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes 157: .standard(proto: "is_lora_tx_disabled"), 158: .standard(proto: "is_power_saving"), 160: .standard(proto: "rotary1_enabled"), - 161: .standard(proto: "rotary1_pin_a"), - 162: .standard(proto: "rotary1_pin_b"), - 163: .standard(proto: "rotary1_pin_press"), - 164: .standard(proto: "rotary1_event_cw"), - 165: .standard(proto: "rotary1_event_ccw"), - 166: .standard(proto: "rotary1_event_press"), - 170: .standard(proto: "canned_message_plugin_enabled"), - 171: .standard(proto: "canned_message_plugin_allow_input_source"), - 172: .standard(proto: "canned_message_plugin_messages"), - 173: .standard(proto: "canned_message_plugin_send_bell"), + 161: .standard(proto: "inputbroker_pin_a"), + 162: .standard(proto: "inputbroker_pin_b"), + 163: .standard(proto: "inputbroker_pin_press"), + 164: .standard(proto: "inputbroker_event_cw"), + 165: .standard(proto: "inputbroker_event_ccw"), + 166: .standard(proto: "inputbroker_event_press"), + 167: .standard(proto: "updown1_enabled"), + 170: .standard(proto: "canned_message_module_enabled"), + 171: .standard(proto: "canned_message_module_allow_input_source"), + 173: .standard(proto: "canned_message_module_send_bell"), 174: .standard(proto: "mqtt_encryption_enabled"), 175: .standard(proto: "adc_multiplier_override"), + 177: .standard(proto: "telemetry_module_environment_update_interval"), ] fileprivate class _StorageClass { var _positionBroadcastSecs: UInt32 = 0 - var _positionBroadcastSmart: Bool = false + var _positionBroadcastSmartDisabled: Bool = false var _sendOwnerInterval: UInt32 = 0 var _waitBluetoothSecs: UInt32 = 0 var _screenOnSecs: UInt32 = 0 @@ -1572,12 +1842,12 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes var _wifiApMode: Bool = false var _region: RegionCode = .unset var _chargeCurrent: ChargeCurrent = .maunset - var _isRouter: Bool = false + var _role: Role = .default var _isLowPower: Bool = false var _fixedPosition: Bool = false var _serialDisabled: Bool = false - var _locationShare: LocationSharing = .locUnset - var _gpsOperation: GpsOperation = .gpsOpUnset + var _locationShareDisabled: Bool = false + var _gpsDisabled: Bool = false var _gpsUpdateInterval: UInt32 = 0 var _gpsAttemptTime: UInt32 = 0 var _gpsAccept2D: Bool = false @@ -1589,34 +1859,35 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes var _factoryReset: Bool = false var _debugLogEnabled: Bool = false var _ignoreIncoming: [UInt32] = [] - var _serialpluginEnabled: Bool = false - var _serialpluginEcho: Bool = false - var _serialpluginRxd: UInt32 = 0 - var _serialpluginTxd: UInt32 = 0 - var _serialpluginTimeout: UInt32 = 0 - var _serialpluginMode: UInt32 = 0 - var _extNotificationPluginEnabled: Bool = false - var _extNotificationPluginOutputMs: UInt32 = 0 - var _extNotificationPluginOutput: UInt32 = 0 - var _extNotificationPluginActive: Bool = false - var _extNotificationPluginAlertMessage: Bool = false - var _extNotificationPluginAlertBell: Bool = false - var _rangeTestPluginEnabled: Bool = false - var _rangeTestPluginSender: UInt32 = 0 - var _rangeTestPluginSave: Bool = false - var _storeForwardPluginEnabled: Bool = false - var _storeForwardPluginHeartbeat: Bool = false - var _storeForwardPluginRecords: UInt32 = 0 - var _storeForwardPluginHistoryReturnMax: UInt32 = 0 - var _storeForwardPluginHistoryReturnWindow: UInt32 = 0 - var _environmentalMeasurementPluginMeasurementEnabled: Bool = false - var _environmentalMeasurementPluginScreenEnabled: Bool = false - var _environmentalMeasurementPluginReadErrorCountThreshold: UInt32 = 0 - var _environmentalMeasurementPluginUpdateInterval: UInt32 = 0 - var _environmentalMeasurementPluginRecoveryInterval: UInt32 = 0 - var _environmentalMeasurementPluginDisplayFarenheit: Bool = false - var _environmentalMeasurementPluginSensorType: RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType = .dht11 - var _environmentalMeasurementPluginSensorPin: UInt32 = 0 + var _serialModuleEnabled: Bool = false + var _serialModuleEcho: Bool = false + var _serialModuleRxd: UInt32 = 0 + var _serialModuleTxd: UInt32 = 0 + var _serialModuleBaud: RadioConfig.UserPreferences.Serial_Baud = .baudDefault + var _serialModuleTimeout: UInt32 = 0 + var _serialModuleMode: RadioConfig.UserPreferences.Serial_Mode = .modeDefault + var _extNotificationModuleEnabled: Bool = false + var _extNotificationModuleOutputMs: UInt32 = 0 + var _extNotificationModuleOutput: UInt32 = 0 + var _extNotificationModuleActive: Bool = false + var _extNotificationModuleAlertMessage: Bool = false + var _extNotificationModuleAlertBell: Bool = false + var _rangeTestModuleEnabled: Bool = false + var _rangeTestModuleSender: UInt32 = 0 + var _rangeTestModuleSave: Bool = false + var _storeForwardModuleEnabled: Bool = false + var _storeForwardModuleHeartbeat: Bool = false + var _storeForwardModuleRecords: UInt32 = 0 + var _storeForwardModuleHistoryReturnMax: UInt32 = 0 + var _storeForwardModuleHistoryReturnWindow: UInt32 = 0 + var _telemetryModuleEnvironmentMeasurementEnabled: Bool = false + var _telemetryModuleEnvironmentScreenEnabled: Bool = false + var _telemetryModuleEnvironmentReadErrorCountThreshold: UInt32 = 0 + var _telemetryModuleDeviceUpdateInterval: UInt32 = 0 + var _telemetryModuleEnvironmentRecoveryInterval: UInt32 = 0 + var _telemetryModuleEnvironmentDisplayFahrenheit: Bool = false + var _telemetryModuleEnvironmentSensorType: RadioConfig.UserPreferences.TelemetrySensorType = .none + var _telemetryModuleEnvironmentSensorPin: UInt32 = 0 var _positionFlags: UInt32 = 0 var _isAlwaysPowered: Bool = false var _autoScreenCarouselSecs: UInt32 = 0 @@ -1627,18 +1898,19 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes var _isLoraTxDisabled: Bool = false var _isPowerSaving: Bool = false var _rotary1Enabled: Bool = false - var _rotary1PinA: UInt32 = 0 - var _rotary1PinB: UInt32 = 0 - var _rotary1PinPress: UInt32 = 0 - var _rotary1EventCw: InputEventChar = .keyNone - var _rotary1EventCcw: InputEventChar = .keyNone - var _rotary1EventPress: InputEventChar = .keyNone - var _cannedMessagePluginEnabled: Bool = false - var _cannedMessagePluginAllowInputSource: String = String() - var _cannedMessagePluginMessages: String = String() - var _cannedMessagePluginSendBell: Bool = false + var _inputbrokerPinA: UInt32 = 0 + var _inputbrokerPinB: UInt32 = 0 + var _inputbrokerPinPress: UInt32 = 0 + var _inputbrokerEventCw: InputEventChar = .keyNone + var _inputbrokerEventCcw: InputEventChar = .keyNone + var _inputbrokerEventPress: InputEventChar = .keyNone + var _updown1Enabled: Bool = false + var _cannedMessageModuleEnabled: Bool = false + var _cannedMessageModuleAllowInputSource: String = String() + var _cannedMessageModuleSendBell: Bool = false var _mqttEncryptionEnabled: Bool = false var _adcMultiplierOverride: Float = 0 + var _telemetryModuleEnvironmentUpdateInterval: UInt32 = 0 static let defaultInstance = _StorageClass() @@ -1646,7 +1918,7 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes init(copying source: _StorageClass) { _positionBroadcastSecs = source._positionBroadcastSecs - _positionBroadcastSmart = source._positionBroadcastSmart + _positionBroadcastSmartDisabled = source._positionBroadcastSmartDisabled _sendOwnerInterval = source._sendOwnerInterval _waitBluetoothSecs = source._waitBluetoothSecs _screenOnSecs = source._screenOnSecs @@ -1661,12 +1933,12 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes _wifiApMode = source._wifiApMode _region = source._region _chargeCurrent = source._chargeCurrent - _isRouter = source._isRouter + _role = source._role _isLowPower = source._isLowPower _fixedPosition = source._fixedPosition _serialDisabled = source._serialDisabled - _locationShare = source._locationShare - _gpsOperation = source._gpsOperation + _locationShareDisabled = source._locationShareDisabled + _gpsDisabled = source._gpsDisabled _gpsUpdateInterval = source._gpsUpdateInterval _gpsAttemptTime = source._gpsAttemptTime _gpsAccept2D = source._gpsAccept2D @@ -1678,34 +1950,35 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes _factoryReset = source._factoryReset _debugLogEnabled = source._debugLogEnabled _ignoreIncoming = source._ignoreIncoming - _serialpluginEnabled = source._serialpluginEnabled - _serialpluginEcho = source._serialpluginEcho - _serialpluginRxd = source._serialpluginRxd - _serialpluginTxd = source._serialpluginTxd - _serialpluginTimeout = source._serialpluginTimeout - _serialpluginMode = source._serialpluginMode - _extNotificationPluginEnabled = source._extNotificationPluginEnabled - _extNotificationPluginOutputMs = source._extNotificationPluginOutputMs - _extNotificationPluginOutput = source._extNotificationPluginOutput - _extNotificationPluginActive = source._extNotificationPluginActive - _extNotificationPluginAlertMessage = source._extNotificationPluginAlertMessage - _extNotificationPluginAlertBell = source._extNotificationPluginAlertBell - _rangeTestPluginEnabled = source._rangeTestPluginEnabled - _rangeTestPluginSender = source._rangeTestPluginSender - _rangeTestPluginSave = source._rangeTestPluginSave - _storeForwardPluginEnabled = source._storeForwardPluginEnabled - _storeForwardPluginHeartbeat = source._storeForwardPluginHeartbeat - _storeForwardPluginRecords = source._storeForwardPluginRecords - _storeForwardPluginHistoryReturnMax = source._storeForwardPluginHistoryReturnMax - _storeForwardPluginHistoryReturnWindow = source._storeForwardPluginHistoryReturnWindow - _environmentalMeasurementPluginMeasurementEnabled = source._environmentalMeasurementPluginMeasurementEnabled - _environmentalMeasurementPluginScreenEnabled = source._environmentalMeasurementPluginScreenEnabled - _environmentalMeasurementPluginReadErrorCountThreshold = source._environmentalMeasurementPluginReadErrorCountThreshold - _environmentalMeasurementPluginUpdateInterval = source._environmentalMeasurementPluginUpdateInterval - _environmentalMeasurementPluginRecoveryInterval = source._environmentalMeasurementPluginRecoveryInterval - _environmentalMeasurementPluginDisplayFarenheit = source._environmentalMeasurementPluginDisplayFarenheit - _environmentalMeasurementPluginSensorType = source._environmentalMeasurementPluginSensorType - _environmentalMeasurementPluginSensorPin = source._environmentalMeasurementPluginSensorPin + _serialModuleEnabled = source._serialModuleEnabled + _serialModuleEcho = source._serialModuleEcho + _serialModuleRxd = source._serialModuleRxd + _serialModuleTxd = source._serialModuleTxd + _serialModuleBaud = source._serialModuleBaud + _serialModuleTimeout = source._serialModuleTimeout + _serialModuleMode = source._serialModuleMode + _extNotificationModuleEnabled = source._extNotificationModuleEnabled + _extNotificationModuleOutputMs = source._extNotificationModuleOutputMs + _extNotificationModuleOutput = source._extNotificationModuleOutput + _extNotificationModuleActive = source._extNotificationModuleActive + _extNotificationModuleAlertMessage = source._extNotificationModuleAlertMessage + _extNotificationModuleAlertBell = source._extNotificationModuleAlertBell + _rangeTestModuleEnabled = source._rangeTestModuleEnabled + _rangeTestModuleSender = source._rangeTestModuleSender + _rangeTestModuleSave = source._rangeTestModuleSave + _storeForwardModuleEnabled = source._storeForwardModuleEnabled + _storeForwardModuleHeartbeat = source._storeForwardModuleHeartbeat + _storeForwardModuleRecords = source._storeForwardModuleRecords + _storeForwardModuleHistoryReturnMax = source._storeForwardModuleHistoryReturnMax + _storeForwardModuleHistoryReturnWindow = source._storeForwardModuleHistoryReturnWindow + _telemetryModuleEnvironmentMeasurementEnabled = source._telemetryModuleEnvironmentMeasurementEnabled + _telemetryModuleEnvironmentScreenEnabled = source._telemetryModuleEnvironmentScreenEnabled + _telemetryModuleEnvironmentReadErrorCountThreshold = source._telemetryModuleEnvironmentReadErrorCountThreshold + _telemetryModuleDeviceUpdateInterval = source._telemetryModuleDeviceUpdateInterval + _telemetryModuleEnvironmentRecoveryInterval = source._telemetryModuleEnvironmentRecoveryInterval + _telemetryModuleEnvironmentDisplayFahrenheit = source._telemetryModuleEnvironmentDisplayFahrenheit + _telemetryModuleEnvironmentSensorType = source._telemetryModuleEnvironmentSensorType + _telemetryModuleEnvironmentSensorPin = source._telemetryModuleEnvironmentSensorPin _positionFlags = source._positionFlags _isAlwaysPowered = source._isAlwaysPowered _autoScreenCarouselSecs = source._autoScreenCarouselSecs @@ -1716,18 +1989,19 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes _isLoraTxDisabled = source._isLoraTxDisabled _isPowerSaving = source._isPowerSaving _rotary1Enabled = source._rotary1Enabled - _rotary1PinA = source._rotary1PinA - _rotary1PinB = source._rotary1PinB - _rotary1PinPress = source._rotary1PinPress - _rotary1EventCw = source._rotary1EventCw - _rotary1EventCcw = source._rotary1EventCcw - _rotary1EventPress = source._rotary1EventPress - _cannedMessagePluginEnabled = source._cannedMessagePluginEnabled - _cannedMessagePluginAllowInputSource = source._cannedMessagePluginAllowInputSource - _cannedMessagePluginMessages = source._cannedMessagePluginMessages - _cannedMessagePluginSendBell = source._cannedMessagePluginSendBell + _inputbrokerPinA = source._inputbrokerPinA + _inputbrokerPinB = source._inputbrokerPinB + _inputbrokerPinPress = source._inputbrokerPinPress + _inputbrokerEventCw = source._inputbrokerEventCw + _inputbrokerEventCcw = source._inputbrokerEventCcw + _inputbrokerEventPress = source._inputbrokerEventPress + _updown1Enabled = source._updown1Enabled + _cannedMessageModuleEnabled = source._cannedMessageModuleEnabled + _cannedMessageModuleAllowInputSource = source._cannedMessageModuleAllowInputSource + _cannedMessageModuleSendBell = source._cannedMessageModuleSendBell _mqttEncryptionEnabled = source._mqttEncryptionEnabled _adcMultiplierOverride = source._adcMultiplierOverride + _telemetryModuleEnvironmentUpdateInterval = source._telemetryModuleEnvironmentUpdateInterval } } @@ -1761,12 +2035,12 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes case 14: try { try decoder.decodeSingularBoolField(value: &_storage._wifiApMode) }() case 15: try { try decoder.decodeSingularEnumField(value: &_storage._region) }() case 16: try { try decoder.decodeSingularEnumField(value: &_storage._chargeCurrent) }() - case 17: try { try decoder.decodeSingularBoolField(value: &_storage._positionBroadcastSmart) }() - case 32: try { try decoder.decodeSingularEnumField(value: &_storage._locationShare) }() - case 33: try { try decoder.decodeSingularEnumField(value: &_storage._gpsOperation) }() + case 17: try { try decoder.decodeSingularBoolField(value: &_storage._positionBroadcastSmartDisabled) }() + case 18: try { try decoder.decodeSingularEnumField(value: &_storage._role) }() + case 32: try { try decoder.decodeSingularBoolField(value: &_storage._locationShareDisabled) }() + case 33: try { try decoder.decodeSingularBoolField(value: &_storage._gpsDisabled) }() case 34: try { try decoder.decodeSingularUInt32Field(value: &_storage._gpsUpdateInterval) }() case 36: try { try decoder.decodeSingularUInt32Field(value: &_storage._gpsAttemptTime) }() - case 37: try { try decoder.decodeSingularBoolField(value: &_storage._isRouter) }() case 38: try { try decoder.decodeSingularBoolField(value: &_storage._isLowPower) }() case 39: try { try decoder.decodeSingularBoolField(value: &_storage._fixedPosition) }() case 40: try { try decoder.decodeSingularBoolField(value: &_storage._serialDisabled) }() @@ -1779,34 +2053,34 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes case 100: try { try decoder.decodeSingularBoolField(value: &_storage._factoryReset) }() case 101: try { try decoder.decodeSingularBoolField(value: &_storage._debugLogEnabled) }() case 103: try { try decoder.decodeRepeatedUInt32Field(value: &_storage._ignoreIncoming) }() - case 120: try { try decoder.decodeSingularBoolField(value: &_storage._serialpluginEnabled) }() - case 121: try { try decoder.decodeSingularBoolField(value: &_storage._serialpluginEcho) }() - case 122: try { try decoder.decodeSingularUInt32Field(value: &_storage._serialpluginRxd) }() - case 123: try { try decoder.decodeSingularUInt32Field(value: &_storage._serialpluginTxd) }() - case 124: try { try decoder.decodeSingularUInt32Field(value: &_storage._serialpluginTimeout) }() - case 125: try { try decoder.decodeSingularUInt32Field(value: &_storage._serialpluginMode) }() - case 126: try { try decoder.decodeSingularBoolField(value: &_storage._extNotificationPluginEnabled) }() - case 127: try { try decoder.decodeSingularUInt32Field(value: &_storage._extNotificationPluginOutputMs) }() - case 128: try { try decoder.decodeSingularUInt32Field(value: &_storage._extNotificationPluginOutput) }() - case 129: try { try decoder.decodeSingularBoolField(value: &_storage._extNotificationPluginActive) }() - case 130: try { try decoder.decodeSingularBoolField(value: &_storage._extNotificationPluginAlertMessage) }() - case 131: try { try decoder.decodeSingularBoolField(value: &_storage._extNotificationPluginAlertBell) }() - case 132: try { try decoder.decodeSingularBoolField(value: &_storage._rangeTestPluginEnabled) }() - case 133: try { try decoder.decodeSingularUInt32Field(value: &_storage._rangeTestPluginSender) }() - case 134: try { try decoder.decodeSingularBoolField(value: &_storage._rangeTestPluginSave) }() - case 137: try { try decoder.decodeSingularUInt32Field(value: &_storage._storeForwardPluginRecords) }() - case 138: try { try decoder.decodeSingularUInt32Field(value: &_storage._storeForwardPluginHistoryReturnMax) }() - case 139: try { try decoder.decodeSingularUInt32Field(value: &_storage._storeForwardPluginHistoryReturnWindow) }() - case 140: try { try decoder.decodeSingularBoolField(value: &_storage._environmentalMeasurementPluginMeasurementEnabled) }() - case 141: try { try decoder.decodeSingularBoolField(value: &_storage._environmentalMeasurementPluginScreenEnabled) }() - case 142: try { try decoder.decodeSingularUInt32Field(value: &_storage._environmentalMeasurementPluginReadErrorCountThreshold) }() - case 143: try { try decoder.decodeSingularUInt32Field(value: &_storage._environmentalMeasurementPluginUpdateInterval) }() - case 144: try { try decoder.decodeSingularUInt32Field(value: &_storage._environmentalMeasurementPluginRecoveryInterval) }() - case 145: try { try decoder.decodeSingularBoolField(value: &_storage._environmentalMeasurementPluginDisplayFarenheit) }() - case 146: try { try decoder.decodeSingularEnumField(value: &_storage._environmentalMeasurementPluginSensorType) }() - case 147: try { try decoder.decodeSingularUInt32Field(value: &_storage._environmentalMeasurementPluginSensorPin) }() - case 148: try { try decoder.decodeSingularBoolField(value: &_storage._storeForwardPluginEnabled) }() - case 149: try { try decoder.decodeSingularBoolField(value: &_storage._storeForwardPluginHeartbeat) }() + case 120: try { try decoder.decodeSingularBoolField(value: &_storage._serialModuleEnabled) }() + case 121: try { try decoder.decodeSingularBoolField(value: &_storage._serialModuleEcho) }() + case 122: try { try decoder.decodeSingularUInt32Field(value: &_storage._serialModuleRxd) }() + case 123: try { try decoder.decodeSingularUInt32Field(value: &_storage._serialModuleTxd) }() + case 124: try { try decoder.decodeSingularUInt32Field(value: &_storage._serialModuleTimeout) }() + case 125: try { try decoder.decodeSingularEnumField(value: &_storage._serialModuleMode) }() + case 126: try { try decoder.decodeSingularBoolField(value: &_storage._extNotificationModuleEnabled) }() + case 127: try { try decoder.decodeSingularUInt32Field(value: &_storage._extNotificationModuleOutputMs) }() + case 128: try { try decoder.decodeSingularUInt32Field(value: &_storage._extNotificationModuleOutput) }() + case 129: try { try decoder.decodeSingularBoolField(value: &_storage._extNotificationModuleActive) }() + case 130: try { try decoder.decodeSingularBoolField(value: &_storage._extNotificationModuleAlertMessage) }() + case 131: try { try decoder.decodeSingularBoolField(value: &_storage._extNotificationModuleAlertBell) }() + case 132: try { try decoder.decodeSingularBoolField(value: &_storage._rangeTestModuleEnabled) }() + case 133: try { try decoder.decodeSingularUInt32Field(value: &_storage._rangeTestModuleSender) }() + case 134: try { try decoder.decodeSingularBoolField(value: &_storage._rangeTestModuleSave) }() + case 137: try { try decoder.decodeSingularUInt32Field(value: &_storage._storeForwardModuleRecords) }() + case 138: try { try decoder.decodeSingularUInt32Field(value: &_storage._storeForwardModuleHistoryReturnMax) }() + case 139: try { try decoder.decodeSingularUInt32Field(value: &_storage._storeForwardModuleHistoryReturnWindow) }() + case 140: try { try decoder.decodeSingularBoolField(value: &_storage._telemetryModuleEnvironmentMeasurementEnabled) }() + case 141: try { try decoder.decodeSingularBoolField(value: &_storage._telemetryModuleEnvironmentScreenEnabled) }() + case 142: try { try decoder.decodeSingularUInt32Field(value: &_storage._telemetryModuleEnvironmentReadErrorCountThreshold) }() + case 143: try { try decoder.decodeSingularUInt32Field(value: &_storage._telemetryModuleDeviceUpdateInterval) }() + case 144: try { try decoder.decodeSingularUInt32Field(value: &_storage._telemetryModuleEnvironmentRecoveryInterval) }() + case 145: try { try decoder.decodeSingularBoolField(value: &_storage._telemetryModuleEnvironmentDisplayFahrenheit) }() + case 146: try { try decoder.decodeSingularEnumField(value: &_storage._telemetryModuleEnvironmentSensorType) }() + case 147: try { try decoder.decodeSingularUInt32Field(value: &_storage._telemetryModuleEnvironmentSensorPin) }() + case 148: try { try decoder.decodeSingularBoolField(value: &_storage._storeForwardModuleEnabled) }() + case 149: try { try decoder.decodeSingularBoolField(value: &_storage._storeForwardModuleHeartbeat) }() 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) }() @@ -1817,18 +2091,20 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes case 157: try { try decoder.decodeSingularBoolField(value: &_storage._isLoraTxDisabled) }() case 158: try { try decoder.decodeSingularBoolField(value: &_storage._isPowerSaving) }() case 160: try { try decoder.decodeSingularBoolField(value: &_storage._rotary1Enabled) }() - case 161: try { try decoder.decodeSingularUInt32Field(value: &_storage._rotary1PinA) }() - case 162: try { try decoder.decodeSingularUInt32Field(value: &_storage._rotary1PinB) }() - case 163: try { try decoder.decodeSingularUInt32Field(value: &_storage._rotary1PinPress) }() - case 164: try { try decoder.decodeSingularEnumField(value: &_storage._rotary1EventCw) }() - case 165: try { try decoder.decodeSingularEnumField(value: &_storage._rotary1EventCcw) }() - case 166: try { try decoder.decodeSingularEnumField(value: &_storage._rotary1EventPress) }() - case 170: try { try decoder.decodeSingularBoolField(value: &_storage._cannedMessagePluginEnabled) }() - case 171: try { try decoder.decodeSingularStringField(value: &_storage._cannedMessagePluginAllowInputSource) }() - case 172: try { try decoder.decodeSingularStringField(value: &_storage._cannedMessagePluginMessages) }() - case 173: try { try decoder.decodeSingularBoolField(value: &_storage._cannedMessagePluginSendBell) }() + case 161: try { try decoder.decodeSingularUInt32Field(value: &_storage._inputbrokerPinA) }() + case 162: try { try decoder.decodeSingularUInt32Field(value: &_storage._inputbrokerPinB) }() + case 163: try { try decoder.decodeSingularUInt32Field(value: &_storage._inputbrokerPinPress) }() + case 164: try { try decoder.decodeSingularEnumField(value: &_storage._inputbrokerEventCw) }() + case 165: try { try decoder.decodeSingularEnumField(value: &_storage._inputbrokerEventCcw) }() + case 166: try { try decoder.decodeSingularEnumField(value: &_storage._inputbrokerEventPress) }() + case 167: try { try decoder.decodeSingularBoolField(value: &_storage._updown1Enabled) }() + case 170: try { try decoder.decodeSingularBoolField(value: &_storage._cannedMessageModuleEnabled) }() + case 171: try { try decoder.decodeSingularStringField(value: &_storage._cannedMessageModuleAllowInputSource) }() + case 173: try { try decoder.decodeSingularBoolField(value: &_storage._cannedMessageModuleSendBell) }() case 174: try { try decoder.decodeSingularBoolField(value: &_storage._mqttEncryptionEnabled) }() case 175: try { try decoder.decodeSingularFloatField(value: &_storage._adcMultiplierOverride) }() + case 176: try { try decoder.decodeSingularEnumField(value: &_storage._serialModuleBaud) }() + case 177: try { try decoder.decodeSingularUInt32Field(value: &_storage._telemetryModuleEnvironmentUpdateInterval) }() default: break } } @@ -1882,14 +2158,17 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._chargeCurrent != .maunset { try visitor.visitSingularEnumField(value: _storage._chargeCurrent, fieldNumber: 16) } - if _storage._positionBroadcastSmart != false { - try visitor.visitSingularBoolField(value: _storage._positionBroadcastSmart, fieldNumber: 17) + if _storage._positionBroadcastSmartDisabled != false { + try visitor.visitSingularBoolField(value: _storage._positionBroadcastSmartDisabled, fieldNumber: 17) } - if _storage._locationShare != .locUnset { - try visitor.visitSingularEnumField(value: _storage._locationShare, fieldNumber: 32) + if _storage._role != .default { + try visitor.visitSingularEnumField(value: _storage._role, fieldNumber: 18) } - if _storage._gpsOperation != .gpsOpUnset { - try visitor.visitSingularEnumField(value: _storage._gpsOperation, fieldNumber: 33) + if _storage._locationShareDisabled != false { + try visitor.visitSingularBoolField(value: _storage._locationShareDisabled, fieldNumber: 32) + } + if _storage._gpsDisabled != false { + try visitor.visitSingularBoolField(value: _storage._gpsDisabled, fieldNumber: 33) } if _storage._gpsUpdateInterval != 0 { try visitor.visitSingularUInt32Field(value: _storage._gpsUpdateInterval, fieldNumber: 34) @@ -1897,9 +2176,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._gpsAttemptTime != 0 { try visitor.visitSingularUInt32Field(value: _storage._gpsAttemptTime, fieldNumber: 36) } - if _storage._isRouter != false { - try visitor.visitSingularBoolField(value: _storage._isRouter, fieldNumber: 37) - } if _storage._isLowPower != false { try visitor.visitSingularBoolField(value: _storage._isLowPower, fieldNumber: 38) } @@ -1936,89 +2212,89 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if !_storage._ignoreIncoming.isEmpty { try visitor.visitPackedUInt32Field(value: _storage._ignoreIncoming, fieldNumber: 103) } - if _storage._serialpluginEnabled != false { - try visitor.visitSingularBoolField(value: _storage._serialpluginEnabled, fieldNumber: 120) + if _storage._serialModuleEnabled != false { + try visitor.visitSingularBoolField(value: _storage._serialModuleEnabled, fieldNumber: 120) } - if _storage._serialpluginEcho != false { - try visitor.visitSingularBoolField(value: _storage._serialpluginEcho, fieldNumber: 121) + if _storage._serialModuleEcho != false { + try visitor.visitSingularBoolField(value: _storage._serialModuleEcho, fieldNumber: 121) } - if _storage._serialpluginRxd != 0 { - try visitor.visitSingularUInt32Field(value: _storage._serialpluginRxd, fieldNumber: 122) + if _storage._serialModuleRxd != 0 { + try visitor.visitSingularUInt32Field(value: _storage._serialModuleRxd, fieldNumber: 122) } - if _storage._serialpluginTxd != 0 { - try visitor.visitSingularUInt32Field(value: _storage._serialpluginTxd, fieldNumber: 123) + if _storage._serialModuleTxd != 0 { + try visitor.visitSingularUInt32Field(value: _storage._serialModuleTxd, fieldNumber: 123) } - if _storage._serialpluginTimeout != 0 { - try visitor.visitSingularUInt32Field(value: _storage._serialpluginTimeout, fieldNumber: 124) + if _storage._serialModuleTimeout != 0 { + try visitor.visitSingularUInt32Field(value: _storage._serialModuleTimeout, fieldNumber: 124) } - if _storage._serialpluginMode != 0 { - try visitor.visitSingularUInt32Field(value: _storage._serialpluginMode, fieldNumber: 125) + if _storage._serialModuleMode != .modeDefault { + try visitor.visitSingularEnumField(value: _storage._serialModuleMode, fieldNumber: 125) } - if _storage._extNotificationPluginEnabled != false { - try visitor.visitSingularBoolField(value: _storage._extNotificationPluginEnabled, fieldNumber: 126) + if _storage._extNotificationModuleEnabled != false { + try visitor.visitSingularBoolField(value: _storage._extNotificationModuleEnabled, fieldNumber: 126) } - if _storage._extNotificationPluginOutputMs != 0 { - try visitor.visitSingularUInt32Field(value: _storage._extNotificationPluginOutputMs, fieldNumber: 127) + if _storage._extNotificationModuleOutputMs != 0 { + try visitor.visitSingularUInt32Field(value: _storage._extNotificationModuleOutputMs, fieldNumber: 127) } - if _storage._extNotificationPluginOutput != 0 { - try visitor.visitSingularUInt32Field(value: _storage._extNotificationPluginOutput, fieldNumber: 128) + if _storage._extNotificationModuleOutput != 0 { + try visitor.visitSingularUInt32Field(value: _storage._extNotificationModuleOutput, fieldNumber: 128) } - if _storage._extNotificationPluginActive != false { - try visitor.visitSingularBoolField(value: _storage._extNotificationPluginActive, fieldNumber: 129) + if _storage._extNotificationModuleActive != false { + try visitor.visitSingularBoolField(value: _storage._extNotificationModuleActive, fieldNumber: 129) } - if _storage._extNotificationPluginAlertMessage != false { - try visitor.visitSingularBoolField(value: _storage._extNotificationPluginAlertMessage, fieldNumber: 130) + if _storage._extNotificationModuleAlertMessage != false { + try visitor.visitSingularBoolField(value: _storage._extNotificationModuleAlertMessage, fieldNumber: 130) } - if _storage._extNotificationPluginAlertBell != false { - try visitor.visitSingularBoolField(value: _storage._extNotificationPluginAlertBell, fieldNumber: 131) + if _storage._extNotificationModuleAlertBell != false { + try visitor.visitSingularBoolField(value: _storage._extNotificationModuleAlertBell, fieldNumber: 131) } - if _storage._rangeTestPluginEnabled != false { - try visitor.visitSingularBoolField(value: _storage._rangeTestPluginEnabled, fieldNumber: 132) + if _storage._rangeTestModuleEnabled != false { + try visitor.visitSingularBoolField(value: _storage._rangeTestModuleEnabled, fieldNumber: 132) } - if _storage._rangeTestPluginSender != 0 { - try visitor.visitSingularUInt32Field(value: _storage._rangeTestPluginSender, fieldNumber: 133) + if _storage._rangeTestModuleSender != 0 { + try visitor.visitSingularUInt32Field(value: _storage._rangeTestModuleSender, fieldNumber: 133) } - if _storage._rangeTestPluginSave != false { - try visitor.visitSingularBoolField(value: _storage._rangeTestPluginSave, fieldNumber: 134) + if _storage._rangeTestModuleSave != false { + try visitor.visitSingularBoolField(value: _storage._rangeTestModuleSave, fieldNumber: 134) } - if _storage._storeForwardPluginRecords != 0 { - try visitor.visitSingularUInt32Field(value: _storage._storeForwardPluginRecords, fieldNumber: 137) + if _storage._storeForwardModuleRecords != 0 { + try visitor.visitSingularUInt32Field(value: _storage._storeForwardModuleRecords, fieldNumber: 137) } - if _storage._storeForwardPluginHistoryReturnMax != 0 { - try visitor.visitSingularUInt32Field(value: _storage._storeForwardPluginHistoryReturnMax, fieldNumber: 138) + if _storage._storeForwardModuleHistoryReturnMax != 0 { + try visitor.visitSingularUInt32Field(value: _storage._storeForwardModuleHistoryReturnMax, fieldNumber: 138) } - if _storage._storeForwardPluginHistoryReturnWindow != 0 { - try visitor.visitSingularUInt32Field(value: _storage._storeForwardPluginHistoryReturnWindow, fieldNumber: 139) + if _storage._storeForwardModuleHistoryReturnWindow != 0 { + try visitor.visitSingularUInt32Field(value: _storage._storeForwardModuleHistoryReturnWindow, fieldNumber: 139) } - if _storage._environmentalMeasurementPluginMeasurementEnabled != false { - try visitor.visitSingularBoolField(value: _storage._environmentalMeasurementPluginMeasurementEnabled, fieldNumber: 140) + if _storage._telemetryModuleEnvironmentMeasurementEnabled != false { + try visitor.visitSingularBoolField(value: _storage._telemetryModuleEnvironmentMeasurementEnabled, fieldNumber: 140) } - if _storage._environmentalMeasurementPluginScreenEnabled != false { - try visitor.visitSingularBoolField(value: _storage._environmentalMeasurementPluginScreenEnabled, fieldNumber: 141) + if _storage._telemetryModuleEnvironmentScreenEnabled != false { + try visitor.visitSingularBoolField(value: _storage._telemetryModuleEnvironmentScreenEnabled, fieldNumber: 141) } - if _storage._environmentalMeasurementPluginReadErrorCountThreshold != 0 { - try visitor.visitSingularUInt32Field(value: _storage._environmentalMeasurementPluginReadErrorCountThreshold, fieldNumber: 142) + if _storage._telemetryModuleEnvironmentReadErrorCountThreshold != 0 { + try visitor.visitSingularUInt32Field(value: _storage._telemetryModuleEnvironmentReadErrorCountThreshold, fieldNumber: 142) } - if _storage._environmentalMeasurementPluginUpdateInterval != 0 { - try visitor.visitSingularUInt32Field(value: _storage._environmentalMeasurementPluginUpdateInterval, fieldNumber: 143) + if _storage._telemetryModuleDeviceUpdateInterval != 0 { + try visitor.visitSingularUInt32Field(value: _storage._telemetryModuleDeviceUpdateInterval, fieldNumber: 143) } - if _storage._environmentalMeasurementPluginRecoveryInterval != 0 { - try visitor.visitSingularUInt32Field(value: _storage._environmentalMeasurementPluginRecoveryInterval, fieldNumber: 144) + if _storage._telemetryModuleEnvironmentRecoveryInterval != 0 { + try visitor.visitSingularUInt32Field(value: _storage._telemetryModuleEnvironmentRecoveryInterval, fieldNumber: 144) } - if _storage._environmentalMeasurementPluginDisplayFarenheit != false { - try visitor.visitSingularBoolField(value: _storage._environmentalMeasurementPluginDisplayFarenheit, fieldNumber: 145) + if _storage._telemetryModuleEnvironmentDisplayFahrenheit != false { + try visitor.visitSingularBoolField(value: _storage._telemetryModuleEnvironmentDisplayFahrenheit, fieldNumber: 145) } - if _storage._environmentalMeasurementPluginSensorType != .dht11 { - try visitor.visitSingularEnumField(value: _storage._environmentalMeasurementPluginSensorType, fieldNumber: 146) + if _storage._telemetryModuleEnvironmentSensorType != .none { + try visitor.visitSingularEnumField(value: _storage._telemetryModuleEnvironmentSensorType, fieldNumber: 146) } - if _storage._environmentalMeasurementPluginSensorPin != 0 { - try visitor.visitSingularUInt32Field(value: _storage._environmentalMeasurementPluginSensorPin, fieldNumber: 147) + if _storage._telemetryModuleEnvironmentSensorPin != 0 { + try visitor.visitSingularUInt32Field(value: _storage._telemetryModuleEnvironmentSensorPin, fieldNumber: 147) } - if _storage._storeForwardPluginEnabled != false { - try visitor.visitSingularBoolField(value: _storage._storeForwardPluginEnabled, fieldNumber: 148) + if _storage._storeForwardModuleEnabled != false { + try visitor.visitSingularBoolField(value: _storage._storeForwardModuleEnabled, fieldNumber: 148) } - if _storage._storeForwardPluginHeartbeat != false { - try visitor.visitSingularBoolField(value: _storage._storeForwardPluginHeartbeat, fieldNumber: 149) + if _storage._storeForwardModuleHeartbeat != false { + try visitor.visitSingularBoolField(value: _storage._storeForwardModuleHeartbeat, fieldNumber: 149) } if _storage._positionFlags != 0 { try visitor.visitSingularUInt32Field(value: _storage._positionFlags, fieldNumber: 150) @@ -2050,35 +2326,35 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._rotary1Enabled != false { try visitor.visitSingularBoolField(value: _storage._rotary1Enabled, fieldNumber: 160) } - if _storage._rotary1PinA != 0 { - try visitor.visitSingularUInt32Field(value: _storage._rotary1PinA, fieldNumber: 161) + if _storage._inputbrokerPinA != 0 { + try visitor.visitSingularUInt32Field(value: _storage._inputbrokerPinA, fieldNumber: 161) } - if _storage._rotary1PinB != 0 { - try visitor.visitSingularUInt32Field(value: _storage._rotary1PinB, fieldNumber: 162) + if _storage._inputbrokerPinB != 0 { + try visitor.visitSingularUInt32Field(value: _storage._inputbrokerPinB, fieldNumber: 162) } - if _storage._rotary1PinPress != 0 { - try visitor.visitSingularUInt32Field(value: _storage._rotary1PinPress, fieldNumber: 163) + if _storage._inputbrokerPinPress != 0 { + try visitor.visitSingularUInt32Field(value: _storage._inputbrokerPinPress, fieldNumber: 163) } - if _storage._rotary1EventCw != .keyNone { - try visitor.visitSingularEnumField(value: _storage._rotary1EventCw, fieldNumber: 164) + if _storage._inputbrokerEventCw != .keyNone { + try visitor.visitSingularEnumField(value: _storage._inputbrokerEventCw, fieldNumber: 164) } - if _storage._rotary1EventCcw != .keyNone { - try visitor.visitSingularEnumField(value: _storage._rotary1EventCcw, fieldNumber: 165) + if _storage._inputbrokerEventCcw != .keyNone { + try visitor.visitSingularEnumField(value: _storage._inputbrokerEventCcw, fieldNumber: 165) } - if _storage._rotary1EventPress != .keyNone { - try visitor.visitSingularEnumField(value: _storage._rotary1EventPress, fieldNumber: 166) + if _storage._inputbrokerEventPress != .keyNone { + try visitor.visitSingularEnumField(value: _storage._inputbrokerEventPress, fieldNumber: 166) } - if _storage._cannedMessagePluginEnabled != false { - try visitor.visitSingularBoolField(value: _storage._cannedMessagePluginEnabled, fieldNumber: 170) + if _storage._updown1Enabled != false { + try visitor.visitSingularBoolField(value: _storage._updown1Enabled, fieldNumber: 167) } - if !_storage._cannedMessagePluginAllowInputSource.isEmpty { - try visitor.visitSingularStringField(value: _storage._cannedMessagePluginAllowInputSource, fieldNumber: 171) + if _storage._cannedMessageModuleEnabled != false { + try visitor.visitSingularBoolField(value: _storage._cannedMessageModuleEnabled, fieldNumber: 170) } - if !_storage._cannedMessagePluginMessages.isEmpty { - try visitor.visitSingularStringField(value: _storage._cannedMessagePluginMessages, fieldNumber: 172) + if !_storage._cannedMessageModuleAllowInputSource.isEmpty { + try visitor.visitSingularStringField(value: _storage._cannedMessageModuleAllowInputSource, fieldNumber: 171) } - if _storage._cannedMessagePluginSendBell != false { - try visitor.visitSingularBoolField(value: _storage._cannedMessagePluginSendBell, fieldNumber: 173) + if _storage._cannedMessageModuleSendBell != false { + try visitor.visitSingularBoolField(value: _storage._cannedMessageModuleSendBell, fieldNumber: 173) } if _storage._mqttEncryptionEnabled != false { try visitor.visitSingularBoolField(value: _storage._mqttEncryptionEnabled, fieldNumber: 174) @@ -2086,6 +2362,12 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._adcMultiplierOverride != 0 { try visitor.visitSingularFloatField(value: _storage._adcMultiplierOverride, fieldNumber: 175) } + if _storage._serialModuleBaud != .baudDefault { + try visitor.visitSingularEnumField(value: _storage._serialModuleBaud, fieldNumber: 176) + } + if _storage._telemetryModuleEnvironmentUpdateInterval != 0 { + try visitor.visitSingularUInt32Field(value: _storage._telemetryModuleEnvironmentUpdateInterval, fieldNumber: 177) + } } try unknownFields.traverse(visitor: &visitor) } @@ -2096,7 +2378,7 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes let _storage = _args.0 let rhs_storage = _args.1 if _storage._positionBroadcastSecs != rhs_storage._positionBroadcastSecs {return false} - if _storage._positionBroadcastSmart != rhs_storage._positionBroadcastSmart {return false} + if _storage._positionBroadcastSmartDisabled != rhs_storage._positionBroadcastSmartDisabled {return false} if _storage._sendOwnerInterval != rhs_storage._sendOwnerInterval {return false} if _storage._waitBluetoothSecs != rhs_storage._waitBluetoothSecs {return false} if _storage._screenOnSecs != rhs_storage._screenOnSecs {return false} @@ -2111,12 +2393,12 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._wifiApMode != rhs_storage._wifiApMode {return false} if _storage._region != rhs_storage._region {return false} if _storage._chargeCurrent != rhs_storage._chargeCurrent {return false} - if _storage._isRouter != rhs_storage._isRouter {return false} + if _storage._role != rhs_storage._role {return false} if _storage._isLowPower != rhs_storage._isLowPower {return false} if _storage._fixedPosition != rhs_storage._fixedPosition {return false} if _storage._serialDisabled != rhs_storage._serialDisabled {return false} - if _storage._locationShare != rhs_storage._locationShare {return false} - if _storage._gpsOperation != rhs_storage._gpsOperation {return false} + if _storage._locationShareDisabled != rhs_storage._locationShareDisabled {return false} + if _storage._gpsDisabled != rhs_storage._gpsDisabled {return false} if _storage._gpsUpdateInterval != rhs_storage._gpsUpdateInterval {return false} if _storage._gpsAttemptTime != rhs_storage._gpsAttemptTime {return false} if _storage._gpsAccept2D != rhs_storage._gpsAccept2D {return false} @@ -2128,34 +2410,35 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._factoryReset != rhs_storage._factoryReset {return false} if _storage._debugLogEnabled != rhs_storage._debugLogEnabled {return false} if _storage._ignoreIncoming != rhs_storage._ignoreIncoming {return false} - if _storage._serialpluginEnabled != rhs_storage._serialpluginEnabled {return false} - if _storage._serialpluginEcho != rhs_storage._serialpluginEcho {return false} - if _storage._serialpluginRxd != rhs_storage._serialpluginRxd {return false} - if _storage._serialpluginTxd != rhs_storage._serialpluginTxd {return false} - if _storage._serialpluginTimeout != rhs_storage._serialpluginTimeout {return false} - if _storage._serialpluginMode != rhs_storage._serialpluginMode {return false} - if _storage._extNotificationPluginEnabled != rhs_storage._extNotificationPluginEnabled {return false} - if _storage._extNotificationPluginOutputMs != rhs_storage._extNotificationPluginOutputMs {return false} - if _storage._extNotificationPluginOutput != rhs_storage._extNotificationPluginOutput {return false} - if _storage._extNotificationPluginActive != rhs_storage._extNotificationPluginActive {return false} - if _storage._extNotificationPluginAlertMessage != rhs_storage._extNotificationPluginAlertMessage {return false} - if _storage._extNotificationPluginAlertBell != rhs_storage._extNotificationPluginAlertBell {return false} - if _storage._rangeTestPluginEnabled != rhs_storage._rangeTestPluginEnabled {return false} - if _storage._rangeTestPluginSender != rhs_storage._rangeTestPluginSender {return false} - if _storage._rangeTestPluginSave != rhs_storage._rangeTestPluginSave {return false} - if _storage._storeForwardPluginEnabled != rhs_storage._storeForwardPluginEnabled {return false} - if _storage._storeForwardPluginHeartbeat != rhs_storage._storeForwardPluginHeartbeat {return false} - if _storage._storeForwardPluginRecords != rhs_storage._storeForwardPluginRecords {return false} - if _storage._storeForwardPluginHistoryReturnMax != rhs_storage._storeForwardPluginHistoryReturnMax {return false} - if _storage._storeForwardPluginHistoryReturnWindow != rhs_storage._storeForwardPluginHistoryReturnWindow {return false} - if _storage._environmentalMeasurementPluginMeasurementEnabled != rhs_storage._environmentalMeasurementPluginMeasurementEnabled {return false} - if _storage._environmentalMeasurementPluginScreenEnabled != rhs_storage._environmentalMeasurementPluginScreenEnabled {return false} - if _storage._environmentalMeasurementPluginReadErrorCountThreshold != rhs_storage._environmentalMeasurementPluginReadErrorCountThreshold {return false} - if _storage._environmentalMeasurementPluginUpdateInterval != rhs_storage._environmentalMeasurementPluginUpdateInterval {return false} - if _storage._environmentalMeasurementPluginRecoveryInterval != rhs_storage._environmentalMeasurementPluginRecoveryInterval {return false} - if _storage._environmentalMeasurementPluginDisplayFarenheit != rhs_storage._environmentalMeasurementPluginDisplayFarenheit {return false} - if _storage._environmentalMeasurementPluginSensorType != rhs_storage._environmentalMeasurementPluginSensorType {return false} - if _storage._environmentalMeasurementPluginSensorPin != rhs_storage._environmentalMeasurementPluginSensorPin {return false} + if _storage._serialModuleEnabled != rhs_storage._serialModuleEnabled {return false} + if _storage._serialModuleEcho != rhs_storage._serialModuleEcho {return false} + if _storage._serialModuleRxd != rhs_storage._serialModuleRxd {return false} + if _storage._serialModuleTxd != rhs_storage._serialModuleTxd {return false} + if _storage._serialModuleBaud != rhs_storage._serialModuleBaud {return false} + if _storage._serialModuleTimeout != rhs_storage._serialModuleTimeout {return false} + if _storage._serialModuleMode != rhs_storage._serialModuleMode {return false} + if _storage._extNotificationModuleEnabled != rhs_storage._extNotificationModuleEnabled {return false} + if _storage._extNotificationModuleOutputMs != rhs_storage._extNotificationModuleOutputMs {return false} + if _storage._extNotificationModuleOutput != rhs_storage._extNotificationModuleOutput {return false} + if _storage._extNotificationModuleActive != rhs_storage._extNotificationModuleActive {return false} + if _storage._extNotificationModuleAlertMessage != rhs_storage._extNotificationModuleAlertMessage {return false} + if _storage._extNotificationModuleAlertBell != rhs_storage._extNotificationModuleAlertBell {return false} + if _storage._rangeTestModuleEnabled != rhs_storage._rangeTestModuleEnabled {return false} + if _storage._rangeTestModuleSender != rhs_storage._rangeTestModuleSender {return false} + if _storage._rangeTestModuleSave != rhs_storage._rangeTestModuleSave {return false} + if _storage._storeForwardModuleEnabled != rhs_storage._storeForwardModuleEnabled {return false} + if _storage._storeForwardModuleHeartbeat != rhs_storage._storeForwardModuleHeartbeat {return false} + if _storage._storeForwardModuleRecords != rhs_storage._storeForwardModuleRecords {return false} + if _storage._storeForwardModuleHistoryReturnMax != rhs_storage._storeForwardModuleHistoryReturnMax {return false} + if _storage._storeForwardModuleHistoryReturnWindow != rhs_storage._storeForwardModuleHistoryReturnWindow {return false} + if _storage._telemetryModuleEnvironmentMeasurementEnabled != rhs_storage._telemetryModuleEnvironmentMeasurementEnabled {return false} + if _storage._telemetryModuleEnvironmentScreenEnabled != rhs_storage._telemetryModuleEnvironmentScreenEnabled {return false} + if _storage._telemetryModuleEnvironmentReadErrorCountThreshold != rhs_storage._telemetryModuleEnvironmentReadErrorCountThreshold {return false} + if _storage._telemetryModuleDeviceUpdateInterval != rhs_storage._telemetryModuleDeviceUpdateInterval {return false} + if _storage._telemetryModuleEnvironmentRecoveryInterval != rhs_storage._telemetryModuleEnvironmentRecoveryInterval {return false} + if _storage._telemetryModuleEnvironmentDisplayFahrenheit != rhs_storage._telemetryModuleEnvironmentDisplayFahrenheit {return false} + if _storage._telemetryModuleEnvironmentSensorType != rhs_storage._telemetryModuleEnvironmentSensorType {return false} + if _storage._telemetryModuleEnvironmentSensorPin != rhs_storage._telemetryModuleEnvironmentSensorPin {return false} if _storage._positionFlags != rhs_storage._positionFlags {return false} if _storage._isAlwaysPowered != rhs_storage._isAlwaysPowered {return false} if _storage._autoScreenCarouselSecs != rhs_storage._autoScreenCarouselSecs {return false} @@ -2166,18 +2449,19 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._isLoraTxDisabled != rhs_storage._isLoraTxDisabled {return false} if _storage._isPowerSaving != rhs_storage._isPowerSaving {return false} if _storage._rotary1Enabled != rhs_storage._rotary1Enabled {return false} - if _storage._rotary1PinA != rhs_storage._rotary1PinA {return false} - if _storage._rotary1PinB != rhs_storage._rotary1PinB {return false} - if _storage._rotary1PinPress != rhs_storage._rotary1PinPress {return false} - if _storage._rotary1EventCw != rhs_storage._rotary1EventCw {return false} - if _storage._rotary1EventCcw != rhs_storage._rotary1EventCcw {return false} - if _storage._rotary1EventPress != rhs_storage._rotary1EventPress {return false} - if _storage._cannedMessagePluginEnabled != rhs_storage._cannedMessagePluginEnabled {return false} - if _storage._cannedMessagePluginAllowInputSource != rhs_storage._cannedMessagePluginAllowInputSource {return false} - if _storage._cannedMessagePluginMessages != rhs_storage._cannedMessagePluginMessages {return false} - if _storage._cannedMessagePluginSendBell != rhs_storage._cannedMessagePluginSendBell {return false} + if _storage._inputbrokerPinA != rhs_storage._inputbrokerPinA {return false} + if _storage._inputbrokerPinB != rhs_storage._inputbrokerPinB {return false} + if _storage._inputbrokerPinPress != rhs_storage._inputbrokerPinPress {return false} + if _storage._inputbrokerEventCw != rhs_storage._inputbrokerEventCw {return false} + if _storage._inputbrokerEventCcw != rhs_storage._inputbrokerEventCcw {return false} + if _storage._inputbrokerEventPress != rhs_storage._inputbrokerEventPress {return false} + if _storage._updown1Enabled != rhs_storage._updown1Enabled {return false} + if _storage._cannedMessageModuleEnabled != rhs_storage._cannedMessageModuleEnabled {return false} + if _storage._cannedMessageModuleAllowInputSource != rhs_storage._cannedMessageModuleAllowInputSource {return false} + if _storage._cannedMessageModuleSendBell != rhs_storage._cannedMessageModuleSendBell {return false} if _storage._mqttEncryptionEnabled != rhs_storage._mqttEncryptionEnabled {return false} if _storage._adcMultiplierOverride != rhs_storage._adcMultiplierOverride {return false} + if _storage._telemetryModuleEnvironmentUpdateInterval != rhs_storage._telemetryModuleEnvironmentUpdateInterval {return false} return true } if !storagesAreEqual {return false} @@ -2187,15 +2471,42 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes } } -extension RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType: SwiftProtobuf._ProtoNameProviding { +extension RadioConfig.UserPreferences.Serial_Baud: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DHT11"), - 1: .same(proto: "DS18B20"), - 2: .same(proto: "DHT12"), - 3: .same(proto: "DHT21"), - 4: .same(proto: "DHT22"), - 5: .same(proto: "BME280"), - 6: .same(proto: "BME680"), - 7: .same(proto: "MCP9808"), + 0: .same(proto: "BAUD_Default"), + 1: .same(proto: "BAUD_2400"), + 2: .same(proto: "BAUD_4800"), + 3: .same(proto: "BAUD_9600"), + 4: .same(proto: "BAUD_19200"), + 5: .same(proto: "BAUD_38400"), + 6: .same(proto: "BAUD_57600"), + 7: .same(proto: "BAUD_115200"), + 8: .same(proto: "BAUD_230400"), + 9: .same(proto: "BAUD_460800"), + 10: .same(proto: "BAUD_576000"), + 11: .same(proto: "BAUD_921600"), + ] +} + +extension RadioConfig.UserPreferences.Serial_Mode: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "MODE_Default"), + 1: .same(proto: "MODE_SIMPLE"), + 2: .same(proto: "MODE_PROTO"), + ] +} + +extension RadioConfig.UserPreferences.TelemetrySensorType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "None"), + 1: .same(proto: "DHT11"), + 2: .same(proto: "DS18B20"), + 3: .same(proto: "DHT12"), + 4: .same(proto: "DHT21"), + 5: .same(proto: "DHT22"), + 6: .same(proto: "BME280"), + 7: .same(proto: "BME680"), + 8: .same(proto: "MCP9808"), + 9: .same(proto: "SHTC3"), ] } diff --git a/MeshtasticClient/Protobufs/remote_hardware.pb.swift b/MeshtasticClient/Protobufs/remote_hardware.pb.swift index 5a21328d..701fafc2 100644 --- a/MeshtasticClient/Protobufs/remote_hardware.pb.swift +++ b/MeshtasticClient/Protobufs/remote_hardware.pb.swift @@ -21,7 +21,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP } /// -/// An example app to show off the plugin system. This message is used for +/// An example app to show off the module system. This message is used for /// REMOTE_HARDWARE_APP PortNums. /// /// Also provides easy remote access to any GPIO. @@ -53,6 +53,8 @@ struct HardwareMessage { var unknownFields = SwiftProtobuf.UnknownStorage() + /// + /// TODO: REPLACE enum TypeEnum: SwiftProtobuf.Enum { typealias RawValue = Int @@ -132,6 +134,11 @@ extension HardwareMessage.TypeEnum: CaseIterable { #endif // swift(>=4.2) +#if swift(>=5.5) && canImport(_Concurrency) +extension HardwareMessage: @unchecked Sendable {} +extension HardwareMessage.TypeEnum: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. extension HardwareMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { diff --git a/MeshtasticClient/Protobufs/storeforward.pb.swift b/MeshtasticClient/Protobufs/storeforward.pb.swift index ceb9d9f8..b6df6719 100644 --- a/MeshtasticClient/Protobufs/storeforward.pb.swift +++ b/MeshtasticClient/Protobufs/storeforward.pb.swift @@ -20,13 +20,19 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } +/// +/// TODO: REPLACE 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. + /// + /// TODO: REPLACE var rr: StoreAndForward.RequestResponse = .unset + /// + /// TODO: REPLACE var stats: StoreAndForward.Statistics { get {return _stats ?? StoreAndForward.Statistics()} set {_stats = newValue} @@ -36,6 +42,8 @@ struct StoreAndForward { /// Clears the value of `stats`. Subsequent reads from it will return its default value. mutating func clearStats() {self._stats = nil} + /// + /// TODO: REPLACE var history: StoreAndForward.History { get {return _history ?? StoreAndForward.History()} set {_history = newValue} @@ -45,6 +53,8 @@ struct StoreAndForward { /// Clears the value of `history`. Subsequent reads from it will return its default value. mutating func clearHistory() {self._history = nil} + /// + /// TODO: REPLACE var heartbeat: StoreAndForward.Heartbeat { get {return _heartbeat ?? StoreAndForward.Heartbeat()} set {_heartbeat = newValue} @@ -161,6 +171,8 @@ struct StoreAndForward { } + /// + /// TODO: REPLACE struct Statistics { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -207,6 +219,8 @@ struct StoreAndForward { init() {} } + /// + /// TODO: REPLACE struct History { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -229,6 +243,8 @@ struct StoreAndForward { init() {} } + /// + /// TODO: REPLACE struct Heartbeat { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -277,6 +293,14 @@ extension StoreAndForward.RequestResponse: CaseIterable { #endif // swift(>=4.2) +#if swift(>=5.5) && canImport(_Concurrency) +extension StoreAndForward: @unchecked Sendable {} +extension StoreAndForward.RequestResponse: @unchecked Sendable {} +extension StoreAndForward.Statistics: @unchecked Sendable {} +extension StoreAndForward.History: @unchecked Sendable {} +extension StoreAndForward.Heartbeat: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. extension StoreAndForward: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { @@ -304,18 +328,22 @@ extension StoreAndForward: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen } 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) } - if let v = self._stats { + try { if let v = self._stats { try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } - if let v = self._history { + } }() + try { if let v = self._history { try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } - if let v = self._heartbeat { + } }() + try { if let v = self._heartbeat { try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - } + } }() try unknownFields.traverse(visitor: &visitor) } diff --git a/MeshtasticClient/Protobufs/telemetry.pb.swift b/MeshtasticClient/Protobufs/telemetry.pb.swift new file mode 100644 index 00000000..9f22221c --- /dev/null +++ b/MeshtasticClient/Protobufs/telemetry.pb.swift @@ -0,0 +1,352 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: telemetry.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// 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. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// +/// Key native device metrics such as battery level +struct DeviceMetrics { + // 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. + + /// + /// 1-100 (0 means powered) + var batteryLevel: UInt32 = 0 + + /// + /// Voltage measured + var voltage: Float = 0 + + /// + /// Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). + var channelUtilization: Float = 0 + + /// + /// Percent of airtime for transmission used within the last hour. + var airUtilTx: Float = 0 + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +/// +/// Weather station or other environmental metrics +struct EnvironmentMetrics { + // 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. + + /// + /// Temperature measured + var temperature: Float = 0 + + /// + /// Relative humidity percent measured + var relativeHumidity: Float = 0 + + /// + /// Barometric pressure in hPA measured + var barometricPressure: Float = 0 + + /// + /// Gas resistance in mOhm measured + var gasResistance: Float = 0 + + /// + /// Voltage measured + var voltage: Float = 0 + + /// + /// Current measured + var current: Float = 0 + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +/// +/// Types of Measurements the telemetry module is equipped to handle +struct Telemetry { + // 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. + + /// + /// This is usually not sent over the mesh (to save space), but it is sent + /// from the phone so that the local device can set its RTC If it is sent over + /// the mesh (because there are devices on the mesh without GPS), it will only + /// be sent by devices which has a hardware GPS clock (IE Mobile Phone). + /// seconds since 1970 + var time: UInt32 = 0 + + var variant: Telemetry.OneOf_Variant? = nil + + /// + /// Key native device metrics such as battery level + var deviceMetrics: DeviceMetrics { + get { + if case .deviceMetrics(let v)? = variant {return v} + return DeviceMetrics() + } + set {variant = .deviceMetrics(newValue)} + } + + /// + /// Weather station or other environmental metrics + var environmentMetrics: EnvironmentMetrics { + get { + if case .environmentMetrics(let v)? = variant {return v} + return EnvironmentMetrics() + } + set {variant = .environmentMetrics(newValue)} + } + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum OneOf_Variant: Equatable { + /// + /// Key native device metrics such as battery level + case deviceMetrics(DeviceMetrics) + /// + /// Weather station or other environmental metrics + case environmentMetrics(EnvironmentMetrics) + + #if !swift(>=4.1) + static func ==(lhs: Telemetry.OneOf_Variant, rhs: Telemetry.OneOf_Variant) -> Bool { + // 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 (lhs, rhs) { + case (.deviceMetrics, .deviceMetrics): return { + guard case .deviceMetrics(let l) = lhs, case .deviceMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.environmentMetrics, .environmentMetrics): return { + guard case .environmentMetrics(let l) = lhs, case .environmentMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif + } + + init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension DeviceMetrics: @unchecked Sendable {} +extension EnvironmentMetrics: @unchecked Sendable {} +extension Telemetry: @unchecked Sendable {} +extension Telemetry.OneOf_Variant: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +extension DeviceMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = "DeviceMetrics" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "battery_level"), + 2: .same(proto: "voltage"), + 3: .standard(proto: "channel_utilization"), + 4: .standard(proto: "air_util_tx"), + ] + + 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.batteryLevel) }() + case 2: try { try decoder.decodeSingularFloatField(value: &self.voltage) }() + case 3: try { try decoder.decodeSingularFloatField(value: &self.channelUtilization) }() + case 4: try { try decoder.decodeSingularFloatField(value: &self.airUtilTx) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.batteryLevel != 0 { + try visitor.visitSingularUInt32Field(value: self.batteryLevel, fieldNumber: 1) + } + if self.voltage != 0 { + try visitor.visitSingularFloatField(value: self.voltage, fieldNumber: 2) + } + if self.channelUtilization != 0 { + try visitor.visitSingularFloatField(value: self.channelUtilization, fieldNumber: 3) + } + if self.airUtilTx != 0 { + try visitor.visitSingularFloatField(value: self.airUtilTx, fieldNumber: 4) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: DeviceMetrics, rhs: DeviceMetrics) -> Bool { + if lhs.batteryLevel != rhs.batteryLevel {return false} + if lhs.voltage != rhs.voltage {return false} + if lhs.channelUtilization != rhs.channelUtilization {return false} + if lhs.airUtilTx != rhs.airUtilTx {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = "EnvironmentMetrics" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "temperature"), + 2: .standard(proto: "relative_humidity"), + 3: .standard(proto: "barometric_pressure"), + 4: .standard(proto: "gas_resistance"), + 5: .same(proto: "voltage"), + 6: .same(proto: "current"), + ] + + 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.decodeSingularFloatField(value: &self.temperature) }() + case 2: try { try decoder.decodeSingularFloatField(value: &self.relativeHumidity) }() + case 3: try { try decoder.decodeSingularFloatField(value: &self.barometricPressure) }() + case 4: try { try decoder.decodeSingularFloatField(value: &self.gasResistance) }() + case 5: try { try decoder.decodeSingularFloatField(value: &self.voltage) }() + case 6: try { try decoder.decodeSingularFloatField(value: &self.current) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.temperature != 0 { + try visitor.visitSingularFloatField(value: self.temperature, fieldNumber: 1) + } + if self.relativeHumidity != 0 { + try visitor.visitSingularFloatField(value: self.relativeHumidity, fieldNumber: 2) + } + if self.barometricPressure != 0 { + try visitor.visitSingularFloatField(value: self.barometricPressure, fieldNumber: 3) + } + if self.gasResistance != 0 { + try visitor.visitSingularFloatField(value: self.gasResistance, fieldNumber: 4) + } + if self.voltage != 0 { + try visitor.visitSingularFloatField(value: self.voltage, fieldNumber: 5) + } + if self.current != 0 { + try visitor.visitSingularFloatField(value: self.current, fieldNumber: 6) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: EnvironmentMetrics, rhs: EnvironmentMetrics) -> Bool { + if lhs.temperature != rhs.temperature {return false} + if lhs.relativeHumidity != rhs.relativeHumidity {return false} + if lhs.barometricPressure != rhs.barometricPressure {return false} + if lhs.gasResistance != rhs.gasResistance {return false} + if lhs.voltage != rhs.voltage {return false} + if lhs.current != rhs.current {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Telemetry: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = "Telemetry" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "time"), + 2: .standard(proto: "device_metrics"), + 3: .standard(proto: "environment_metrics"), + ] + + 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.time) }() + case 2: try { + var v: DeviceMetrics? + var hadOneofValue = false + if let current = self.variant { + hadOneofValue = true + if case .deviceMetrics(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .deviceMetrics(v) + } + }() + case 3: try { + var v: EnvironmentMetrics? + var hadOneofValue = false + if let current = self.variant { + hadOneofValue = true + if case .environmentMetrics(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .environmentMetrics(v) + } + }() + 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.time != 0 { + try visitor.visitSingularFixed32Field(value: self.time, fieldNumber: 1) + } + switch self.variant { + case .deviceMetrics?: try { + guard case .deviceMetrics(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + }() + case .environmentMetrics?: try { + guard case .environmentMetrics(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + }() + case nil: break + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Telemetry, rhs: Telemetry) -> Bool { + if lhs.time != rhs.time {return false} + if lhs.variant != rhs.variant {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/gen_protos.sh b/gen_protos.sh index 0f34f5e6..ec9f89be 100755 --- a/gen_protos.sh +++ b/gen_protos.sh @@ -15,7 +15,7 @@ fi pdir=$(realpath "../Meshtastic-protobufs") sdir=$(realpath "./MeshtasticClient/Protobufs") echo "pdir:$pdir sdir:$sdir" -pfiles="admin.proto apponly.proto cannedmessages.proto channel.proto deviceonly.proto environmental_measurement.proto mesh.proto mqtt.proto portnums.proto radioconfig.proto remote_hardware.proto storeforward.proto" +pfiles="admin.proto apponly.proto cannedmessages.proto channel.proto deviceonly.proto mesh.proto mqtt.proto portnums.proto radioconfig.proto remote_hardware.proto storeforward.proto telemetry.proto" for pf in $pfiles do echo "Generating $pf..." From 832241e1f30db5773f249982de837ee370873629 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 29 Mar 2022 21:16:15 -0700 Subject: [PATCH 02/21] Remove tapbacks replace with emoji --- Meshtastic Client.xcodeproj/project.pbxproj | 4 +- MeshtasticClient/Helpers/BLEManager.swift | 8 +- .../Meshtastic.xcdatamodeld/.xccurrentversion | 2 +- .../contents | 86 +++++++++++ .../Views/Messages/UserMessageList.swift | 16 +-- MeshtasticClient/Views/Nodes/NodeDetail.swift | 133 ++++++++---------- 6 files changed, 162 insertions(+), 87 deletions(-) create mode 100644 MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 42d90624..bd764e32 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -112,6 +112,7 @@ DDAF8C6826ED0D070058C060 /* deviceonly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = deviceonly.pb.swift; sourceTree = ""; }; DDAF8C6D26ED19040058C060 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; DDB2CC6D27F3EB47009C5FCC /* telemetry.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = telemetry.pb.swift; sourceTree = ""; }; + DDB2CC6F27F3F0AC009C5FCC /* MeshtasticDataModel v 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModel v 3.xcdatamodel"; sourceTree = ""; }; DDC2E15426CE248E0042C5E4 /* MeshtasticClient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeshtasticClient.app; sourceTree = BUILT_PRODUCTS_DIR; }; DDC2E15726CE248E0042C5E4 /* MeshtasticClientApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticClientApp.swift; sourceTree = ""; }; DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = ../Assets.xcassets; sourceTree = ""; }; @@ -942,10 +943,11 @@ DD9D8F2D2764403B00080993 /* Meshtastic.xcdatamodeld */ = { isa = XCVersionGroup; children = ( + DDB2CC6F27F3F0AC009C5FCC /* MeshtasticDataModel v 3.xcdatamodel */, DD45C77427BD4EF80011784F /* MeshtasticDataModel v2.xcdatamodel */, DD9D8F2E2764403B00080993 /* CoreDataSample.xcdatamodel */, ); - currentVersion = DD45C77427BD4EF80011784F /* MeshtasticDataModel v2.xcdatamodel */; + currentVersion = DDB2CC6F27F3F0AC009C5FCC /* MeshtasticDataModel v 3.xcdatamodel */; name = Meshtastic.xcdatamodeld; path = MeshtasticClient/Meshtastic.xcdatamodeld; sourceTree = ""; diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 551f9220..4f519aa2 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -705,7 +705,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } newMessage.receivedACK = false newMessage.direction = "IN" - newMessage.isTapback = decodedInfo.packet.decoded.emoji == 1 + newMessage.isEmoji = decodedInfo.packet.decoded.emoji == 1 if decodedInfo.packet.decoded.replyID > 0 { @@ -1010,7 +1010,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } // Send Message - public func sendMessage(message: String, toUserNum: Int64, isTapback: Bool, replyID: Int64) -> Bool { + public func sendMessage(message: String, toUserNum: Int64, isEmoji: Bool, replyID: Int64) -> Bool { var success = false @@ -1061,7 +1061,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph newMessage.receivedACK = false newMessage.direction = "IN" newMessage.toUser = fetchedUsers.first(where: { $0.num == toUserNum }) - newMessage.isTapback = isTapback + newMessage.isEmoji = isEmoji if replyID > 0 { @@ -1093,7 +1093,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph meshPacket.to = UInt32(toUserNum) meshPacket.from = UInt32(fromUserNum) meshPacket.decoded = dataMessage - meshPacket.decoded.emoji = isTapback ? 1 : 0 + meshPacket.decoded.emoji = isEmoji ? 1 : 0 if replyID > 0 { meshPacket.decoded.replyID = UInt32(replyID) } diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/.xccurrentversion b/MeshtasticClient/Meshtastic.xcdatamodeld/.xccurrentversion index b75edd3e..0ef73013 100644 --- a/MeshtasticClient/Meshtastic.xcdatamodeld/.xccurrentversion +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - MeshtasticDataModel v2.xcdatamodel + MeshtasticDataModel v 3.xcdatamodel diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents new file mode 100644 index 00000000..2769305d --- /dev/null +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MeshtasticClient/Views/Messages/UserMessageList.swift b/MeshtasticClient/Views/Messages/UserMessageList.swift index 11373df7..1d64cb66 100644 --- a/MeshtasticClient/Views/Messages/UserMessageList.swift +++ b/MeshtasticClient/Views/Messages/UserMessageList.swift @@ -101,7 +101,7 @@ struct UserMessageList: View { Button(action: { - if bleManager.sendMessage(message: "❤️", toUserNum: user.num, isTapback: true, replyID: message.messageId) { + if bleManager.sendMessage(message: "❤️", toUserNum: user.num, isEmoji: true, replyID: message.messageId) { print("Sent ❤️ Tapback") self.context.refresh(user, mergeChanges: true) @@ -115,7 +115,7 @@ struct UserMessageList: View { } Button(action: { - if bleManager.sendMessage(message: "👍", toUserNum: user.num, isTapback: true, replyID: message.messageId) { + if bleManager.sendMessage(message: "👍", toUserNum: user.num, isEmoji: true, replyID: message.messageId) { print("Sent 👍 Tapback") self.context.refresh(user, mergeChanges: true) @@ -129,7 +129,7 @@ struct UserMessageList: View { } Button(action: { - if bleManager.sendMessage(message: "👎", toUserNum: user.num, isTapback: true, replyID: message.messageId) { + if bleManager.sendMessage(message: "👎", toUserNum: user.num, isEmoji: true, replyID: message.messageId) { print("Sent 👎 Tapback") self.context.refresh(user, mergeChanges: true) @@ -143,7 +143,7 @@ struct UserMessageList: View { } Button(action: { - if bleManager.sendMessage(message: "🤣", toUserNum: user.num, isTapback: true, replyID: message.messageId) { + if bleManager.sendMessage(message: "🤣", toUserNum: user.num, isEmoji: true, replyID: message.messageId) { print("Sent 🤣 Tapback") self.context.refresh(user, mergeChanges: true) @@ -157,7 +157,7 @@ struct UserMessageList: View { } Button(action: { - if bleManager.sendMessage(message: "‼️", toUserNum: user.num, isTapback: true, replyID: message.messageId) { + if bleManager.sendMessage(message: "‼️", toUserNum: user.num, isEmoji: true, replyID: message.messageId) { print("Sent ‼️ Tapback") self.context.refresh(user, mergeChanges: true) @@ -171,7 +171,7 @@ struct UserMessageList: View { } Button(action: { - if bleManager.sendMessage(message: "❓", toUserNum: user.num, isTapback: true, replyID: message.messageId) { + if bleManager.sendMessage(message: "❓", toUserNum: user.num, isEmoji: true, replyID: message.messageId) { print("Sent ❓ Tapback") self.context.refresh(user, mergeChanges: true) @@ -185,7 +185,7 @@ struct UserMessageList: View { } Button(action: { - if bleManager.sendMessage(message: "💩", toUserNum: user.num, isTapback: true, replyID: message.messageId) { + if bleManager.sendMessage(message: "💩", toUserNum: user.num, isEmoji: true, replyID: message.messageId) { print("Sent 💩 Tapback") self.context.refresh(user, mergeChanges: true) @@ -434,7 +434,7 @@ struct UserMessageList: View { .padding(.bottom, 15) Button(action: { - if bleManager.sendMessage(message: typingMessage, toUserNum: user.num, isTapback: false, replyID: replyMessageId) { + if bleManager.sendMessage(message: typingMessage, toUserNum: user.num, isEmoji: false, replyID: replyMessageId) { typingMessage = "" focusedField = nil replyMessageId = 0 diff --git a/MeshtasticClient/Views/Nodes/NodeDetail.swift b/MeshtasticClient/Views/Nodes/NodeDetail.swift index f3ec3049..a6d96931 100644 --- a/MeshtasticClient/Views/Nodes/NodeDetail.swift +++ b/MeshtasticClient/Views/Nodes/NodeDetail.swift @@ -130,25 +130,9 @@ struct NodeDetail: View { VStack(alignment: .center) { - BatteryIcon(batteryLevel: mostRecent.batteryLevel, font: .title, color: .accentColor) + BatteryIcon(batteryLevel: 100, font: .title, color: .accentColor) .padding(.bottom) - if mostRecent.batteryLevel > 0 { - - Text("Battery") - .font(.title2) - .fixedSize() - .textCase(.uppercase) - Text(String(mostRecent.batteryLevel) + "%") - .font(.title2) - .foregroundColor(.gray) - .symbolRenderingMode(.hierarchical) - } else { - - Text("Powered") - .font(.callout) - .fixedSize() - .textCase(.uppercase) - } + } .padding(5) } @@ -207,63 +191,66 @@ struct NodeDetail: View { .padding() Divider() - ForEach(node.positions!.array as! [PositionEntity], id: \.self) { (mappin: PositionEntity) in - - if mappin.coordinate != nil { - - VStack { - - HStack { - - Image(systemName: "mappin.and.ellipse").foregroundColor(.accentColor) // .font(.subheadline) - Text("Lat/Long:").font(.caption) - Text("\(String(mappin.latitude ?? 0)) \(String(mappin.longitude ?? 0))") - .foregroundColor(.gray) - .font(.caption) - - Image(systemName: "arrow.up.arrow.down.circle") - .font(.subheadline) - .foregroundColor(.accentColor) - .symbolRenderingMode(.hierarchical) - - Text("Alt:") - .font(.caption) - - Text("\(String(mappin.altitude))m") - .foregroundColor(.gray) - .font(.caption) - } - HStack { - - Image(systemName: "clock.badge.checkmark.fill") - .font(.subheadline) - .foregroundColor(.accentColor) - .symbolRenderingMode(.hierarchical) - Text("Time:") - .font(.caption) - Text("\(mappin.time!, style: .date) \(mappin.time!, style: .time)") - .foregroundColor(.gray) - .font(.caption) - Divider() - - HStack { - - BatteryIcon(batteryLevel: mappin.batteryLevel, font: .subheadline, color: .accentColor) - - if mappin.batteryLevel > 0 { - - Text(String(mappin.batteryLevel) + "%") - .font(.caption2) - .foregroundColor(.gray) - } - } - } - } - .padding(1) - Divider() - } + + } +// ForEach(node.positions!.array as! [PositionEntity], id: \.self) { (mappin: PositionEntity) in +// +// if mappin.coordinate != nil { +// +// VStack { +// +// HStack { +// +// Image(systemName: "mappin.and.ellipse").foregroundColor(.accentColor) // .font(.subheadline) +// Text("Lat/Long:").font(.caption) +// Text("\(String(mappin.latitude ?? 0)) \(String(mappin.longitude ?? 0))") +// .foregroundColor(.gray) +// .font(.caption) +// +// Image(systemName: "arrow.up.arrow.down.circle") +// .font(.subheadline) +// .foregroundColor(.accentColor) +// .symbolRenderingMode(.hierarchical) +// +// Text("Alt:") +// .font(.caption) +// +// Text("\(String(mappin.altitude))m") +// .foregroundColor(.gray) +// .font(.caption) +// } +// HStack { +// +// Image(systemName: "clock.badge.checkmark.fill") +// .font(.subheadline) +// .foregroundColor(.accentColor) +// .symbolRenderingMode(.hierarchical) +// Text("Time:") +// .font(.caption) +// Text("\(mappin.time!, style: .date) \(mappin.time!, style: .time)") +// .foregroundColor(.gray) +// .font(.caption) +// Divider() +// +// HStack { +// +// BatteryIcon(batteryLevel: mappin.batteryLevel, font: .subheadline, color: .accentColor) +// +// if mappin.batteryLevel > 0 { +// +// Text(String(mappin.batteryLevel) + "%") +// .font(.caption2) +// .foregroundColor(.gray) +// } +// } +// } +// } +// .padding(1) +// Divider() +// } +// } } } } From 0ba625fa882a0aa93f555bafb2e7ef55c72f1894 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 2 Apr 2022 06:02:21 -0700 Subject: [PATCH 03/21] More 1.3 Photo updates --- MeshtasticClient/Helpers/BLEManager.swift | 6 ++ .../contents | 10 ++- .../Protobufs/cannedmessages.pb.swift | 19 ----- MeshtasticClient/Protobufs/channel.pb.swift | 22 ------ MeshtasticClient/Protobufs/mesh.pb.swift | 63 ++++----------- MeshtasticClient/Protobufs/portnums.pb.swift | 5 -- .../Protobufs/radioconfig.pb.swift | 77 ++++++++++--------- .../Protobufs/remote_hardware.pb.swift | 3 - .../Views/Bluetooth/Connect.swift | 2 +- 9 files changed, 67 insertions(+), 140 deletions(-) diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 4f519aa2..76bf93ff 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -513,6 +513,12 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let newNode = NodeInfoEntity(context: context!) newNode.id = Int64(decodedInfo.nodeInfo.num) newNode.num = Int64(decodedInfo.nodeInfo.num) + if decodedInfo.nodeInfo.hasDeviceMetrics { + newNode.batteryLevel = Int32(decodedInfo.nodeInfo.deviceMetrics.batteryLevel) + newNode.voltage = decodedInfo.nodeInfo.deviceMetrics.voltage + } + + if decodedInfo.nodeInfo.lastHeard > 0 { newNode.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.lastHeard))) } diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents index 2769305d..ae0f4abb 100644 --- a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -23,10 +23,12 @@ + + @@ -39,11 +41,13 @@ + + @@ -78,8 +82,8 @@ - - + + diff --git a/MeshtasticClient/Protobufs/cannedmessages.pb.swift b/MeshtasticClient/Protobufs/cannedmessages.pb.swift index dc943c33..6d544684 100644 --- a/MeshtasticClient/Protobufs/cannedmessages.pb.swift +++ b/MeshtasticClient/Protobufs/cannedmessages.pb.swift @@ -7,25 +7,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -/// -/// Meshtastic protobufs -/// -/// For more information on protobufs (and tools to use them with the language of your choice) see -/// https://developers.google.com/protocol-buffers/docs/proto3 -/// -/// We are not placing any of these defs inside a package, because if you do the -/// resulting nanopb version is super verbose package mesh. -/// -/// Protobuf build instructions: -/// -/// To build java classes for reading writing: -/// protoc -I=. --java_out /tmp mesh.proto -/// -/// To generate Nanopb c code: -/// /home/kevinh/packages/nanopb-0.4.0-linux-x86/generator-bin/protoc --nanopb_out=/tmp -I=app/src/main/proto mesh.proto -/// -/// Nanopb binaries available here: https://jpa.kapsi.fi/nanopb/download/ use nanopb 0.4.0 - import Foundation import SwiftProtobuf diff --git a/MeshtasticClient/Protobufs/channel.pb.swift b/MeshtasticClient/Protobufs/channel.pb.swift index 187de7b2..bb901196 100644 --- a/MeshtasticClient/Protobufs/channel.pb.swift +++ b/MeshtasticClient/Protobufs/channel.pb.swift @@ -7,25 +7,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -/// -/// Meshtastic protobufs -/// -/// For more information on protobufs (and tools to use them with the language of your choice) see -/// https://developers.google.com/protocol-buffers/docs/proto3 -/// -/// We are not placing any of these defs inside a package, because if you do the -/// resulting nanopb version is super verbose package mesh. -/// -/// Protobuf build instructions: -/// -/// To build java classes for reading writing: -/// protoc -I=. --java_out /tmp mesh.proto -/// -/// To generate Nanopb c code: -/// /home/kevinh/packages/nanopb-0.4.0-linux-x86/generator-bin/protoc --nanopb_out=/tmp -I=app/src/main/proto mesh.proto -/// -/// Nanopb binaries available here: https://jpa.kapsi.fi/nanopb/download/ use nanopb 0.4.0 - import Foundation import SwiftProtobuf @@ -56,7 +37,6 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// users COULD type in a channel name and be able to talk. /// Y is a lower case letter from a-z that represents the channel 'speed' settings /// (for some future definition of speed) -/// /// FIXME: Add description of multi-channel support and how primary vs secondary channels are used. /// FIXME: explain how apps use channels for security. /// explain how remote settings and remote gpio are managed as an example @@ -285,12 +265,10 @@ struct Channel { /// /// How this channel is being used (or not). - /// /// Note: this field is an enum to give us options for the future. /// In particular, someday we might make a 'SCANNING' option. /// SCANNING channels could have different frequencies and the radio would /// occasionally check that freq to see if anything is being transmitted. - /// /// For devices that have multiple physical radios attached, we could keep multiple PRIMARY/SCANNING channels active at once to allow /// cross band routing as needed. /// If a device has only a single radio (the common case) only one channel can be PRIMARY at a time diff --git a/MeshtasticClient/Protobufs/mesh.pb.swift b/MeshtasticClient/Protobufs/mesh.pb.swift index bf18f8ca..b72e9eb1 100644 --- a/MeshtasticClient/Protobufs/mesh.pb.swift +++ b/MeshtasticClient/Protobufs/mesh.pb.swift @@ -7,25 +7,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -/// -/// Meshtastic protobufs -/// -/// For more information on protobufs (and tools to use them with the language of your choice) see -/// https://developers.google.com/protocol-buffers/docs/proto3 -/// -/// We are not placing any of these defs inside a package, because if you do the -/// resulting nanopb version is super verbose package mesh. -/// -/// Protobuf build instructions: -/// -/// To build java classes for reading writing: -/// protoc -I=. --java_out /tmp mesh.proto -/// -/// To generate Nanopb c code: -/// /home/kevinh/packages/nanopb-0.4.0-linux-x86/generator-bin/protoc --nanopb_out=/tmp -I=app/src/main/proto mesh.proto -/// -/// Nanopb binaries available here: https://jpa.kapsi.fi/nanopb/download/ use nanopb 0.4.0 - import Foundation import SwiftProtobuf @@ -425,7 +406,6 @@ extension Constants: CaseIterable { /// /// Error codes for critical errors -/// /// The device might report these fault codes on the screen. /// If you encounter a fault code, please post on the meshtastic.discourse.group /// and we'll try to help. @@ -665,7 +645,6 @@ struct Position { /// /// Ground speed in m/s and True North TRACK in 1/100 degrees - /// /// Clarification of terms: /// - "track" is the direction of motion (measured in horizontal plane) /// - "heading" is where the fuselage points (measured in horizontal plane) @@ -868,24 +847,20 @@ extension Position.AltSource: CaseIterable { /// Broadcast when a newly powered mesh node wants to find a node num it can use /// Sent from the phone over bluetooth to set the user id for the owner of this node. /// Also sent from nodes to each other when a new node signs on (so all clients can have this info) -/// /// The algorithm is as follows: /// when a node starts up, it broadcasts their user and the normal flow is for all /// other nodes to reply with their User as well (so the new node can build its nodedb) /// If a node ever receives a User (not just the first broadcast) message where /// the sender node number equals our node number, that indicates a collision has /// occurred and the following steps should happen: -/// /// If the receiving node (that was already in the mesh)'s macaddr is LOWER than the /// new User who just tried to sign in: it gets to keep its nodenum. /// We send a broadcast message of OUR User (we use a broadcast so that the other node can /// receive our message, considering we have the same id - it also serves to let /// observers correct their nodedb) - this case is rare so it should be okay. -/// /// If any node receives a User where the macaddr is GTE than their local macaddr, /// they have been vetoed and should pick a new random nodenum (filtering against /// whatever it knows about the nodedb) and rebroadcast their User. -/// /// A few nodenums are reserved and will never be requested: /// 0xff - broadcast /// 0 through 3 - for future use @@ -1453,11 +1428,8 @@ struct MeshPacket { /// This field is never sent over the air, it is only used internally inside of a local device node. /// API clients (either on the local node or connected directly to the node) /// can set this parameter if necessary. - /// /// (values must be <= 127 to keep protobuf field to one byte in size. - /// /// Detailed background on this field: - /// /// I noticed a funny side effect of lora being so slow: Usually when making /// a protocol there isn’t much need to use message priority to change the order /// of transmission (because interfaces are fairly fast). @@ -1466,7 +1438,6 @@ struct MeshPacket { /// In the case of meshtastic that means we want to send protocol acks as soon as possible /// (to prevent unneeded retransmissions), we want routing messages to be sent next, /// then messages marked as reliable and finally ‘background’ packets like periodic position updates. - /// /// So I bit the bullet and implemented a new (internal - not sent over the air) /// field in MeshPacket called ‘priority’. /// And the transmission queue in the router object is now a priority queue. @@ -1612,16 +1583,12 @@ extension MeshPacket.Delayed: CaseIterable { /// /// The bluetooth to device link: -/// /// Old BTLE protocol docs from TODO, merge in above and make real docs... -/// /// use protocol buffers, and NanoPB -/// /// messages from device to phone: /// POSITION_UPDATE (..., time) /// TEXT_RECEIVED(from, text, time) /// OPAQUE_RECEIVED(from, payload, time) (for signal messages or other applications) -/// /// messages from phone to device: /// SET_MYID(id, human readable long, human readable short) (send down the unique ID /// string used for this node, a human readable string shown for that id, and a very @@ -1630,7 +1597,6 @@ extension MeshPacket.Delayed: CaseIterable { /// nodes() (returns list of nodes, with full info, last time seen, loc, battery /// level etc) SET_CONFIG (switches device to a new set of radio params and /// preshared key, drops all existing nodes, force our node to rejoin this new group) -/// /// Full information about a node on the mesh struct NodeInfo { // SwiftProtobuf.Message conformance is added in an extension below. See the @@ -1683,15 +1649,15 @@ struct NodeInfo { } /// - /// The latest device telemetry data for the node. - var telemetry: Telemetry { - get {return _storage._telemetry ?? Telemetry()} - set {_uniqueStorage()._telemetry = newValue} + /// The latest device metrics for the node. + var deviceMetrics: DeviceMetrics { + get {return _storage._deviceMetrics ?? DeviceMetrics()} + set {_uniqueStorage()._deviceMetrics = newValue} } - /// Returns true if `telemetry` has been explicitly set. - var hasTelemetry: Bool {return _storage._telemetry != nil} - /// Clears the value of `telemetry`. Subsequent reads from it will return its default value. - mutating func clearTelemetry() {_uniqueStorage()._telemetry = nil} + /// Returns true if `deviceMetrics` has been explicitly set. + var hasDeviceMetrics: Bool {return _storage._deviceMetrics != nil} + /// Clears the value of `deviceMetrics`. Subsequent reads from it will return its default value. + mutating func clearDeviceMetrics() {_uniqueStorage()._deviceMetrics = nil} var unknownFields = SwiftProtobuf.UnknownStorage() @@ -1856,7 +1822,6 @@ struct MyNodeInfo { /// /// Debug output from the device. -/// /// 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, @@ -3197,7 +3162,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB 3: .same(proto: "position"), 4: .same(proto: "snr"), 5: .standard(proto: "last_heard"), - 6: .same(proto: "telemetry"), + 6: .standard(proto: "device_metrics"), ] fileprivate class _StorageClass { @@ -3206,7 +3171,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB var _position: Position? = nil var _snr: Float = 0 var _lastHeard: UInt32 = 0 - var _telemetry: Telemetry? = nil + var _deviceMetrics: DeviceMetrics? = nil static let defaultInstance = _StorageClass() @@ -3218,7 +3183,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB _position = source._position _snr = source._snr _lastHeard = source._lastHeard - _telemetry = source._telemetry + _deviceMetrics = source._deviceMetrics } } @@ -3242,7 +3207,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB case 3: try { try decoder.decodeSingularMessageField(value: &_storage._position) }() case 4: try { try decoder.decodeSingularFloatField(value: &_storage._snr) }() case 5: try { try decoder.decodeSingularFixed32Field(value: &_storage._lastHeard) }() - case 6: try { try decoder.decodeSingularMessageField(value: &_storage._telemetry) }() + case 6: try { try decoder.decodeSingularMessageField(value: &_storage._deviceMetrics) }() default: break } } @@ -3270,7 +3235,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB if _storage._lastHeard != 0 { try visitor.visitSingularFixed32Field(value: _storage._lastHeard, fieldNumber: 5) } - try { if let v = _storage._telemetry { + try { if let v = _storage._deviceMetrics { try visitor.visitSingularMessageField(value: v, fieldNumber: 6) } }() } @@ -3287,7 +3252,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB if _storage._position != rhs_storage._position {return false} if _storage._snr != rhs_storage._snr {return false} if _storage._lastHeard != rhs_storage._lastHeard {return false} - if _storage._telemetry != rhs_storage._telemetry {return false} + if _storage._deviceMetrics != rhs_storage._deviceMetrics {return false} return true } if !storagesAreEqual {return false} diff --git a/MeshtasticClient/Protobufs/portnums.pb.swift b/MeshtasticClient/Protobufs/portnums.pb.swift index 175c4f66..57102fd2 100644 --- a/MeshtasticClient/Protobufs/portnums.pb.swift +++ b/MeshtasticClient/Protobufs/portnums.pb.swift @@ -23,19 +23,14 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// For any new 'apps' that run on the device or via sister apps on phones/PCs they should pick and use a /// unique 'portnum' for their application. -/// /// If you are making a new app using meshtastic, please send in a pull request to add your 'portnum' to this /// master table. /// PortNums should be assigned in the following range: -/// /// 0-63 Core Meshtastic use, do not use for third party apps /// 64-127 Registered 3rd party apps, send in a pull request that adds a new entry to portnums.proto to register your application /// 256-511 Use one of these portnums for your private applications that you don't want to register publically -/// /// All other values are reserved. -/// /// Note: This was formerly a Type enum named 'typ' with the same id # -/// /// We have change to this 'portnum' based scheme for specifying app handlers for particular payloads. /// This change is backwards compatible by treating the legacy OPAQUE/CLEAR_TEXT values identically. enum PortNum: SwiftProtobuf.Enum { diff --git a/MeshtasticClient/Protobufs/radioconfig.pb.swift b/MeshtasticClient/Protobufs/radioconfig.pb.swift index 2d77364f..76bf1efe 100644 --- a/MeshtasticClient/Protobufs/radioconfig.pb.swift +++ b/MeshtasticClient/Protobufs/radioconfig.pb.swift @@ -7,25 +7,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -/// -/// Meshtastic protobufs -/// -/// For more information on protobufs (and tools to use them with the language of your choice) see -/// https://developers.google.com/protocol-buffers/docs/proto3 -/// -/// We are not placing any of these defs inside a package, because if you do the -/// resulting nanopb version is super verbose package mesh. -/// -/// Protobuf build instructions: -/// -/// To build java classes for reading writing: -/// protoc -I=. --java_out /tmp mesh.proto -/// -/// To generate Nanopb c code: -/// /home/kevinh/packages/nanopb-0.4.0-linux-x86/generator-bin/protoc --nanopb_out=/tmp -I=app/src/main/proto mesh.proto -/// -/// Nanopb binaries available here: https://jpa.kapsi.fi/nanopb/download/ use nanopb 0.4.0 - import Foundation import SwiftProtobuf @@ -41,10 +22,8 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// The frequency/regulatory region the user has selected. -/// /// Note: In 1.0 builds (which must still be supported by the android app for a /// long time) this field will be unpopulated. -/// /// If firmware is ever upgraded from an old 1.0ish build, the old /// MyNodeInfo.region string will be used to set UserPreferences.region and the /// old value will be no longer set. @@ -175,37 +154,57 @@ extension RegionCode: CaseIterable { /// Defines the device's role on the Mesh network /// unset /// Behave normally. -/// /// Router /// Functions as a router enum Role: SwiftProtobuf.Enum { typealias RawValue = Int /// - /// Default device role - case `default` // = 0 + /// Client device role + case client // = 0 /// - /// Router device role - case router // = 1 + /// ClientMute device role + /// This is like the client but packets will not hop over this node. Would be + /// useful if you want to save power by not contributing to the mesh. + case clientMute // = 1 + + /// + /// Router device role. + /// Uses an agressive algirithem for the flood networking so packets will + /// prefer to be routed over this node. Also assume that this will be generally + /// unattended and so will turn off the wifi/ble radio as well as the oled screen. + case router // = 2 + + /// + /// RouterClient device role + /// Uses an agressive algirithem for the flood networking so packets will + /// prefer to be routed over this node. Similiar power management as a regular + /// client, so the RouterClient can be used as both a Router and a Client. Useful + /// as a well placed base station that you could also use to send messages. + case routerClient // = 3 case UNRECOGNIZED(Int) init() { - self = .default + self = .client } init?(rawValue: Int) { switch rawValue { - case 0: self = .default - case 1: self = .router + case 0: self = .client + case 1: self = .clientMute + case 2: self = .router + case 3: self = .routerClient default: self = .UNRECOGNIZED(rawValue) } } var rawValue: Int { switch self { - case .default: return 0 - case .router: return 1 + case .client: return 0 + case .clientMute: return 1 + case .router: return 2 + case .routerClient: return 3 case .UNRECOGNIZED(let i): return i } } @@ -217,8 +216,10 @@ enum Role: SwiftProtobuf.Enum { extension Role: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. static var allCases: [Role] = [ - .default, + .client, + .clientMute, .router, + .routerClient, ] } @@ -465,7 +466,6 @@ extension GpsCoordinateFormat: CaseIterable { /// 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) -/// /// NOTE: the more fields are included, the larger the message will be - /// leading to longer airtime and a higher risk of packet loss enum PositionFlags: SwiftProtobuf.Enum { @@ -1338,7 +1338,6 @@ struct RadioConfig { /// Whether to send encrypted or decrypted packets to MQTT. /// This parameter is only honoured if you also set mqtt_server /// (the default official mqtt.meshtastic.org server can handle encrypted packets) - /// /// Decrypted packets may be useful for external systems that want to consume meshtastic packets var mqttEncryptionEnabled: Bool { get {return _storage._mqttEncryptionEnabled} @@ -1633,8 +1632,10 @@ extension RegionCode: SwiftProtobuf._ProtoNameProviding { extension Role: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "Default"), - 1: .same(proto: "Router"), + 0: .same(proto: "Client"), + 1: .same(proto: "ClientMute"), + 2: .same(proto: "Router"), + 3: .same(proto: "RouterClient"), ] } @@ -1842,7 +1843,7 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes var _wifiApMode: Bool = false var _region: RegionCode = .unset var _chargeCurrent: ChargeCurrent = .maunset - var _role: Role = .default + var _role: Role = .client var _isLowPower: Bool = false var _fixedPosition: Bool = false var _serialDisabled: Bool = false @@ -2161,7 +2162,7 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._positionBroadcastSmartDisabled != false { try visitor.visitSingularBoolField(value: _storage._positionBroadcastSmartDisabled, fieldNumber: 17) } - if _storage._role != .default { + if _storage._role != .client { try visitor.visitSingularEnumField(value: _storage._role, fieldNumber: 18) } if _storage._locationShareDisabled != false { diff --git a/MeshtasticClient/Protobufs/remote_hardware.pb.swift b/MeshtasticClient/Protobufs/remote_hardware.pb.swift index 701fafc2..90af7dec 100644 --- a/MeshtasticClient/Protobufs/remote_hardware.pb.swift +++ b/MeshtasticClient/Protobufs/remote_hardware.pb.swift @@ -23,12 +23,9 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// An example app to show off the module system. This message is used for /// REMOTE_HARDWARE_APP PortNums. -/// /// Also provides easy remote access to any GPIO. -/// /// In the future other remote hardware operations can be added based on user interest /// (i.e. serial output, spi/i2c input/output). -/// /// FIXME - currently this feature is turned on by default which is dangerous /// because no security yet (beyond the channel mechanism). /// It should be off by default and then protected based on some TBD mechanism diff --git a/MeshtasticClient/Views/Bluetooth/Connect.swift b/MeshtasticClient/Views/Bluetooth/Connect.swift index e8a9dcc2..49386672 100644 --- a/MeshtasticClient/Views/Bluetooth/Connect.swift +++ b/MeshtasticClient/Views/Bluetooth/Connect.swift @@ -24,7 +24,7 @@ struct Connect: View { var body: some View { let firmwareVersion = bleManager.lastConnnectionVersion - let minimumVersion = "1.2.52" + let minimumVersion = "1.3.0" let supportedVersion = firmwareVersion == "0.0.0" || minimumVersion.compare(firmwareVersion, options: .numeric) == .orderedAscending || minimumVersion.compare(firmwareVersion, options: .numeric) == .orderedSame NavigationView { From e915a61e929a04aa82afa1a20556ab3947421f7e Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 3 Apr 2022 10:57:58 -0700 Subject: [PATCH 04/21] Telemetry changes for the core data entities --- .../MeshtasticDataModel v 3.xcdatamodel/contents | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents index ae0f4abb..7b9b2b94 100644 --- a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -50,6 +50,7 @@ + @@ -65,6 +66,16 @@ + + + + + + + + + + @@ -83,8 +94,9 @@ - + + \ No newline at end of file From 43a0055b72eeb8c1d87db27f43bb471469fe19ce Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 3 Apr 2022 21:59:19 -0700 Subject: [PATCH 05/21] New fields for 1.3 --- MeshtasticClient/Helpers/BLEManager.swift | 26 +++++++------------ .../contents | 8 +++--- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 76bf93ff..2d04564a 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -405,8 +405,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let myInfo = MyInfoEntity(context: context!) myInfo.myNodeNum = Int64(decodedInfo.myInfo.myNodeNum) myInfo.hasGps = decodedInfo.myInfo.hasGps_p - myInfo.channelUtilization = decodedInfo.myInfo.channelUtilization - + // Swift does strings weird, this does work to get the version without the github hash let lastDotIndex = decodedInfo.myInfo.firmwareVersion.lastIndex(of: ".") var version = decodedInfo.myInfo.firmwareVersion[...(lastDotIndex ?? String.Index(utf16Offset: 6, in: decodedInfo.myInfo.firmwareVersion))] @@ -420,8 +419,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph self.connectedPeripheral.num = myInfo.myNodeNum self.connectedPeripheral.firmwareVersion = myInfo.firmwareVersion ?? "Unknown" self.connectedPeripheral.name = myInfo.bleName ?? "Unknown" - self.connectedPeripheral.channelUtilization = myInfo.channelUtilization - self.connectedPeripheral.airTime = myInfo.airUtilTx let fetchBCUserRequest: NSFetchRequest = NSFetchRequest.init(entityName: "UserEntity") fetchBCUserRequest.predicate = NSPredicate(format: "num == %lld", Int64(decodedInfo.myInfo.myNodeNum)) @@ -449,7 +446,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph fetchedMyInfo[0].myNodeNum = Int64(decodedInfo.myInfo.myNodeNum) fetchedMyInfo[0].hasGps = decodedInfo.myInfo.hasGps_p - fetchedMyInfo[0].channelUtilization = decodedInfo.myInfo.channelUtilization let lastDotIndex = decodedInfo.myInfo.firmwareVersion.lastIndex(of: ".")//.lastIndex(of: ".", offsetBy: -1) var version = decodedInfo.myInfo.firmwareVersion[...(lastDotIndex ?? String.Index(utf16Offset:6, in: decodedInfo.myInfo.firmwareVersion))] version = version.dropLast() @@ -461,9 +457,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph self.connectedPeripheral.num = fetchedMyInfo[0].myNodeNum self.connectedPeripheral.firmwareVersion = fetchedMyInfo[0].firmwareVersion ?? "Unknown" self.connectedPeripheral.name = fetchedMyInfo[0].bleName ?? "Unknown" - self.connectedPeripheral.channelUtilization = fetchedMyInfo[0].channelUtilization - self.connectedPeripheral.airTime = fetchedMyInfo[0].airUtilTx - } do { @@ -513,18 +506,19 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let newNode = NodeInfoEntity(context: context!) newNode.id = Int64(decodedInfo.nodeInfo.num) newNode.num = Int64(decodedInfo.nodeInfo.num) + if decodedInfo.nodeInfo.hasDeviceMetrics { + newNode.batteryLevel = Int32(decodedInfo.nodeInfo.deviceMetrics.batteryLevel) newNode.voltage = decodedInfo.nodeInfo.deviceMetrics.voltage + newNode.channelUtilization = decodedInfo.nodeInfo.deviceMetrics.channelUtilization + self.connectedPeripheral.channelUtilization = newNode.channelUtilization + newNode.airUtilTx = decodedInfo.nodeInfo.deviceMetrics.airUtilTx + self.connectedPeripheral.airTime = decodedInfo.nodeInfo.deviceMetrics.airUtilTx } - - if decodedInfo.nodeInfo.lastHeard > 0 { - newNode.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.lastHeard))) - } - else { - newNode.lastHeard = Date() - } + // FIXME: Date from the node info, may be a bad date, needs to be fixed upstream in the firmware + newNode.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.lastHeard))) newNode.snr = decodedInfo.nodeInfo.snr if self.connectedPeripheral != nil && self.connectedPeripheral.num == newNode.num { @@ -534,7 +528,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph connectedPeripheral.name = decodedInfo.nodeInfo.user.longName } } - + if decodedInfo.nodeInfo.hasUser { let newUser = UserEntity(context: context!) diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents index ae0f4abb..d476aa02 100644 --- a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents @@ -22,10 +22,8 @@ - - @@ -41,8 +39,10 @@ + + @@ -82,8 +82,8 @@ - - + + From a2c73418fc3845e3a935cb3974f730efa5df024f Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Mon, 4 Apr 2022 22:49:26 -0700 Subject: [PATCH 06/21] Add charts for telemetry, update core data with telemetryentity --- Meshtastic Client.xcodeproj/project.pbxproj | 19 +++++++++++++++++++ .../xcshareddata/swiftpm/Package.resolved | 9 +++++++++ MeshtasticClient/Helpers/BLEManager.swift | 11 +++++++++++ .../contents | 10 ++++++---- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index bd764e32..c4bc655a 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -34,6 +34,7 @@ DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD90860D26F69BAE00DC5189 /* NodeMap.swift */; }; DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */; }; DD9D8F2F2764403B00080993 /* Meshtastic.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DD9D8F2D2764403B00080993 /* Meshtastic.xcdatamodeld */; }; + DD9E682F27FACD1F00EE0214 /* SwiftUICharts in Frameworks */ = {isa = PBXBuildFile; productRef = DD9E682E27FACD1F00EE0214 /* SwiftUICharts */; }; DDAF8C5326EB1DF10058C060 /* BLEManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C5226EB1DF10058C060 /* BLEManager.swift */; }; DDAF8C5826ED07FD0058C060 /* mesh.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C5726ED07FD0058C060 /* mesh.pb.swift */; }; DDAF8C5D26ED09490058C060 /* portnums.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C5C26ED09490058C060 /* portnums.pb.swift */; }; @@ -135,6 +136,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DD9E682F27FACD1F00EE0214 /* SwiftUICharts in Frameworks */, C9697FA527933B8C00250207 /* SQLite in Frameworks */, DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */, ); @@ -388,6 +390,7 @@ packageProductDependencies = ( DD5394FB276993AD00AD86B1 /* SwiftProtobuf */, C9697FA427933B8C00250207 /* SQLite */, + DD9E682E27FACD1F00EE0214 /* SwiftUICharts */, ); productName = MeshtasticClient; productReference = DDC2E15426CE248E0042C5E4 /* MeshtasticClient.app */; @@ -464,6 +467,7 @@ packageReferences = ( DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */, C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */, + DD9E682D27FACD1F00EE0214 /* XCRemoteSwiftPackageReference "SwiftUICharts" */, ); productRefGroup = DDC2E15526CE248E0042C5E4 /* Products */; projectDirPath = ""; @@ -787,6 +791,7 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = GCH7VS5Y9R; INFOPLIST_FILE = MeshtasticClientTests/Info.plist; @@ -809,6 +814,7 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = GCH7VS5Y9R; INFOPLIST_FILE = MeshtasticClientTests/Info.plist; @@ -924,6 +930,14 @@ minimumVersion = 1.0.0; }; }; + DD9E682D27FACD1F00EE0214 /* XCRemoteSwiftPackageReference "SwiftUICharts" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/mecid/SwiftUICharts.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.6.8; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -937,6 +951,11 @@ package = DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */; productName = SwiftProtobuf; }; + DD9E682E27FACD1F00EE0214 /* SwiftUICharts */ = { + isa = XCSwiftPackageProductDependency; + package = DD9E682D27FACD1F00EE0214 /* XCRemoteSwiftPackageReference "SwiftUICharts" */; + productName = SwiftUICharts; + }; /* End XCSwiftPackageProductDependency section */ /* Begin XCVersionGroup section */ diff --git a/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index c0572681..23f76265 100644 --- a/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -18,6 +18,15 @@ "revision": "7e2c5f3cbbeea68e004915e3a8961e20bd11d824", "version": "1.18.0" } + }, + { + "package": "SwiftUICharts", + "repositoryURL": "https://github.com/mecid/SwiftUICharts.git", + "state": { + "branch": null, + "revision": "15ec6551761e6a444e9439073e1f557c1c9700c6", + "version": "0.6.8" + } } ] }, diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 2d04564a..41540a7d 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -967,8 +967,19 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } } + // MARK: Incoming TELEMETRY_APP Packet } else if decodedInfo.packet.decoded.portnum == PortNum.telemetryApp { + + if let telemetryMessage = try? Telemetry(serializedData: decodedInfo.packet.decoded.payload) { + + let telemetry = TelemetryEntity(context: context!) + telemetry.num = Int64(decodedInfo.packet.from) + print(decodedInfo.packet.decoded.requestID) + print(telemetryMessage) + } + + if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Telemetry App UNHANDLED \(try decodedInfo.packet.jsonString())") } print("ℹ️ MESH PACKET received for Telemetry App UNHANDLED \(try decodedInfo.packet.jsonString())") diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents index 651578f4..55b039d0 100644 --- a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents @@ -50,7 +50,7 @@ - + @@ -66,15 +66,16 @@ - + + - + @@ -96,6 +97,7 @@ + - + \ No newline at end of file From 90ba351aebad9cd41304bdb4430c77606de5fadd Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 7 Apr 2022 19:26:40 -0700 Subject: [PATCH 07/21] Randomize configid --- MeshtasticClient/Helpers/BLEManager.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 41540a7d..032b4267 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -318,7 +318,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if meshLoggingEnabled { MeshLogger.log("✅ BLE did discover TORADIO characteristic for Meshtastic by \(peripheral.name ?? "Unknown")") } TORADIO_characteristic = characteristic var toRadio: ToRadio = ToRadio() - toRadio.wantConfigID = 32168 + toRadio.wantConfigID = UInt32.random(in: UInt32(UInt8.max).. Date: Thu, 7 Apr 2022 20:27:10 -0700 Subject: [PATCH 08/21] =?UTF-8?q?=F0=9F=92=A5=20Emoji=20for=20all=20Core?= =?UTF-8?q?=20Data=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MeshtasticClient/Helpers/BLEManager.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 032b4267..f5aa4704 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -469,7 +469,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph context!.rollback() let nsError = error as NSError - print("💥 Error Saving CoreData MyInfoEntity: \(nsError)") + print("💥 Error Saving Core Data MyInfoEntity: \(nsError)") } } catch { @@ -652,7 +652,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph context!.rollback() let nsError = error as NSError - print("💥 Error Saving CoreData NodeInfoEntity: \(nsError)") + print("💥 Error Saving Core Data NodeInfoEntity: \(nsError)") } } catch { @@ -1133,8 +1133,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph context!.rollback() let nsError = error as NSError - print("🚫 Unresolved Core Data error in Send Message Function \(nsError)") - if meshLoggingEnabled { MeshLogger.log("🚫 Unresolved Core Data error \(nsError)") } + print("💥 Unresolved Core Data error in Send Message Function \(nsError)") + if meshLoggingEnabled { MeshLogger.log("💥 Unresolved Core Data error \(nsError)") } } } } From 2145f43a42a3aa22bcbd3308d96b9a17479c91c9 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 8 Apr 2022 08:56:13 -0700 Subject: [PATCH 09/21] Remove Charts Libraries, and QR Code Library --- Meshtastic Client.xcodeproj/project.pbxproj | 24 +++++++++++-------- .../xcshareddata/swiftpm/Package.resolved | 18 +++++++------- MeshtasticClient/Views/Settings/Channel.swift | 8 +++++++ 3 files changed, 31 insertions(+), 19 deletions(-) create mode 100644 MeshtasticClient/Views/Settings/Channel.swift diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index c4bc655a..b9129eb7 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -25,6 +25,8 @@ DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = DD5394FB276993AD00AD86B1 /* SwiftProtobuf */; }; DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */; }; DD539502276DAA6A00AD86B1 /* MapLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD539501276DAA6A00AD86B1 /* MapLocation.swift */; }; + DD6B85A62800915B000ACD6B /* CarBode in Frameworks */ = {isa = PBXBuildFile; productRef = DD6B85A52800915B000ACD6B /* CarBode */; }; + DD6B85A828009258000ACD6B /* Channel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6B85A728009258000ACD6B /* Channel.swift */; }; DD8169F9271F1A6100F4AB02 /* MeshLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */; }; DD8169FB271F1F3A00F4AB02 /* MeshLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */; }; DD8169FF272476C700F4AB02 /* LogDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169FE272476C700F4AB02 /* LogDocument.swift */; }; @@ -34,7 +36,6 @@ DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD90860D26F69BAE00DC5189 /* NodeMap.swift */; }; DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */; }; DD9D8F2F2764403B00080993 /* Meshtastic.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DD9D8F2D2764403B00080993 /* Meshtastic.xcdatamodeld */; }; - DD9E682F27FACD1F00EE0214 /* SwiftUICharts in Frameworks */ = {isa = PBXBuildFile; productRef = DD9E682E27FACD1F00EE0214 /* SwiftUICharts */; }; DDAF8C5326EB1DF10058C060 /* BLEManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C5226EB1DF10058C060 /* BLEManager.swift */; }; DDAF8C5826ED07FD0058C060 /* mesh.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C5726ED07FD0058C060 /* mesh.pb.swift */; }; DDAF8C5D26ED09490058C060 /* portnums.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C5C26ED09490058C060 /* portnums.pb.swift */; }; @@ -92,6 +93,7 @@ DD4DED8F27AD2975004BA27E /* cannedmessages.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = cannedmessages.pb.swift; sourceTree = ""; }; DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionEntityExtension.swift; sourceTree = ""; }; DD539501276DAA6A00AD86B1 /* MapLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLocation.swift; sourceTree = ""; }; + DD6B85A728009258000ACD6B /* Channel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Channel.swift; sourceTree = ""; }; DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLogger.swift; sourceTree = ""; }; DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLog.swift; sourceTree = ""; }; DD8169FE272476C700F4AB02 /* LogDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogDocument.swift; sourceTree = ""; }; @@ -136,7 +138,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DD9E682F27FACD1F00EE0214 /* SwiftUICharts in Frameworks */, + DD6B85A62800915B000ACD6B /* CarBode in Frameworks */, C9697FA527933B8C00250207 /* SQLite in Frameworks */, DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */, ); @@ -202,6 +204,7 @@ DD4A911D2708C65400501B7E /* AppSettings.swift */, DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */, DD8169FE272476C700F4AB02 /* LogDocument.swift */, + DD6B85A728009258000ACD6B /* Channel.swift */, ); path = Settings; sourceTree = ""; @@ -390,7 +393,7 @@ packageProductDependencies = ( DD5394FB276993AD00AD86B1 /* SwiftProtobuf */, C9697FA427933B8C00250207 /* SQLite */, - DD9E682E27FACD1F00EE0214 /* SwiftUICharts */, + DD6B85A52800915B000ACD6B /* CarBode */, ); productName = MeshtasticClient; productReference = DDC2E15426CE248E0042C5E4 /* MeshtasticClient.app */; @@ -467,7 +470,7 @@ packageReferences = ( DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */, C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */, - DD9E682D27FACD1F00EE0214 /* XCRemoteSwiftPackageReference "SwiftUICharts" */, + DD6B85A42800915B000ACD6B /* XCRemoteSwiftPackageReference "CarBode-Barcode-Scanner-For-SwiftUI" */, ); productRefGroup = DDC2E15526CE248E0042C5E4 /* Products */; projectDirPath = ""; @@ -538,6 +541,7 @@ DDAF8C5F26ED09B50058C060 /* radioconfig.pb.swift in Sources */, DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */, DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */, + DD6B85A828009258000ACD6B /* Channel.swift in Sources */, DDAF8C5326EB1DF10058C060 /* BLEManager.swift in Sources */, DDC4D568275499A500A4208E /* Persistence.swift in Sources */, DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */, @@ -930,12 +934,12 @@ minimumVersion = 1.0.0; }; }; - DD9E682D27FACD1F00EE0214 /* XCRemoteSwiftPackageReference "SwiftUICharts" */ = { + DD6B85A42800915B000ACD6B /* XCRemoteSwiftPackageReference "CarBode-Barcode-Scanner-For-SwiftUI" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/mecid/SwiftUICharts.git"; + repositoryURL = "https://github.com/heart/CarBode-Barcode-Scanner-For-SwiftUI"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.8; + minimumVersion = 2.0.0; }; }; /* End XCRemoteSwiftPackageReference section */ @@ -951,10 +955,10 @@ package = DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */; productName = SwiftProtobuf; }; - DD9E682E27FACD1F00EE0214 /* SwiftUICharts */ = { + DD6B85A52800915B000ACD6B /* CarBode */ = { isa = XCSwiftPackageProductDependency; - package = DD9E682D27FACD1F00EE0214 /* XCRemoteSwiftPackageReference "SwiftUICharts" */; - productName = SwiftUICharts; + package = DD6B85A42800915B000ACD6B /* XCRemoteSwiftPackageReference "CarBode-Barcode-Scanner-For-SwiftUI" */; + productName = CarBode; }; /* End XCSwiftPackageProductDependency section */ diff --git a/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 23f76265..94cdf5f2 100644 --- a/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,15 @@ { "object": { "pins": [ + { + "package": "CarBode", + "repositoryURL": "https://github.com/heart/CarBode-Barcode-Scanner-For-SwiftUI", + "state": { + "branch": null, + "revision": "6167624ec47174900434f1c03dfa0b2dd5d19c0d", + "version": "2.2.3" + } + }, { "package": "SQLite.swift", "repositoryURL": "https://github.com/stephencelis/SQLite.swift.git", @@ -18,15 +27,6 @@ "revision": "7e2c5f3cbbeea68e004915e3a8961e20bd11d824", "version": "1.18.0" } - }, - { - "package": "SwiftUICharts", - "repositoryURL": "https://github.com/mecid/SwiftUICharts.git", - "state": { - "branch": null, - "revision": "15ec6551761e6a444e9439073e1f557c1c9700c6", - "version": "0.6.8" - } } ] }, diff --git a/MeshtasticClient/Views/Settings/Channel.swift b/MeshtasticClient/Views/Settings/Channel.swift new file mode 100644 index 00000000..1c874aed --- /dev/null +++ b/MeshtasticClient/Views/Settings/Channel.swift @@ -0,0 +1,8 @@ +// +// Channel.swift +// MeshtasticClient +// +// Created by Garth Vander Houwen on 4/8/22. +// + +import Foundation From 8171b84272c8d9e895c2f2f265b8c93339bcd9f5 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Mon, 11 Apr 2022 15:58:11 -0700 Subject: [PATCH 10/21] Start of QR Code, updated protobufs --- Meshtastic Client.xcodeproj/project.pbxproj | 14 +- MeshtasticClient/Helpers/BLEManager.swift | 51 +++++++ MeshtasticClient/Protobufs/mesh.pb.swift | 16 +++ .../Protobufs/radioconfig.pb.swift | 15 -- MeshtasticClient/Views/Helpers/QRCamera.swift | 133 ++++++++++++++++++ .../Views/Settings/AppSettings.swift | 7 + MeshtasticClient/Views/Settings/Channel.swift | 8 -- .../Views/Settings/ShareChannel.swift | 75 ++++++++++ 8 files changed, 292 insertions(+), 27 deletions(-) create mode 100644 MeshtasticClient/Views/Helpers/QRCamera.swift delete mode 100644 MeshtasticClient/Views/Settings/Channel.swift create mode 100644 MeshtasticClient/Views/Settings/ShareChannel.swift diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index b9129eb7..eaeaeda9 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -26,7 +26,8 @@ DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */; }; DD539502276DAA6A00AD86B1 /* MapLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD539501276DAA6A00AD86B1 /* MapLocation.swift */; }; DD6B85A62800915B000ACD6B /* CarBode in Frameworks */ = {isa = PBXBuildFile; productRef = DD6B85A52800915B000ACD6B /* CarBode */; }; - DD6B85A828009258000ACD6B /* Channel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6B85A728009258000ACD6B /* Channel.swift */; }; + DD6B85A828009258000ACD6B /* ShareChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6B85A728009258000ACD6B /* ShareChannel.swift */; }; + DD6B85AA2800DFE5000ACD6B /* QRCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6B85A92800DFE5000ACD6B /* QRCamera.swift */; }; DD8169F9271F1A6100F4AB02 /* MeshLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */; }; DD8169FB271F1F3A00F4AB02 /* MeshLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */; }; DD8169FF272476C700F4AB02 /* LogDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169FE272476C700F4AB02 /* LogDocument.swift */; }; @@ -93,7 +94,8 @@ DD4DED8F27AD2975004BA27E /* cannedmessages.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = cannedmessages.pb.swift; sourceTree = ""; }; DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionEntityExtension.swift; sourceTree = ""; }; DD539501276DAA6A00AD86B1 /* MapLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLocation.swift; sourceTree = ""; }; - DD6B85A728009258000ACD6B /* Channel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Channel.swift; sourceTree = ""; }; + DD6B85A728009258000ACD6B /* ShareChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareChannel.swift; sourceTree = ""; }; + DD6B85A92800DFE5000ACD6B /* QRCamera.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCamera.swift; sourceTree = ""; }; DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLogger.swift; sourceTree = ""; }; DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLog.swift; sourceTree = ""; }; DD8169FE272476C700F4AB02 /* LogDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogDocument.swift; sourceTree = ""; }; @@ -204,7 +206,7 @@ DD4A911D2708C65400501B7E /* AppSettings.swift */, DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */, DD8169FE272476C700F4AB02 /* LogDocument.swift */, - DD6B85A728009258000ACD6B /* Channel.swift */, + DD6B85A728009258000ACD6B /* ShareChannel.swift */, ); path = Settings; sourceTree = ""; @@ -348,6 +350,7 @@ DD47E3D826F3093800029299 /* MessageBubble.swift */, DD90860B26F684AF00DC5189 /* BatteryIcon.swift */, DDF924C926FBB953009FE055 /* ConnectedDevice.swift */, + DD6B85A92800DFE5000ACD6B /* QRCamera.swift */, ); path = Helpers; sourceTree = ""; @@ -536,12 +539,13 @@ files = ( DD4DED9027AD2975004BA27E /* cannedmessages.pb.swift in Sources */, DD836AE726F6B38600ABCC23 /* Connect.swift in Sources */, + DD6B85AA2800DFE5000ACD6B /* QRCamera.swift in Sources */, DDAF8C6E26ED19040058C060 /* Extensions.swift in Sources */, DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */, DDAF8C5F26ED09B50058C060 /* radioconfig.pb.swift in Sources */, DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */, DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */, - DD6B85A828009258000ACD6B /* Channel.swift in Sources */, + DD6B85A828009258000ACD6B /* ShareChannel.swift in Sources */, DDAF8C5326EB1DF10058C060 /* BLEManager.swift in Sources */, DDC4D568275499A500A4208E /* Persistence.swift in Sources */, DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */, @@ -745,6 +749,7 @@ ENABLE_PREVIEWS = YES; INFOPLIST_FILE = MeshtasticClient/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; + "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 15.2; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -776,6 +781,7 @@ ENABLE_PREVIEWS = YES; INFOPLIST_FILE = MeshtasticClient/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; + "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 15.2; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index f5aa4704..7d21920f 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -384,6 +384,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph switch characteristic.uuid { case FROMRADIO_UUID: + if characteristic.value == nil || characteristic.value!.isEmpty { return } @@ -405,6 +406,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let myInfo = MyInfoEntity(context: context!) myInfo.myNodeNum = Int64(decodedInfo.myInfo.myNodeNum) myInfo.hasGps = decodedInfo.myInfo.hasGps_p + myInfo.bitrate = decodedInfo.myInfo.bitrate // Swift does strings weird, this does work to get the version without the github hash let lastDotIndex = decodedInfo.myInfo.firmwareVersion.lastIndex(of: ".") @@ -437,6 +439,18 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph print("💾 Saved the All - Broadcast User") } + var settingsCalled = self.getSettings() + + if settingsCalled { + + print("💾 Called Get Settings") + + } else { + + print("💥 Get Settings Call Failed") + } + + } catch { print("💥 Error Saving the All - Broadcast User") @@ -1146,6 +1160,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph return success } + // Send Position public func sendPosition(destNum: Int64, wantResponse: Bool) -> Bool { var success = false @@ -1223,4 +1238,40 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } } } + + // MARK: Device Settings + public func getSettings() -> Bool { + + var adminPacket = AdminMessage() + adminPacket.getRadioRequest = true + + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(connectedPeripheral.num) + meshPacket.from = UInt32(connectedPeripheral.num) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. Path { + Path { path in + let width = rect.width + let height = rect.height + + path.addLines( [ + + CGPoint(x: 0, y: height * 0.25), + CGPoint(x: 0, y: 0), + CGPoint(x:width * 0.25, y:0) + ]) + + path.addLines( [ + + CGPoint(x: width * 0.75, y: 0), + CGPoint(x: width, y: 0), + CGPoint(x:width, y:height * 0.25) + ]) + + path.addLines( [ + + CGPoint(x: width, y: height * 0.75), + CGPoint(x: width, y: height), + CGPoint(x:width * 0.75, y: height) + ]) + + path.addLines( [ + + CGPoint(x:width * 0.25, y: height), + CGPoint(x:0, y: height), + CGPoint(x:0, y:height * 0.75) + + ]) + + } + } +} + +struct QRCamera: View { + @State var barcodeValue = "" + @State var torchIsOn = false + @State var showingAlert = false + @State var cameraPosition = AVCaptureDevice.Position.back + + var body: some View { + VStack { + Text("QRCode Scanner") + + Spacer() + + if cameraPosition == .back{ + Text("Using back camera") + }else{ + Text("Using front camera") + } + + Button(action: { + if cameraPosition == .back { + cameraPosition = .front + }else{ + cameraPosition = .back + } + }) { + if cameraPosition == .back{ + Text("Switch Camera to Front") + }else{ + Text("Switch Camera to Back") + } + } + + + Button(action: { + self.torchIsOn.toggle() + }) { + Text("Toggle Torch Light") + } + + Spacer() + + CBScanner( + supportBarcode: .constant([.qr, .code128]), + torchLightIsOn: $torchIsOn, + cameraPosition: $cameraPosition, + mockBarCode: .constant(BarcodeData(value:"My Test Data", type: .qr)) + ){ + print("BarCodeType =",$0.type.rawValue, "Value =",$0.value) + barcodeValue = $0.value + } + onDraw: { + print("Preview View Size = \($0.cameraPreviewView.bounds)") + print("Barcode Corners = \($0.corners)") + + let lineColor = UIColor.green + let fillColor = UIColor(red: 0, green: 1, blue: 0.2, alpha: 0.4) + //Draw Barcode corner + $0.draw(lineWidth: 1, lineColor: lineColor, fillColor: fillColor) + + }.frame(minWidth: 0, maxWidth: .infinity, minHeight: 400, maxHeight: 400, alignment: .topLeading) + .overlay(cameraFrame() + .stroke(lineWidth: 5) + .frame(width: 500, height: 250) + .foregroundColor(.blue)) + + Spacer() + + Text(barcodeValue) + + Spacer() + + }.alert(isPresented: $showingAlert) { + Alert(title: Text("Found Barcode"), message: Text("\(barcodeValue)"), dismissButton: .default(Text("Close"))) + } + } +} + +struct ModalScannerView_Previews: PreviewProvider { + static var previews: some View { + QRCamera() + } +} + diff --git a/MeshtasticClient/Views/Settings/AppSettings.swift b/MeshtasticClient/Views/Settings/AppSettings.swift index caf7f255..bc9e9668 100644 --- a/MeshtasticClient/Views/Settings/AppSettings.swift +++ b/MeshtasticClient/Views/Settings/AppSettings.swift @@ -206,6 +206,13 @@ struct AppSettings: View { .listRowSeparator(.visible) } } + Section(header: Text("MESH OPTIONS")) { + + NavigationLink(destination: ShareChannel()) { + Text("Share Your Channel vis QR Code") + } + + } Section(header: Text("MESSAGING OPTIONS")) { Picker("Keyboard Type", selection: $userSettings.keyboardType) { diff --git a/MeshtasticClient/Views/Settings/Channel.swift b/MeshtasticClient/Views/Settings/Channel.swift deleted file mode 100644 index 1c874aed..00000000 --- a/MeshtasticClient/Views/Settings/Channel.swift +++ /dev/null @@ -1,8 +0,0 @@ -// -// Channel.swift -// MeshtasticClient -// -// Created by Garth Vander Houwen on 4/8/22. -// - -import Foundation diff --git a/MeshtasticClient/Views/Settings/ShareChannel.swift b/MeshtasticClient/Views/Settings/ShareChannel.swift new file mode 100644 index 00000000..e734b454 --- /dev/null +++ b/MeshtasticClient/Views/Settings/ShareChannel.swift @@ -0,0 +1,75 @@ +// +// Channel.swift +// MeshtasticClient +// +// Created by Garth Vander Houwen on 4/8/22. +// +import SwiftUI +import CoreData +import CarBode + + +struct ShareChannel: View { + + @Environment(\.managedObjectContext) var context + @EnvironmentObject var bleManager: BLEManager + @EnvironmentObject var userSettings: UserSettings + + + @State var dataString = "Hello Carbode" + @State var barcodeType = CBBarcodeView.BarcodeType.qrCode + @State var rotate = CBBarcodeView.Orientation.up + + @State var barcodeImage: UIImage? + + + var body: some View { + + HStack { + + GeometryReader { bounds in + + ScrollView { + + VStack { + + let smallest = min(bounds.size.width, bounds.size.height) + + Text("Channel Name").font(.largeTitle) + CBBarcodeView(data: $dataString, + barcodeType: $barcodeType, + orientation: $rotate) + { image in + self.barcodeImage = image + }.frame( + minWidth: smallest * 0.9, + maxWidth: smallest * 0.9, + minHeight: smallest * 0.9, + maxHeight: smallest * 0.9, + alignment: .topLeading + ) + .padding(.bottom) + Text("Channel Details").font(.title) + + Text("Some helpful text about how this whole thing works goes here, also could add a share sheet icon and pass the link around.") + Spacer() + Text("Some helpful text about how this whole thing works goes here, also could add a share sheet icon and pass the link around.") + } + } + }.padding() + } + .navigationTitle("Share Channel") + .navigationBarTitleDisplayMode(.inline) + .navigationBarItems(trailing: + + ZStack { + + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???") + }) + .onAppear { + + self.bleManager.context = context + } + .navigationViewStyle(StackNavigationViewStyle()) + } +} From ada29b167db9721d3571f88bde300c77d347aca7 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 12 Apr 2022 17:37:00 -0700 Subject: [PATCH 11/21] telemetries --- .../contents | 8 ++++---- MeshtasticClient/Protobufs/radioconfig.pb.swift | 17 ----------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents index 55b039d0..6205af2a 100644 --- a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents @@ -50,7 +50,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -95,9 +95,9 @@ - + - + \ No newline at end of file diff --git a/MeshtasticClient/Protobufs/radioconfig.pb.swift b/MeshtasticClient/Protobufs/radioconfig.pb.swift index 783a964f..895a8c90 100644 --- a/MeshtasticClient/Protobufs/radioconfig.pb.swift +++ b/MeshtasticClient/Protobufs/radioconfig.pb.swift @@ -732,15 +732,6 @@ struct RadioConfig { set {_uniqueStorage()._phoneTimeoutSecs = newValue} } - /// - /// Power management state machine option. - /// See [power management](/docs/software/other/power) for details. - /// 0 for default of two hours, MAXUINT for disabled - var phoneSdsTimeoutSec: UInt32 { - get {return _storage._phoneSdsTimeoutSec} - set {_uniqueStorage()._phoneSdsTimeoutSec = newValue} - } - /// /// Power management state machine option. /// See [power management](/docs/software/other/power) for details. @@ -1737,7 +1728,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes 4: .standard(proto: "wait_bluetooth_secs"), 5: .standard(proto: "screen_on_secs"), 6: .standard(proto: "phone_timeout_secs"), - 7: .standard(proto: "phone_sds_timeout_sec"), 8: .standard(proto: "mesh_sds_timeout_secs"), 9: .standard(proto: "sds_secs"), 10: .standard(proto: "ls_secs"), @@ -1824,7 +1814,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes var _waitBluetoothSecs: UInt32 = 0 var _screenOnSecs: UInt32 = 0 var _phoneTimeoutSecs: UInt32 = 0 - var _phoneSdsTimeoutSec: UInt32 = 0 var _meshSdsTimeoutSecs: UInt32 = 0 var _sdsSecs: UInt32 = 0 var _lsSecs: UInt32 = 0 @@ -1914,7 +1903,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes _waitBluetoothSecs = source._waitBluetoothSecs _screenOnSecs = source._screenOnSecs _phoneTimeoutSecs = source._phoneTimeoutSecs - _phoneSdsTimeoutSec = source._phoneSdsTimeoutSec _meshSdsTimeoutSecs = source._meshSdsTimeoutSecs _sdsSecs = source._sdsSecs _lsSecs = source._lsSecs @@ -2015,7 +2003,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes case 4: try { try decoder.decodeSingularUInt32Field(value: &_storage._waitBluetoothSecs) }() case 5: try { try decoder.decodeSingularUInt32Field(value: &_storage._screenOnSecs) }() case 6: try { try decoder.decodeSingularUInt32Field(value: &_storage._phoneTimeoutSecs) }() - case 7: try { try decoder.decodeSingularUInt32Field(value: &_storage._phoneSdsTimeoutSec) }() case 8: try { try decoder.decodeSingularUInt32Field(value: &_storage._meshSdsTimeoutSecs) }() case 9: try { try decoder.decodeSingularUInt32Field(value: &_storage._sdsSecs) }() case 10: try { try decoder.decodeSingularUInt32Field(value: &_storage._lsSecs) }() @@ -2115,9 +2102,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._phoneTimeoutSecs != 0 { try visitor.visitSingularUInt32Field(value: _storage._phoneTimeoutSecs, fieldNumber: 6) } - if _storage._phoneSdsTimeoutSec != 0 { - try visitor.visitSingularUInt32Field(value: _storage._phoneSdsTimeoutSec, fieldNumber: 7) - } if _storage._meshSdsTimeoutSecs != 0 { try visitor.visitSingularUInt32Field(value: _storage._meshSdsTimeoutSecs, fieldNumber: 8) } @@ -2369,7 +2353,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._waitBluetoothSecs != rhs_storage._waitBluetoothSecs {return false} if _storage._screenOnSecs != rhs_storage._screenOnSecs {return false} if _storage._phoneTimeoutSecs != rhs_storage._phoneTimeoutSecs {return false} - if _storage._phoneSdsTimeoutSec != rhs_storage._phoneSdsTimeoutSec {return false} if _storage._meshSdsTimeoutSecs != rhs_storage._meshSdsTimeoutSecs {return false} if _storage._sdsSecs != rhs_storage._sdsSecs {return false} if _storage._lsSecs != rhs_storage._lsSecs {return false} From be8577a6100fd99903c4994d12fea585bd33ff4c Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 19 Apr 2022 22:56:59 -0700 Subject: [PATCH 12/21] Kill the CarBode! --- Meshtastic Client.xcodeproj/project.pbxproj | 29 +--- .../xcshareddata/swiftpm/Package.resolved | 17 +-- MeshtasticClient/Helpers/BLEManager.swift | 17 +-- MeshtasticClient/Info.plist | 2 + .../contents | 16 +-- MeshtasticClient/Protobufs/mesh.pb.swift | 78 +++++++++- MeshtasticClient/Views/Helpers/QRCamera.swift | 133 ------------------ MeshtasticClient/Views/Nodes/NodeDetail.swift | 3 +- .../Views/Settings/ShareChannel.swift | 95 ++++++++----- 9 files changed, 158 insertions(+), 232 deletions(-) delete mode 100644 MeshtasticClient/Views/Helpers/QRCamera.swift diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index eaeaeda9..bc7af150 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -25,9 +25,7 @@ DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = DD5394FB276993AD00AD86B1 /* SwiftProtobuf */; }; DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */; }; DD539502276DAA6A00AD86B1 /* MapLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD539501276DAA6A00AD86B1 /* MapLocation.swift */; }; - DD6B85A62800915B000ACD6B /* CarBode in Frameworks */ = {isa = PBXBuildFile; productRef = DD6B85A52800915B000ACD6B /* CarBode */; }; DD6B85A828009258000ACD6B /* ShareChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6B85A728009258000ACD6B /* ShareChannel.swift */; }; - DD6B85AA2800DFE5000ACD6B /* QRCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6B85A92800DFE5000ACD6B /* QRCamera.swift */; }; DD8169F9271F1A6100F4AB02 /* MeshLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */; }; DD8169FB271F1F3A00F4AB02 /* MeshLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */; }; DD8169FF272476C700F4AB02 /* LogDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169FE272476C700F4AB02 /* LogDocument.swift */; }; @@ -95,7 +93,6 @@ DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionEntityExtension.swift; sourceTree = ""; }; DD539501276DAA6A00AD86B1 /* MapLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLocation.swift; sourceTree = ""; }; DD6B85A728009258000ACD6B /* ShareChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareChannel.swift; sourceTree = ""; }; - DD6B85A92800DFE5000ACD6B /* QRCamera.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCamera.swift; sourceTree = ""; }; DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLogger.swift; sourceTree = ""; }; DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLog.swift; sourceTree = ""; }; DD8169FE272476C700F4AB02 /* LogDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogDocument.swift; sourceTree = ""; }; @@ -140,7 +137,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DD6B85A62800915B000ACD6B /* CarBode in Frameworks */, C9697FA527933B8C00250207 /* SQLite in Frameworks */, DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */, ); @@ -350,7 +346,6 @@ DD47E3D826F3093800029299 /* MessageBubble.swift */, DD90860B26F684AF00DC5189 /* BatteryIcon.swift */, DDF924C926FBB953009FE055 /* ConnectedDevice.swift */, - DD6B85A92800DFE5000ACD6B /* QRCamera.swift */, ); path = Helpers; sourceTree = ""; @@ -396,7 +391,6 @@ packageProductDependencies = ( DD5394FB276993AD00AD86B1 /* SwiftProtobuf */, C9697FA427933B8C00250207 /* SQLite */, - DD6B85A52800915B000ACD6B /* CarBode */, ); productName = MeshtasticClient; productReference = DDC2E15426CE248E0042C5E4 /* MeshtasticClient.app */; @@ -473,7 +467,6 @@ packageReferences = ( DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */, C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */, - DD6B85A42800915B000ACD6B /* XCRemoteSwiftPackageReference "CarBode-Barcode-Scanner-For-SwiftUI" */, ); productRefGroup = DDC2E15526CE248E0042C5E4 /* Products */; projectDirPath = ""; @@ -539,7 +532,6 @@ files = ( DD4DED9027AD2975004BA27E /* cannedmessages.pb.swift in Sources */, DD836AE726F6B38600ABCC23 /* Connect.swift in Sources */, - DD6B85AA2800DFE5000ACD6B /* QRCamera.swift in Sources */, DDAF8C6E26ED19040058C060 /* Extensions.swift in Sources */, DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */, DDAF8C5F26ED09B50058C060 /* radioconfig.pb.swift in Sources */, @@ -743,7 +735,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 20; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; @@ -754,7 +746,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.53; + MARKETING_VERSION = 1.3.1; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -775,7 +767,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 20; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; @@ -786,7 +778,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.53; + MARKETING_VERSION = 1.3.1; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -940,14 +932,6 @@ minimumVersion = 1.0.0; }; }; - DD6B85A42800915B000ACD6B /* XCRemoteSwiftPackageReference "CarBode-Barcode-Scanner-For-SwiftUI" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/heart/CarBode-Barcode-Scanner-For-SwiftUI"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 2.0.0; - }; - }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -961,11 +945,6 @@ package = DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */; productName = SwiftProtobuf; }; - DD6B85A52800915B000ACD6B /* CarBode */ = { - isa = XCSwiftPackageProductDependency; - package = DD6B85A42800915B000ACD6B /* XCRemoteSwiftPackageReference "CarBode-Barcode-Scanner-For-SwiftUI" */; - productName = CarBode; - }; /* End XCSwiftPackageProductDependency section */ /* Begin XCVersionGroup section */ diff --git a/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 94cdf5f2..55b7b56c 100644 --- a/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,22 +1,13 @@ { "object": { "pins": [ - { - "package": "CarBode", - "repositoryURL": "https://github.com/heart/CarBode-Barcode-Scanner-For-SwiftUI", - "state": { - "branch": null, - "revision": "6167624ec47174900434f1c03dfa0b2dd5d19c0d", - "version": "2.2.3" - } - }, { "package": "SQLite.swift", "repositoryURL": "https://github.com/stephencelis/SQLite.swift.git", "state": { "branch": null, - "revision": "60a65015f6402b7c34b9a924f755ca0a73afeeaa", - "version": "0.13.1" + "revision": "4d543d811ee644fa4cc4bfa0be996b4dd6ba0f54", + "version": "0.13.3" } }, { @@ -24,8 +15,8 @@ "repositoryURL": "https://github.com/apple/swift-protobuf.git", "state": { "branch": null, - "revision": "7e2c5f3cbbeea68e004915e3a8961e20bd11d824", - "version": "1.18.0" + "revision": "e1499bc69b9040b29184f7f2996f7bab467c1639", + "version": "1.19.0" } } ] diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 7d21920f..29e471d2 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -523,11 +523,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if decodedInfo.nodeInfo.hasDeviceMetrics { - newNode.batteryLevel = Int32(decodedInfo.nodeInfo.deviceMetrics.batteryLevel) - newNode.voltage = decodedInfo.nodeInfo.deviceMetrics.voltage - newNode.channelUtilization = decodedInfo.nodeInfo.deviceMetrics.channelUtilization - self.connectedPeripheral.channelUtilization = newNode.channelUtilization - newNode.airUtilTx = decodedInfo.nodeInfo.deviceMetrics.airUtilTx + let newTelemetry = TelemetryEntity(context: context!) + + newTelemetry.batteryLevel = Int32(decodedInfo.nodeInfo.deviceMetrics.batteryLevel) + newTelemetry.voltage = decodedInfo.nodeInfo.deviceMetrics.voltage + newTelemetry.channelUtilization = decodedInfo.nodeInfo.deviceMetrics.channelUtilization + self.connectedPeripheral.channelUtilization = newTelemetry.channelUtilization + newTelemetry.airUtilTx = decodedInfo.nodeInfo.deviceMetrics.airUtilTx self.connectedPeripheral.airTime = decodedInfo.nodeInfo.deviceMetrics.airUtilTx } @@ -988,7 +990,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if let telemetryMessage = try? Telemetry(serializedData: decodedInfo.packet.decoded.payload) { let telemetry = TelemetryEntity(context: context!) - telemetry.num = Int64(decodedInfo.packet.from) print(decodedInfo.packet.decoded.requestID) print(telemetryMessage) } @@ -1178,6 +1179,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph do { let fetchedNode = try context?.fetch(fetchNode) as! [NodeInfoEntity] + if fetchedNode.count == 1 { @@ -1207,10 +1209,9 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph print("📍 Sent a Position Packet from the phone to the device for node: \(fromNodeNum)") if connectedPeripheral!.peripheral.state == CBPeripheralState.connected { + connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) - success = true - } } diff --git a/MeshtasticClient/Info.plist b/MeshtasticClient/Info.plist index 1a7b3ab5..ea9d0da6 100644 --- a/MeshtasticClient/Info.plist +++ b/MeshtasticClient/Info.plist @@ -45,6 +45,8 @@ We use bluetooth to connect to nearby Meshtastic Devices NSBluetoothPeripheralUsageDescription Bluetooth is used to connect an iPhone to a user's meshtastic device to allow text messaging and location data for the mesh network. + NSCameraUsageDescription + We use the camera to share channels using a QR Code NSLocationUsageDescription We use your location to display it on the mesh map as well as to have GPS coordinatess to send to the connected device. NSLocationWhenInUseUsageDescription diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents index 6205af2a..a5ab71a8 100644 --- a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents @@ -24,6 +24,7 @@ + @@ -31,6 +32,7 @@ + @@ -39,15 +41,11 @@ - - - - @@ -67,10 +65,12 @@ + + + - @@ -94,10 +94,10 @@ - - + + - + \ No newline at end of file diff --git a/MeshtasticClient/Protobufs/mesh.pb.swift b/MeshtasticClient/Protobufs/mesh.pb.swift index ed36b55d..7876eb12 100644 --- a/MeshtasticClient/Protobufs/mesh.pb.swift +++ b/MeshtasticClient/Protobufs/mesh.pb.swift @@ -1171,9 +1171,27 @@ struct DataMessage { /// Formerly named typ and of type Type var portnum: PortNum = .unknownApp + var payloadVariant: DataMessage.OneOf_PayloadVariant? = nil + /// /// TODO: REPLACE - var payload: Data = Data() + var payload: Data { + get { + if case .payload(let v)? = payloadVariant {return v} + return Data() + } + set {payloadVariant = .payload(newValue)} + } + + /// + /// TODO: REPLACE + var payloadCompressed: Data { + get { + if case .payloadCompressed(let v)? = payloadVariant {return v} + return Data() + } + set {payloadVariant = .payloadCompressed(newValue)} + } /// /// Not normally used, but for testing a sender can request that recipient @@ -1222,6 +1240,34 @@ struct DataMessage { var unknownFields = SwiftProtobuf.UnknownStorage() + enum OneOf_PayloadVariant: Equatable { + /// + /// TODO: REPLACE + case payload(Data) + /// + /// TODO: REPLACE + case payloadCompressed(Data) + + #if !swift(>=4.1) + static func ==(lhs: DataMessage.OneOf_PayloadVariant, rhs: DataMessage.OneOf_PayloadVariant) -> Bool { + // 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 (lhs, rhs) { + case (.payload, .payload): return { + guard case .payload(let l) = lhs, case .payload(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.payloadCompressed, .payloadCompressed): return { + guard case .payloadCompressed(let l) = lhs, case .payloadCompressed(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif + } + init() {} fileprivate var _location: Location? = nil @@ -2266,6 +2312,7 @@ extension Routing: @unchecked Sendable {} extension Routing.OneOf_Variant: @unchecked Sendable {} extension Routing.Error: @unchecked Sendable {} extension DataMessage: @unchecked Sendable {} +extension DataMessage.OneOf_PayloadVariant: @unchecked Sendable {} extension Location: @unchecked Sendable {} extension MeshPacket: @unchecked Sendable {} extension MeshPacket.OneOf_PayloadVariant: @unchecked Sendable {} @@ -2830,6 +2877,7 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .same(proto: "portnum"), 2: .same(proto: "payload"), + 10: .standard(proto: "payload_compressed"), 3: .standard(proto: "want_response"), 4: .same(proto: "dest"), 5: .same(proto: "source"), @@ -2846,7 +2894,14 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { case 1: try { try decoder.decodeSingularEnumField(value: &self.portnum) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self.payload) }() + case 2: try { + var v: Data? + try decoder.decodeSingularBytesField(value: &v) + if let v = v { + if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} + self.payloadVariant = .payload(v) + } + }() case 3: try { try decoder.decodeSingularBoolField(value: &self.wantResponse) }() case 4: try { try decoder.decodeSingularFixed32Field(value: &self.dest) }() case 5: try { try decoder.decodeSingularFixed32Field(value: &self.source) }() @@ -2854,6 +2909,14 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati case 7: try { try decoder.decodeSingularFixed32Field(value: &self.replyID) }() case 8: try { try decoder.decodeSingularFixed32Field(value: &self.emoji) }() case 9: try { try decoder.decodeSingularMessageField(value: &self._location) }() + case 10: try { + var v: Data? + try decoder.decodeSingularBytesField(value: &v) + if let v = v { + if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} + self.payloadVariant = .payloadCompressed(v) + } + }() default: break } } @@ -2867,9 +2930,9 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati if self.portnum != .unknownApp { try visitor.visitSingularEnumField(value: self.portnum, fieldNumber: 1) } - if !self.payload.isEmpty { - try visitor.visitSingularBytesField(value: self.payload, fieldNumber: 2) - } + try { if case .payload(let v)? = self.payloadVariant { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() if self.wantResponse != false { try visitor.visitSingularBoolField(value: self.wantResponse, fieldNumber: 3) } @@ -2891,12 +2954,15 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati try { if let v = self._location { try visitor.visitSingularMessageField(value: v, fieldNumber: 9) } }() + try { if case .payloadCompressed(let v)? = self.payloadVariant { + try visitor.visitSingularBytesField(value: v, fieldNumber: 10) + } }() try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: DataMessage, rhs: DataMessage) -> Bool { if lhs.portnum != rhs.portnum {return false} - if lhs.payload != rhs.payload {return false} + if lhs.payloadVariant != rhs.payloadVariant {return false} if lhs.wantResponse != rhs.wantResponse {return false} if lhs.dest != rhs.dest {return false} if lhs.source != rhs.source {return false} diff --git a/MeshtasticClient/Views/Helpers/QRCamera.swift b/MeshtasticClient/Views/Helpers/QRCamera.swift deleted file mode 100644 index 050a5d10..00000000 --- a/MeshtasticClient/Views/Helpers/QRCamera.swift +++ /dev/null @@ -1,133 +0,0 @@ -// -// QRCamera.swift -// MeshtasticClient -// -// Created by Garth Vander Houwen on 4/8/22. -// - -import SwiftUI -import CarBode -import AVFoundation - -struct cameraFrame: Shape { - func path(in rect: CGRect) -> Path { - Path { path in - let width = rect.width - let height = rect.height - - path.addLines( [ - - CGPoint(x: 0, y: height * 0.25), - CGPoint(x: 0, y: 0), - CGPoint(x:width * 0.25, y:0) - ]) - - path.addLines( [ - - CGPoint(x: width * 0.75, y: 0), - CGPoint(x: width, y: 0), - CGPoint(x:width, y:height * 0.25) - ]) - - path.addLines( [ - - CGPoint(x: width, y: height * 0.75), - CGPoint(x: width, y: height), - CGPoint(x:width * 0.75, y: height) - ]) - - path.addLines( [ - - CGPoint(x:width * 0.25, y: height), - CGPoint(x:0, y: height), - CGPoint(x:0, y:height * 0.75) - - ]) - - } - } -} - -struct QRCamera: View { - @State var barcodeValue = "" - @State var torchIsOn = false - @State var showingAlert = false - @State var cameraPosition = AVCaptureDevice.Position.back - - var body: some View { - VStack { - Text("QRCode Scanner") - - Spacer() - - if cameraPosition == .back{ - Text("Using back camera") - }else{ - Text("Using front camera") - } - - Button(action: { - if cameraPosition == .back { - cameraPosition = .front - }else{ - cameraPosition = .back - } - }) { - if cameraPosition == .back{ - Text("Switch Camera to Front") - }else{ - Text("Switch Camera to Back") - } - } - - - Button(action: { - self.torchIsOn.toggle() - }) { - Text("Toggle Torch Light") - } - - Spacer() - - CBScanner( - supportBarcode: .constant([.qr, .code128]), - torchLightIsOn: $torchIsOn, - cameraPosition: $cameraPosition, - mockBarCode: .constant(BarcodeData(value:"My Test Data", type: .qr)) - ){ - print("BarCodeType =",$0.type.rawValue, "Value =",$0.value) - barcodeValue = $0.value - } - onDraw: { - print("Preview View Size = \($0.cameraPreviewView.bounds)") - print("Barcode Corners = \($0.corners)") - - let lineColor = UIColor.green - let fillColor = UIColor(red: 0, green: 1, blue: 0.2, alpha: 0.4) - //Draw Barcode corner - $0.draw(lineWidth: 1, lineColor: lineColor, fillColor: fillColor) - - }.frame(minWidth: 0, maxWidth: .infinity, minHeight: 400, maxHeight: 400, alignment: .topLeading) - .overlay(cameraFrame() - .stroke(lineWidth: 5) - .frame(width: 500, height: 250) - .foregroundColor(.blue)) - - Spacer() - - Text(barcodeValue) - - Spacer() - - }.alert(isPresented: $showingAlert) { - Alert(title: Text("Found Barcode"), message: Text("\(barcodeValue)"), dismissButton: .default(Text("Close"))) - } - } -} - -struct ModalScannerView_Previews: PreviewProvider { - static var previews: some View { - QRCamera() - } -} - diff --git a/MeshtasticClient/Views/Nodes/NodeDetail.swift b/MeshtasticClient/Views/Nodes/NodeDetail.swift index a6d96931..6bd11342 100644 --- a/MeshtasticClient/Views/Nodes/NodeDetail.swift +++ b/MeshtasticClient/Views/Nodes/NodeDetail.swift @@ -104,7 +104,8 @@ struct NodeDetail: View { } } .padding(5) - + + if node.snr > 0 { Divider() VStack(alignment: .center) { diff --git a/MeshtasticClient/Views/Settings/ShareChannel.swift b/MeshtasticClient/Views/Settings/ShareChannel.swift index e734b454..352ab6af 100644 --- a/MeshtasticClient/Views/Settings/ShareChannel.swift +++ b/MeshtasticClient/Views/Settings/ShareChannel.swift @@ -6,69 +6,88 @@ // import SwiftUI import CoreData -import CarBode +import CoreImage.CIFilterBuiltins +struct QrCodeImage { + let context = CIContext() + + func generateQRCode(from text: String) -> UIImage { + var qrImage = UIImage(systemName: "xmark.circle") ?? UIImage() + let data = Data(text.utf8) + let filter = CIFilter.qrCodeGenerator() + filter.setValue(data, forKey: "inputMessage") + + let transform = CGAffineTransform(scaleX: 15, y: 15) + if let outputImage = filter.outputImage?.transformed(by: transform) { + if let image = context.createCGImage( + outputImage, + from: outputImage.extent) { + qrImage = UIImage(cgImage: image) + } + } + return qrImage + } +} + struct ShareChannel: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager @EnvironmentObject var userSettings: UserSettings - - - @State var dataString = "Hello Carbode" - @State var barcodeType = CBBarcodeView.BarcodeType.qrCode - @State var rotate = CBBarcodeView.Orientation.up - - @State var barcodeImage: UIImage? - + + @State private var text = "meshtastic.org" + var qrCodeImage = QrCodeImage() + var body: some View { - - HStack { + + VStack { GeometryReader { bounds in + let smallest = min(bounds.size.width, bounds.size.height) + ScrollView { - - VStack { - - let smallest = min(bounds.size.width, bounds.size.height) - Text("Channel Name").font(.largeTitle) - CBBarcodeView(data: $dataString, - barcodeType: $barcodeType, - orientation: $rotate) - { image in - self.barcodeImage = image - }.frame( + VStack { + Text("Scan the QR code below with the Apple or Android device you would like to share with your channel settings with.") + .fixedSize(horizontal: false, vertical: true) + .font(.callout) + .padding() + Spacer() + + let image = qrCodeImage.generateQRCode(from: text) + Image(uiImage: image) + .resizable() + .scaledToFit() + .frame( minWidth: smallest * 0.9, maxWidth: smallest * 0.9, minHeight: smallest * 0.9, maxHeight: smallest * 0.9, - alignment: .topLeading + alignment: .center ) - .padding(.bottom) - Text("Channel Details").font(.title) - - Text("Some helpful text about how this whole thing works goes here, also could add a share sheet icon and pass the link around.") Spacer() - Text("Some helpful text about how this whole thing works goes here, also could add a share sheet icon and pass the link around.") + Text("Channel Name (Long/Slow)").font(.title) + Spacer() } + .frame(width: bounds.size.width, height: bounds.size.height) } - }.padding() - } - .navigationTitle("Share Channel") - .navigationBarTitleDisplayMode(.inline) - .navigationBarItems(trailing: + } + .navigationTitle("Share Channel") + .navigationBarTitleDisplayMode(.automatic) + .navigationBarItems(trailing: - ZStack { + ZStack { - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???") - }) - .onAppear { + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???") + }) + .onAppear { - self.bleManager.context = context + self.bleManager.context = context + } + } .navigationViewStyle(StackNavigationViewStyle()) } From 48de377922be20b0d4a11376fbc7847bd733854f Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 23 Apr 2022 12:57:47 -0700 Subject: [PATCH 13/21] Update protobufs, clean up qr sharing view --- Meshtastic Client.xcodeproj/project.pbxproj | 4 +- MeshtasticClient/Helpers/BLEManager.swift | 2 +- .../Protobufs/deviceonly.pb.swift | 154 ++++++++++++++++++ .../Protobufs/radioconfig.pb.swift | 20 +++ .../Views/Settings/AppSettings.swift | 2 +- .../Views/Settings/ShareChannel.swift | 4 +- 6 files changed, 180 insertions(+), 6 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index bc7af150..d2e228f4 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -735,7 +735,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; @@ -767,7 +767,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 29e471d2..56f17a71 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -1148,7 +1148,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph context!.rollback() let nsError = error as NSError - print("💥 Unresolved Core Data error in Send Message Function \(nsError)") + print("💥 Unresolved Core Data error in Send Message Function it is likely that your database is corrupted deleting and re-installing the app should clear the corrupted data. Error: \(nsError)") if meshLoggingEnabled { MeshLogger.log("💥 Unresolved Core Data error \(nsError)") } } } diff --git a/MeshtasticClient/Protobufs/deviceonly.pb.swift b/MeshtasticClient/Protobufs/deviceonly.pb.swift index 9311b664..52a31d33 100644 --- a/MeshtasticClient/Protobufs/deviceonly.pb.swift +++ b/MeshtasticClient/Protobufs/deviceonly.pb.swift @@ -20,6 +20,61 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } +/// +/// TODO: REPLACE +enum ScreenFonts: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// TODO: REPLACE + case fontSmall // = 0 + + /// + /// TODO: REPLACE + case fontMedium // = 1 + + /// + /// TODO: REPLACE + case fontLarge // = 2 + case UNRECOGNIZED(Int) + + init() { + self = .fontSmall + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .fontSmall + case 1: self = .fontMedium + case 2: self = .fontLarge + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .fontSmall: return 0 + case .fontMedium: return 1 + case .fontLarge: return 2 + case .UNRECOGNIZED(let i): return i + } + } + +} + +#if swift(>=4.2) + +extension ScreenFonts: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [ScreenFonts] = [ + .fontSmall, + .fontMedium, + .fontLarge, + ] +} + +#endif // swift(>=4.2) + /// /// This message is never sent over the wire, but it is used for serializing DB /// state to flash in the device code @@ -127,13 +182,56 @@ struct ChannelFile { init() {} } +/// +/// This can be used for customizing the firmware distribution. If populated, +/// show a secondary bootup screen with cuatom logo and text for 2.5 seconds. +struct OEMStore { + // 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. + + /// + /// The Logo width in Px + var oemIconWidth: UInt32 = 0 + + /// + /// The Logo height in Px + var oemIconHeight: UInt32 = 0 + + /// + /// The Logo in xbm bytechar format + var oemIconBits: Data = Data() + + /// + /// Use this font for the OEM text. + var oemFont: ScreenFonts = .fontSmall + + /// + /// Use this font for the OEM text. + var oemText: String = String() + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + #if swift(>=5.5) && canImport(_Concurrency) +extension ScreenFonts: @unchecked Sendable {} extension DeviceState: @unchecked Sendable {} extension ChannelFile: @unchecked Sendable {} +extension OEMStore: @unchecked Sendable {} #endif // swift(>=5.5) && canImport(_Concurrency) // MARK: - Code below here is support for the SwiftProtobuf runtime. +extension ScreenFonts: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "FONT_SMALL"), + 1: .same(proto: "FONT_MEDIUM"), + 2: .same(proto: "FONT_LARGE"), + ] +} + extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "DeviceState" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ @@ -289,3 +387,59 @@ extension ChannelFile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati return true } } + +extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = "OEMStore" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "oem_icon_width"), + 2: .standard(proto: "oem_icon_height"), + 3: .standard(proto: "oem_icon_bits"), + 4: .standard(proto: "oem_font"), + 5: .standard(proto: "oem_text"), + ] + + 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.oemIconWidth) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.oemIconHeight) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self.oemIconBits) }() + case 4: try { try decoder.decodeSingularEnumField(value: &self.oemFont) }() + case 5: try { try decoder.decodeSingularStringField(value: &self.oemText) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.oemIconWidth != 0 { + try visitor.visitSingularUInt32Field(value: self.oemIconWidth, fieldNumber: 1) + } + if self.oemIconHeight != 0 { + try visitor.visitSingularUInt32Field(value: self.oemIconHeight, fieldNumber: 2) + } + if !self.oemIconBits.isEmpty { + try visitor.visitSingularBytesField(value: self.oemIconBits, fieldNumber: 3) + } + if self.oemFont != .fontSmall { + try visitor.visitSingularEnumField(value: self.oemFont, fieldNumber: 4) + } + if !self.oemText.isEmpty { + try visitor.visitSingularStringField(value: self.oemText, fieldNumber: 5) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: OEMStore, rhs: OEMStore) -> Bool { + if lhs.oemIconWidth != rhs.oemIconWidth {return false} + if lhs.oemIconHeight != rhs.oemIconHeight {return false} + if lhs.oemIconBits != rhs.oemIconBits {return false} + if lhs.oemFont != rhs.oemFont {return false} + if lhs.oemText != rhs.oemText {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/MeshtasticClient/Protobufs/radioconfig.pb.swift b/MeshtasticClient/Protobufs/radioconfig.pb.swift index 895a8c90..83453149 100644 --- a/MeshtasticClient/Protobufs/radioconfig.pb.swift +++ b/MeshtasticClient/Protobufs/radioconfig.pb.swift @@ -1362,6 +1362,10 @@ struct RadioConfig { case baud460800 // = 9 case baud576000 // = 10 case baud921600 // = 11 + case baud110 // = 12 + case baud300 // = 13 + case baud600 // = 14 + case baud1200 // = 15 case UNRECOGNIZED(Int) init() { @@ -1382,6 +1386,10 @@ struct RadioConfig { case 9: self = .baud460800 case 10: self = .baud576000 case 11: self = .baud921600 + case 12: self = .baud110 + case 13: self = .baud300 + case 14: self = .baud600 + case 15: self = .baud1200 default: self = .UNRECOGNIZED(rawValue) } } @@ -1400,6 +1408,10 @@ struct RadioConfig { case .baud460800: return 9 case .baud576000: return 10 case .baud921600: return 11 + case .baud110: return 12 + case .baud300: return 13 + case .baud600: return 14 + case .baud1200: return 15 case .UNRECOGNIZED(let i): return i } } @@ -1550,6 +1562,10 @@ extension RadioConfig.UserPreferences.Serial_Baud: CaseIterable { .baud460800, .baud576000, .baud921600, + .baud110, + .baud300, + .baud600, + .baud1200, ] } @@ -2454,6 +2470,10 @@ extension RadioConfig.UserPreferences.Serial_Baud: SwiftProtobuf._ProtoNameProvi 9: .same(proto: "BAUD_460800"), 10: .same(proto: "BAUD_576000"), 11: .same(proto: "BAUD_921600"), + 12: .same(proto: "BAUD_110"), + 13: .same(proto: "BAUD_300"), + 14: .same(proto: "BAUD_600"), + 15: .same(proto: "BAUD_1200"), ] } diff --git a/MeshtasticClient/Views/Settings/AppSettings.swift b/MeshtasticClient/Views/Settings/AppSettings.swift index bc9e9668..769419db 100644 --- a/MeshtasticClient/Views/Settings/AppSettings.swift +++ b/MeshtasticClient/Views/Settings/AppSettings.swift @@ -158,7 +158,7 @@ struct AppSettings: View { GeometryReader { _ in - List { + Form { Section(header: Text("USER DETAILS")) { HStack { diff --git a/MeshtasticClient/Views/Settings/ShareChannel.swift b/MeshtasticClient/Views/Settings/ShareChannel.swift index 352ab6af..2fbab5d3 100644 --- a/MeshtasticClient/Views/Settings/ShareChannel.swift +++ b/MeshtasticClient/Views/Settings/ShareChannel.swift @@ -1,5 +1,5 @@ // -// Channel.swift +// ShareChannel.swift // MeshtasticClient // // Created by Garth Vander Houwen on 4/8/22. @@ -18,7 +18,7 @@ struct QrCodeImage { let filter = CIFilter.qrCodeGenerator() filter.setValue(data, forKey: "inputMessage") - let transform = CGAffineTransform(scaleX: 15, y: 15) + let transform = CGAffineTransform(scaleX: 20, y: 20) if let outputImage = filter.outputImage?.transformed(by: transform) { if let image = context.createCGImage( outputImage, From 575f598c83c417c639e54c7cf5664b7ce550b697 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 5 May 2022 18:01:20 -0700 Subject: [PATCH 14/21] Upgrade protos --- Meshtastic Client.xcodeproj/project.pbxproj | 12 +- MeshtasticClient/Helpers/BLEManager.swift | 69 ++- .../Persistence/Persistence.swift | 1 + MeshtasticClient/Protobufs/admin.pb.swift | 440 ++++++++++++++++++ .../Protobufs/deviceonly.pb.swift | 197 +++----- MeshtasticClient/Protobufs/mesh.pb.swift | 175 ------- .../Protobufs/radioconfig.pb.swift | 260 ----------- MeshtasticClient/Protobufs/telemetry.pb.swift | 120 +++++ MeshtasticClient/Views/Nodes/NodeDetail.swift | 6 +- gen_protos.sh | 2 +- 10 files changed, 689 insertions(+), 593 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index d2e228f4..bba66583 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -21,6 +21,8 @@ DD47E3D626F17ED900029299 /* CircleText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3D526F17ED900029299 /* CircleText.swift */; }; DD47E3D926F3093800029299 /* MessageBubble.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3D826F3093800029299 /* MessageBubble.swift */; }; DD4A911E2708C65400501B7E /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4A911D2708C65400501B7E /* AppSettings.swift */; }; + DD4C158C2824A91E0032668E /* module_config.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4C158B2824A91E0032668E /* module_config.pb.swift */; }; + DD4C158E2824AA7E0032668E /* config.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4C158D2824AA7E0032668E /* config.pb.swift */; }; DD4DED9027AD2975004BA27E /* cannedmessages.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4DED8F27AD2975004BA27E /* cannedmessages.pb.swift */; }; DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = DD5394FB276993AD00AD86B1 /* SwiftProtobuf */; }; DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */; }; @@ -89,6 +91,8 @@ DD47E3D526F17ED900029299 /* CircleText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleText.swift; sourceTree = ""; }; DD47E3D826F3093800029299 /* MessageBubble.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageBubble.swift; sourceTree = ""; }; DD4A911D2708C65400501B7E /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = ""; }; + DD4C158B2824A91E0032668E /* module_config.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = module_config.pb.swift; sourceTree = ""; }; + DD4C158D2824AA7E0032668E /* config.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = config.pb.swift; sourceTree = ""; }; DD4DED8F27AD2975004BA27E /* cannedmessages.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = cannedmessages.pb.swift; sourceTree = ""; }; DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionEntityExtension.swift; sourceTree = ""; }; DD539501276DAA6A00AD86B1 /* MapLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLocation.swift; sourceTree = ""; }; @@ -217,18 +221,20 @@ DDAF8C5626ED07740058C060 /* Protobufs */ = { isa = PBXGroup; children = ( - DDB2CC6D27F3EB47009C5FCC /* telemetry.pb.swift */, DD4DED8F27AD2975004BA27E /* cannedmessages.pb.swift */, DDAF8C6126ED0A230058C060 /* admin.pb.swift */, C9A88B56278B559900BD810A /* apponly.pb.swift */, DDAF8C6426ED0A490058C060 /* channel.pb.swift */, + DD4C158D2824AA7E0032668E /* config.pb.swift */, DDAF8C6826ED0D070058C060 /* deviceonly.pb.swift */, DDAF8C5726ED07FD0058C060 /* mesh.pb.swift */, + DD4C158B2824A91E0032668E /* module_config.pb.swift */, DDAF8C6026ED0A230058C060 /* mqtt.pb.swift */, DDAF8C5C26ED09490058C060 /* portnums.pb.swift */, DDAF8C5E26ED09B50058C060 /* radioconfig.pb.swift */, DDAF8C6626ED0C8C0058C060 /* remote_hardware.pb.swift */, DD17E5DC277D49D400010EC2 /* storeforward.pb.swift */, + DDB2CC6D27F3EB47009C5FCC /* telemetry.pb.swift */, ); path = Protobufs; sourceTree = ""; @@ -537,6 +543,7 @@ DDAF8C5F26ED09B50058C060 /* radioconfig.pb.swift in Sources */, DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */, DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */, + DD4C158C2824A91E0032668E /* module_config.pb.swift in Sources */, DD6B85A828009258000ACD6B /* ShareChannel.swift in Sources */, DDAF8C5326EB1DF10058C060 /* BLEManager.swift in Sources */, DDC4D568275499A500A4208E /* Persistence.swift in Sources */, @@ -565,6 +572,7 @@ DD8169FB271F1F3A00F4AB02 /* MeshLog.swift in Sources */, DD2E65262767A01F00E45FC5 /* NodeDetail.swift in Sources */, C9A88B57278B559900BD810A /* apponly.pb.swift in Sources */, + DD4C158E2824AA7E0032668E /* config.pb.swift in Sources */, DD47E3D926F3093800029299 /* MessageBubble.swift in Sources */, C9697F9D279336B700250207 /* LocalMBTileOverlay.swift in Sources */, DD8169F9271F1A6100F4AB02 /* MeshLogger.swift in Sources */, @@ -929,7 +937,7 @@ repositoryURL = "https://github.com/apple/swift-protobuf.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 1.0.0; + minimumVersion = 1.19.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 56f17a71..712ef706 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -439,9 +439,9 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph print("💾 Saved the All - Broadcast User") } - var settingsCalled = self.getSettings() + //var settingsCalled = self.getSettings() - if settingsCalled { + if false { print("💾 Called Get Settings") @@ -523,14 +523,18 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if decodedInfo.nodeInfo.hasDeviceMetrics { - let newTelemetry = TelemetryEntity(context: context!) + let telemetry = TelemetryEntity(context: context!) - newTelemetry.batteryLevel = Int32(decodedInfo.nodeInfo.deviceMetrics.batteryLevel) - newTelemetry.voltage = decodedInfo.nodeInfo.deviceMetrics.voltage - newTelemetry.channelUtilization = decodedInfo.nodeInfo.deviceMetrics.channelUtilization - self.connectedPeripheral.channelUtilization = newTelemetry.channelUtilization - newTelemetry.airUtilTx = decodedInfo.nodeInfo.deviceMetrics.airUtilTx + telemetry.batteryLevel = Int32(decodedInfo.nodeInfo.deviceMetrics.batteryLevel) + telemetry.voltage = decodedInfo.nodeInfo.deviceMetrics.voltage + telemetry.channelUtilization = decodedInfo.nodeInfo.deviceMetrics.channelUtilization + self.connectedPeripheral.channelUtilization = telemetry.channelUtilization + telemetry.airUtilTx = decodedInfo.nodeInfo.deviceMetrics.airUtilTx self.connectedPeripheral.airTime = decodedInfo.nodeInfo.deviceMetrics.airUtilTx + + var newTelemetries = [TelemetryEntity]() + newTelemetries.append(telemetry) + newNode.telemetries? = NSOrderedSet(array: newTelemetries) } // FIXME: Date from the node info, may be a bad date, needs to be fixed upstream in the firmware @@ -554,7 +558,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph newUser.shortName = decodedInfo.nodeInfo.user.shortName newUser.macaddr = decodedInfo.nodeInfo.user.macaddr newUser.hwModel = String(describing: decodedInfo.nodeInfo.user.hwModel).uppercased() - newUser.team = (String(describing: decodedInfo.nodeInfo.user.team)) newNode.user = newUser } @@ -622,26 +625,44 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph fetchedNode[0].user!.shortName = decodedInfo.nodeInfo.user.shortName fetchedNode[0].user!.macaddr = decodedInfo.nodeInfo.user.macaddr fetchedNode[0].user!.hwModel = String(describing: decodedInfo.nodeInfo.user.hwModel).uppercased() - fetchedNode[0].user!.team = (String(describing: decodedInfo.nodeInfo.user.team)) } - - let position = PositionEntity(context: context!) - position.latitudeI = decodedInfo.nodeInfo.position.latitudeI - position.longitudeI = decodedInfo.nodeInfo.position.longitudeI - position.altitude = decodedInfo.nodeInfo.position.altitude - - if decodedInfo.nodeInfo.position.time > 0 { + + if decodedInfo.nodeInfo.hasDeviceMetrics { - position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time))) + let newTelemetry = TelemetryEntity(context: context!) + + newTelemetry.batteryLevel = Int32(decodedInfo.nodeInfo.deviceMetrics.batteryLevel) + newTelemetry.voltage = decodedInfo.nodeInfo.deviceMetrics.voltage + newTelemetry.channelUtilization = decodedInfo.nodeInfo.deviceMetrics.channelUtilization + self.connectedPeripheral.channelUtilization = newTelemetry.channelUtilization + newTelemetry.airUtilTx = decodedInfo.nodeInfo.deviceMetrics.airUtilTx + self.connectedPeripheral.airTime = decodedInfo.nodeInfo.deviceMetrics.airUtilTx + + let mutableTelemetries = fetchedNode[0].telemetries!.mutableCopy() as! NSMutableOrderedSet + fetchedNode[0].telemetries = mutableTelemetries.copy() as? NSOrderedSet } - else { - position.time = Date() + + if decodedInfo.nodeInfo.hasPosition { + + let position = PositionEntity(context: context!) + position.latitudeI = decodedInfo.nodeInfo.position.latitudeI + position.longitudeI = decodedInfo.nodeInfo.position.longitudeI + position.altitude = decodedInfo.nodeInfo.position.altitude + + if decodedInfo.nodeInfo.position.time > 0 { + + position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time))) + } + else { + position.time = Date() + } + + let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet + + fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet + } - let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet - - fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet - // Look for a MyInfo let fetchMyInfoRequest: NSFetchRequest = NSFetchRequest.init(entityName: "MyInfoEntity") fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(decodedInfo.nodeInfo.num)) diff --git a/MeshtasticClient/Persistence/Persistence.swift b/MeshtasticClient/Persistence/Persistence.swift index d8b6a973..c37af6e4 100644 --- a/MeshtasticClient/Persistence/Persistence.swift +++ b/MeshtasticClient/Persistence/Persistence.swift @@ -34,6 +34,7 @@ class PersistenceController { init(inMemory: Bool = false) { container = NSPersistentContainer(name: "Meshtastic") + //self.clearDatabase() if inMemory { container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") diff --git a/MeshtasticClient/Protobufs/admin.pb.swift b/MeshtasticClient/Protobufs/admin.pb.swift index 8bcd5fa1..e6d15c24 100644 --- a/MeshtasticClient/Protobufs/admin.pb.swift +++ b/MeshtasticClient/Protobufs/admin.pb.swift @@ -128,6 +128,86 @@ struct AdminMessage { set {variant = .getOwnerResponse(newValue)} } + /// + /// Ask for the following config data to be sent + var getConfigRequest: AdminMessage.ConfigType { + get { + if case .getConfigRequest(let v)? = variant {return v} + return .deviceConfig + } + set {variant = .getConfigRequest(newValue)} + } + + /// + /// Send the current Config in the response to this message. + var getConfigResponse: Config { + get { + if case .getConfigResponse(let v)? = variant {return v} + return Config() + } + set {variant = .getConfigResponse(newValue)} + } + + /// + /// Set the current Config + var setConfig: Config { + get { + if case .setConfig(let v)? = variant {return v} + return Config() + } + set {variant = .setConfig(newValue)} + } + + /// + /// Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins + var confirmSetConfig: Bool { + get { + if case .confirmSetConfig(let v)? = variant {return v} + return false + } + set {variant = .confirmSetConfig(newValue)} + } + + /// + /// Ask for the following config data to be sent + var getModuleConfigRequest: AdminMessage.ModuleConfigType { + get { + if case .getModuleConfigRequest(let v)? = variant {return v} + return .mqttConfig + } + set {variant = .getModuleConfigRequest(newValue)} + } + + /// + /// Send the current Config in the response to this message. + var getModuleConfigResponse: ModuleConfig { + get { + if case .getModuleConfigResponse(let v)? = variant {return v} + return ModuleConfig() + } + set {variant = .getModuleConfigResponse(newValue)} + } + + /// + /// Set the current Config + var setModuleConfig: ModuleConfig { + get { + if case .setModuleConfig(let v)? = variant {return v} + return ModuleConfig() + } + set {variant = .setModuleConfig(newValue)} + } + + /// + /// Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins + var confirmSetModuleConfig: Bool { + get { + if case .confirmSetModuleConfig(let v)? = variant {return v} + return false + } + set {variant = .confirmSetModuleConfig(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. @@ -340,6 +420,30 @@ struct AdminMessage { /// TODO: REPLACE case getOwnerResponse(User) /// + /// Ask for the following config data to be sent + case getConfigRequest(AdminMessage.ConfigType) + /// + /// Send the current Config in the response to this message. + case getConfigResponse(Config) + /// + /// Set the current Config + case setConfig(Config) + /// + /// Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins + case confirmSetConfig(Bool) + /// + /// Ask for the following config data to be sent + case getModuleConfigRequest(AdminMessage.ModuleConfigType) + /// + /// Send the current Config in the response to this message. + case getModuleConfigResponse(ModuleConfig) + /// + /// Set the current Config + case setModuleConfig(ModuleConfig) + /// + /// Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins + case confirmSetModuleConfig(Bool) + /// /// 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. @@ -437,6 +541,38 @@ struct AdminMessage { guard case .getOwnerResponse(let l) = lhs, case .getOwnerResponse(let r) = rhs else { preconditionFailure() } return l == r }() + case (.getConfigRequest, .getConfigRequest): return { + guard case .getConfigRequest(let l) = lhs, case .getConfigRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getConfigResponse, .getConfigResponse): return { + guard case .getConfigResponse(let l) = lhs, case .getConfigResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setConfig, .setConfig): return { + guard case .setConfig(let l) = lhs, case .setConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.confirmSetConfig, .confirmSetConfig): return { + guard case .confirmSetConfig(let l) = lhs, case .confirmSetConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getModuleConfigRequest, .getModuleConfigRequest): return { + guard case .getModuleConfigRequest(let l) = lhs, case .getModuleConfigRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getModuleConfigResponse, .getModuleConfigResponse): return { + guard case .getModuleConfigResponse(let l) = lhs, case .getModuleConfigResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setModuleConfig, .setModuleConfig): return { + guard case .setModuleConfig(let l) = lhs, case .setModuleConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.confirmSetModuleConfig, .confirmSetModuleConfig): return { + guard case .confirmSetModuleConfig(let l) = lhs, case .confirmSetModuleConfig(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 @@ -511,12 +647,169 @@ struct AdminMessage { #endif } + /// + /// TODO: REPLACE + enum ConfigType: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// TODO: REPLACE + case deviceConfig // = 0 + + /// + /// TODO: REPLACE + case gpsConfig // = 1 + + /// + /// TODO: REPLACE + case powerConfig // = 2 + + /// + /// TODO: REPLACE + case wifiConfig // = 3 + + /// + /// TODO: REPLACE + case displayConfig // = 4 + + /// + /// TODO: REPLACE + case loraConfig // = 5 + case UNRECOGNIZED(Int) + + init() { + self = .deviceConfig + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .deviceConfig + case 1: self = .gpsConfig + case 2: self = .powerConfig + case 3: self = .wifiConfig + case 4: self = .displayConfig + case 5: self = .loraConfig + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .deviceConfig: return 0 + case .gpsConfig: return 1 + case .powerConfig: return 2 + case .wifiConfig: return 3 + case .displayConfig: return 4 + case .loraConfig: return 5 + case .UNRECOGNIZED(let i): return i + } + } + + } + + /// + /// TODO: REPLACE + enum ModuleConfigType: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// TODO: REPLACE + case mqttConfig // = 0 + + /// + /// TODO: REPLACE + case serialConfig // = 1 + + /// + /// TODO: REPLACE + case extnotifConfig // = 2 + + /// + /// TODO: REPLACE + case storeforwardConfig // = 3 + + /// + /// TODO: REPLACE + case rangetestConfig // = 4 + + /// + /// TODO: REPLACE + case telemetryConfig // = 5 + + /// + /// TODO: REPLACE + case cannedmsgConfig // = 6 + case UNRECOGNIZED(Int) + + init() { + self = .mqttConfig + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .mqttConfig + case 1: self = .serialConfig + case 2: self = .extnotifConfig + case 3: self = .storeforwardConfig + case 4: self = .rangetestConfig + case 5: self = .telemetryConfig + case 6: self = .cannedmsgConfig + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .mqttConfig: return 0 + case .serialConfig: return 1 + case .extnotifConfig: return 2 + case .storeforwardConfig: return 3 + case .rangetestConfig: return 4 + case .telemetryConfig: return 5 + case .cannedmsgConfig: return 6 + case .UNRECOGNIZED(let i): return i + } + } + + } + init() {} } +#if swift(>=4.2) + +extension AdminMessage.ConfigType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [AdminMessage.ConfigType] = [ + .deviceConfig, + .gpsConfig, + .powerConfig, + .wifiConfig, + .displayConfig, + .loraConfig, + ] +} + +extension AdminMessage.ModuleConfigType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [AdminMessage.ModuleConfigType] = [ + .mqttConfig, + .serialConfig, + .extnotifConfig, + .storeforwardConfig, + .rangetestConfig, + .telemetryConfig, + .cannedmsgConfig, + ] +} + +#endif // swift(>=4.2) + #if swift(>=5.5) && canImport(_Concurrency) extension AdminMessage: @unchecked Sendable {} extension AdminMessage.OneOf_Variant: @unchecked Sendable {} +extension AdminMessage.ConfigType: @unchecked Sendable {} +extension AdminMessage.ModuleConfigType: @unchecked Sendable {} #endif // swift(>=5.5) && canImport(_Concurrency) // MARK: - Code below here is support for the SwiftProtobuf runtime. @@ -533,6 +826,14 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat 7: .standard(proto: "get_channel_response"), 8: .standard(proto: "get_owner_request"), 9: .standard(proto: "get_owner_response"), + 10: .standard(proto: "get_config_request"), + 11: .standard(proto: "get_config_response"), + 12: .standard(proto: "set_config"), + 13: .standard(proto: "confirm_set_config"), + 14: .standard(proto: "get_module_config_request"), + 15: .standard(proto: "get_module_config_response"), + 16: .standard(proto: "set_module_config"), + 17: .standard(proto: "confirm_set_module_config"), 32: .standard(proto: "confirm_set_channel"), 33: .standard(proto: "confirm_set_radio"), 34: .standard(proto: "exit_simulator"), @@ -660,6 +961,90 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat self.variant = .getOwnerResponse(v) } }() + case 10: try { + var v: AdminMessage.ConfigType? + try decoder.decodeSingularEnumField(value: &v) + if let v = v { + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getConfigRequest(v) + } + }() + case 11: try { + var v: Config? + var hadOneofValue = false + if let current = self.variant { + hadOneofValue = true + if case .getConfigResponse(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .getConfigResponse(v) + } + }() + case 12: try { + var v: Config? + var hadOneofValue = false + if let current = self.variant { + hadOneofValue = true + if case .setConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .setConfig(v) + } + }() + case 13: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .confirmSetConfig(v) + } + }() + case 14: try { + var v: AdminMessage.ModuleConfigType? + try decoder.decodeSingularEnumField(value: &v) + if let v = v { + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getModuleConfigRequest(v) + } + }() + case 15: try { + var v: ModuleConfig? + var hadOneofValue = false + if let current = self.variant { + hadOneofValue = true + if case .getModuleConfigResponse(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .getModuleConfigResponse(v) + } + }() + case 16: try { + var v: ModuleConfig? + var hadOneofValue = false + if let current = self.variant { + hadOneofValue = true + if case .setModuleConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .setModuleConfig(v) + } + }() + case 17: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .confirmSetModuleConfig(v) + } + }() case 32: try { var v: Bool? try decoder.decodeSingularBoolField(value: &v) @@ -843,6 +1228,38 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat guard case .getOwnerResponse(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 9) }() + case .getConfigRequest?: try { + guard case .getConfigRequest(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularEnumField(value: v, fieldNumber: 10) + }() + case .getConfigResponse?: try { + guard case .getConfigResponse(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 11) + }() + case .setConfig?: try { + guard case .setConfig(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 12) + }() + case .confirmSetConfig?: try { + guard case .confirmSetConfig(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularBoolField(value: v, fieldNumber: 13) + }() + case .getModuleConfigRequest?: try { + guard case .getModuleConfigRequest(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularEnumField(value: v, fieldNumber: 14) + }() + case .getModuleConfigResponse?: try { + guard case .getModuleConfigResponse(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 15) + }() + case .setModuleConfig?: try { + guard case .setModuleConfig(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 16) + }() + case .confirmSetModuleConfig?: try { + guard case .confirmSetModuleConfig(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularBoolField(value: v, fieldNumber: 17) + }() case .confirmSetChannel?: try { guard case .confirmSetChannel(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularBoolField(value: v, fieldNumber: 32) @@ -922,3 +1339,26 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat return true } } + +extension AdminMessage.ConfigType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "DEVICE_CONFIG"), + 1: .same(proto: "GPS_CONFIG"), + 2: .same(proto: "POWER_CONFIG"), + 3: .same(proto: "WIFI_CONFIG"), + 4: .same(proto: "DISPLAY_CONFIG"), + 5: .same(proto: "LORA_CONFIG"), + ] +} + +extension AdminMessage.ModuleConfigType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "MQTT_CONFIG"), + 1: .same(proto: "SERIAL_CONFIG"), + 2: .same(proto: "EXTNOTIF_CONFIG"), + 3: .same(proto: "STOREFORWARD_CONFIG"), + 4: .same(proto: "RANGETEST_CONFIG"), + 5: .same(proto: "TELEMETRY_CONFIG"), + 6: .same(proto: "CANNEDMSG_CONFIG"), + ] +} diff --git a/MeshtasticClient/Protobufs/deviceonly.pb.swift b/MeshtasticClient/Protobufs/deviceonly.pb.swift index 52a31d33..a8e59f76 100644 --- a/MeshtasticClient/Protobufs/deviceonly.pb.swift +++ b/MeshtasticClient/Protobufs/deviceonly.pb.swift @@ -89,81 +89,68 @@ struct DeviceState { /// /// Read only settings/info about this node var myNode: MyNodeInfo { - get {return _storage._myNode ?? MyNodeInfo()} - set {_uniqueStorage()._myNode = newValue} + get {return _myNode ?? MyNodeInfo()} + set {_myNode = newValue} } /// Returns true if `myNode` has been explicitly set. - var hasMyNode: Bool {return _storage._myNode != nil} + var hasMyNode: Bool {return self._myNode != nil} /// Clears the value of `myNode`. Subsequent reads from it will return its default value. - mutating func clearMyNode() {_uniqueStorage()._myNode = nil} + mutating func clearMyNode() {self._myNode = nil} /// /// My owner info var owner: User { - get {return _storage._owner ?? User()} - set {_uniqueStorage()._owner = newValue} + get {return _owner ?? User()} + set {_owner = newValue} } /// Returns true if `owner` has been explicitly set. - var hasOwner: Bool {return _storage._owner != nil} + var hasOwner: Bool {return self._owner != nil} /// Clears the value of `owner`. Subsequent reads from it will return its default value. - mutating func clearOwner() {_uniqueStorage()._owner = nil} + mutating func clearOwner() {self._owner = nil} /// /// TODO: REPLACE - var nodeDb: [NodeInfo] { - get {return _storage._nodeDb} - set {_uniqueStorage()._nodeDb = newValue} - } + var nodeDb: [NodeInfo] = [] /// /// Received packets saved for delivery to the phone - var receiveQueue: [MeshPacket] { - get {return _storage._receiveQueue} - set {_uniqueStorage()._receiveQueue = newValue} - } + var receiveQueue: [MeshPacket] = [] /// /// A version integer used to invalidate old save files when we make /// incompatible changes This integer is set at build time and is private to /// NodeDB.cpp in the device code. - var version: UInt32 { - get {return _storage._version} - set {_uniqueStorage()._version = newValue} - } + var version: UInt32 = 0 /// /// We keep the last received text message (only) stored in the device flash, /// so we can show it on the screen. /// Might be null var rxTextMessage: MeshPacket { - get {return _storage._rxTextMessage ?? MeshPacket()} - set {_uniqueStorage()._rxTextMessage = newValue} + get {return _rxTextMessage ?? MeshPacket()} + set {_rxTextMessage = newValue} } /// Returns true if `rxTextMessage` has been explicitly set. - var hasRxTextMessage: Bool {return _storage._rxTextMessage != nil} + var hasRxTextMessage: Bool {return self._rxTextMessage != nil} /// Clears the value of `rxTextMessage`. Subsequent reads from it will return its default value. - mutating func clearRxTextMessage() {_uniqueStorage()._rxTextMessage = nil} + mutating func clearRxTextMessage() {self._rxTextMessage = nil} /// /// Used only during development. /// Indicates developer is testing and changes should never be saved to flash. - var noSave: Bool { - get {return _storage._noSave} - set {_uniqueStorage()._noSave = newValue} - } + var noSave: Bool = false /// /// Some GPSes seem to have bogus settings from the factory, so we always do one factory reset. - var didGpsReset: Bool { - get {return _storage._didGpsReset} - set {_uniqueStorage()._didGpsReset = newValue} - } + var didGpsReset: Bool = false var unknownFields = SwiftProtobuf.UnknownStorage() init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _myNode: MyNodeInfo? = nil + fileprivate var _owner: User? = nil + fileprivate var _rxTextMessage: MeshPacket? = nil } /// @@ -245,112 +232,66 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati 11: .standard(proto: "did_gps_reset"), ] - fileprivate class _StorageClass { - var _myNode: MyNodeInfo? = nil - var _owner: User? = nil - var _nodeDb: [NodeInfo] = [] - var _receiveQueue: [MeshPacket] = [] - var _version: UInt32 = 0 - var _rxTextMessage: MeshPacket? = nil - var _noSave: Bool = false - var _didGpsReset: Bool = false - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _myNode = source._myNode - _owner = source._owner - _nodeDb = source._nodeDb - _receiveQueue = source._receiveQueue - _version = source._version - _rxTextMessage = source._rxTextMessage - _noSave = source._noSave - _didGpsReset = source._didGpsReset - } - } - - 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 2: try { try decoder.decodeSingularMessageField(value: &_storage._myNode) }() - case 3: try { try decoder.decodeSingularMessageField(value: &_storage._owner) }() - case 4: try { try decoder.decodeRepeatedMessageField(value: &_storage._nodeDb) }() - case 5: try { try decoder.decodeRepeatedMessageField(value: &_storage._receiveQueue) }() - case 7: try { try decoder.decodeSingularMessageField(value: &_storage._rxTextMessage) }() - case 8: try { try decoder.decodeSingularUInt32Field(value: &_storage._version) }() - case 9: try { try decoder.decodeSingularBoolField(value: &_storage._noSave) }() - case 11: try { try decoder.decodeSingularBoolField(value: &_storage._didGpsReset) }() - 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 2: try { try decoder.decodeSingularMessageField(value: &self._myNode) }() + case 3: try { try decoder.decodeSingularMessageField(value: &self._owner) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.nodeDb) }() + case 5: try { try decoder.decodeRepeatedMessageField(value: &self.receiveQueue) }() + case 7: try { try decoder.decodeSingularMessageField(value: &self._rxTextMessage) }() + case 8: try { try decoder.decodeSingularUInt32Field(value: &self.version) }() + case 9: try { try decoder.decodeSingularBoolField(value: &self.noSave) }() + case 11: try { try decoder.decodeSingularBoolField(value: &self.didGpsReset) }() + 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._myNode { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { 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 { - try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - } }() - if _storage._version != 0 { - try visitor.visitSingularUInt32Field(value: _storage._version, fieldNumber: 8) - } - if _storage._noSave != false { - try visitor.visitSingularBoolField(value: _storage._noSave, fieldNumber: 9) - } - if _storage._didGpsReset != false { - try visitor.visitSingularBoolField(value: _storage._didGpsReset, fieldNumber: 11) - } + // 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._myNode { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try { if let v = self._owner { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + if !self.nodeDb.isEmpty { + try visitor.visitRepeatedMessageField(value: self.nodeDb, fieldNumber: 4) + } + if !self.receiveQueue.isEmpty { + try visitor.visitRepeatedMessageField(value: self.receiveQueue, fieldNumber: 5) + } + try { if let v = self._rxTextMessage { + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + } }() + if self.version != 0 { + try visitor.visitSingularUInt32Field(value: self.version, fieldNumber: 8) + } + if self.noSave != false { + try visitor.visitSingularBoolField(value: self.noSave, fieldNumber: 9) + } + if self.didGpsReset != false { + try visitor.visitSingularBoolField(value: self.didGpsReset, fieldNumber: 11) } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: DeviceState, rhs: DeviceState) -> 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._myNode != rhs_storage._myNode {return false} - if _storage._owner != rhs_storage._owner {return false} - if _storage._nodeDb != rhs_storage._nodeDb {return false} - if _storage._receiveQueue != rhs_storage._receiveQueue {return false} - if _storage._version != rhs_storage._version {return false} - if _storage._rxTextMessage != rhs_storage._rxTextMessage {return false} - if _storage._noSave != rhs_storage._noSave {return false} - if _storage._didGpsReset != rhs_storage._didGpsReset {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs._myNode != rhs._myNode {return false} + if lhs._owner != rhs._owner {return false} + if lhs.nodeDb != rhs.nodeDb {return false} + if lhs.receiveQueue != rhs.receiveQueue {return false} + if lhs.version != rhs.version {return false} + if lhs._rxTextMessage != rhs._rxTextMessage {return false} + if lhs.noSave != rhs.noSave {return false} + if lhs.didGpsReset != rhs.didGpsReset {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/MeshtasticClient/Protobufs/mesh.pb.swift b/MeshtasticClient/Protobufs/mesh.pb.swift index 7876eb12..c3f77995 100644 --- a/MeshtasticClient/Protobufs/mesh.pb.swift +++ b/MeshtasticClient/Protobufs/mesh.pb.swift @@ -227,146 +227,6 @@ extension HardwareModel: CaseIterable { #endif // swift(>=4.2) -/// -/// The team colors are based on the names of "friendly teams" in ATAK: -/// https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/atak/ATAK/app/src/main/assets/filters/team_filters.xml -enum Team: SwiftProtobuf.Enum { - typealias RawValue = Int - - /// - /// the default (unset) is "achromatic" (unaffiliated) - case clear // = 0 - - /// - /// TODO: REPLACE - case cyan // = 1 - - /// - /// TODO: REPLACE - case white // = 2 - - /// - /// TODO: REPLACE - case yellow // = 3 - - /// - /// TODO: REPLACE - case orange // = 4 - - /// - /// TODO: REPLACE - case magenta // = 5 - - /// - /// TODO: REPLACE - case red // = 6 - - /// - /// TODO: REPLACE - case maroon // = 7 - - /// - /// TODO: REPLACE - case purple // = 8 - - /// - /// TODO: REPLACE - case darkBlue // = 9 - - /// - /// TODO: REPLACE - case blue // = 10 - - /// - /// TODO: REPLACE - case teal // = 11 - - /// - /// TODO: REPLACE - case green // = 12 - - /// - /// TODO: REPLACE - case darkGreen // = 13 - - /// - /// TODO: REPLACE - case brown // = 14 - case UNRECOGNIZED(Int) - - init() { - self = .clear - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .clear - case 1: self = .cyan - case 2: self = .white - case 3: self = .yellow - case 4: self = .orange - case 5: self = .magenta - case 6: self = .red - case 7: self = .maroon - case 8: self = .purple - case 9: self = .darkBlue - case 10: self = .blue - case 11: self = .teal - case 12: self = .green - case 13: self = .darkGreen - case 14: self = .brown - default: self = .UNRECOGNIZED(rawValue) - } - } - - var rawValue: Int { - switch self { - case .clear: return 0 - case .cyan: return 1 - case .white: return 2 - case .yellow: return 3 - case .orange: return 4 - case .magenta: return 5 - case .red: return 6 - case .maroon: return 7 - case .purple: return 8 - case .darkBlue: return 9 - case .blue: return 10 - case .teal: return 11 - case .green: return 12 - case .darkGreen: return 13 - case .brown: return 14 - case .UNRECOGNIZED(let i): return i - } - } - -} - -#if swift(>=4.2) - -extension Team: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - static var allCases: [Team] = [ - .clear, - .cyan, - .white, - .yellow, - .orange, - .magenta, - .red, - .maroon, - .purple, - .darkBlue, - .blue, - .teal, - .green, - .darkGreen, - .brown, - ] -} - -#endif // swift(>=4.2) - /// /// Shared constants between device and phone enum Constants: SwiftProtobuf.Enum { @@ -917,14 +777,6 @@ struct User { /// Also, "long_name" should be their licence number. var isLicensed: Bool = false - /// - /// 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. - /// In total, 14 teams are defined (encoded in 4 bits) - var team: Team = .clear - /// /// Transmit power at antenna connector, in decibel-milliwatt /// An optional self-reported value useful in network planning, discovery @@ -2300,7 +2152,6 @@ struct ToRadio { #if swift(>=5.5) && canImport(_Concurrency) extension HardwareModel: @unchecked Sendable {} -extension Team: @unchecked Sendable {} extension Constants: @unchecked Sendable {} extension CriticalErrorCode: @unchecked Sendable {} extension Position: @unchecked Sendable {} @@ -2360,26 +2211,6 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { ] } -extension Team: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "CLEAR"), - 1: .same(proto: "CYAN"), - 2: .same(proto: "WHITE"), - 3: .same(proto: "YELLOW"), - 4: .same(proto: "ORANGE"), - 5: .same(proto: "MAGENTA"), - 6: .same(proto: "RED"), - 7: .same(proto: "MAROON"), - 8: .same(proto: "PURPLE"), - 9: .same(proto: "DARK_BLUE"), - 10: .same(proto: "BLUE"), - 11: .same(proto: "TEAL"), - 12: .same(proto: "GREEN"), - 13: .same(proto: "DARK_GREEN"), - 14: .same(proto: "BROWN"), - ] -} - extension Constants: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 0: .same(proto: "Unused"), @@ -2664,7 +2495,6 @@ extension User: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, 4: .same(proto: "macaddr"), 6: .standard(proto: "hw_model"), 7: .standard(proto: "is_licensed"), - 8: .same(proto: "team"), 10: .standard(proto: "tx_power_dbm"), 11: .standard(proto: "ant_gain_dbi"), 12: .standard(proto: "ant_azimuth"), @@ -2682,7 +2512,6 @@ extension User: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, case 4: try { try decoder.decodeSingularBytesField(value: &self.macaddr) }() case 6: try { try decoder.decodeSingularEnumField(value: &self.hwModel) }() case 7: try { try decoder.decodeSingularBoolField(value: &self.isLicensed) }() - case 8: try { try decoder.decodeSingularEnumField(value: &self.team) }() case 10: try { try decoder.decodeSingularUInt32Field(value: &self.txPowerDbm) }() case 11: try { try decoder.decodeSingularUInt32Field(value: &self.antGainDbi) }() case 12: try { try decoder.decodeSingularUInt32Field(value: &self.antAzimuth) }() @@ -2710,9 +2539,6 @@ extension User: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, if self.isLicensed != false { try visitor.visitSingularBoolField(value: self.isLicensed, fieldNumber: 7) } - if self.team != .clear { - try visitor.visitSingularEnumField(value: self.team, fieldNumber: 8) - } if self.txPowerDbm != 0 { try visitor.visitSingularUInt32Field(value: self.txPowerDbm, fieldNumber: 10) } @@ -2732,7 +2558,6 @@ extension User: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, if lhs.macaddr != rhs.macaddr {return false} if lhs.hwModel != rhs.hwModel {return false} if lhs.isLicensed != rhs.isLicensed {return false} - if lhs.team != rhs.team {return false} if lhs.txPowerDbm != rhs.txPowerDbm {return false} if lhs.antGainDbi != rhs.antGainDbi {return false} if lhs.antAzimuth != rhs.antAzimuth {return false} diff --git a/MeshtasticClient/Protobufs/radioconfig.pb.swift b/MeshtasticClient/Protobufs/radioconfig.pb.swift index 83453149..53e39e75 100644 --- a/MeshtasticClient/Protobufs/radioconfig.pb.swift +++ b/MeshtasticClient/Protobufs/radioconfig.pb.swift @@ -1104,70 +1104,6 @@ struct RadioConfig { set {_uniqueStorage()._storeForwardModuleHistoryReturnWindow = newValue} } - /// - /// Preferences for the Telemetry Module (Environment) - /// FIXME - Move this out of UserPreferences and into a section for module configuration. - /// Enable/Disable the telemetry measurement module measurement collection - var telemetryModuleEnvironmentMeasurementEnabled: Bool { - get {return _storage._telemetryModuleEnvironmentMeasurementEnabled} - set {_uniqueStorage()._telemetryModuleEnvironmentMeasurementEnabled = newValue} - } - - /// - /// Enable/Disable the telemetry measurement module on-device display - var telemetryModuleEnvironmentScreenEnabled: Bool { - get {return _storage._telemetryModuleEnvironmentScreenEnabled} - set {_uniqueStorage()._telemetryModuleEnvironmentScreenEnabled = newValue} - } - - /// - /// Sometimes sensor reads can fail. - /// If this happens, we will retry a configurable number of attempts, - /// each attempt will be delayed by the minimum required refresh rate for that sensor - var telemetryModuleEnvironmentReadErrorCountThreshold: UInt32 { - get {return _storage._telemetryModuleEnvironmentReadErrorCountThreshold} - set {_uniqueStorage()._telemetryModuleEnvironmentReadErrorCountThreshold = newValue} - } - - /// - /// Interval in seconds of how often we should try to send our - /// measurements to the mesh - var telemetryModuleDeviceUpdateInterval: UInt32 { - get {return _storage._telemetryModuleDeviceUpdateInterval} - set {_uniqueStorage()._telemetryModuleDeviceUpdateInterval = newValue} - } - - /// - /// Sometimes we can end up with more than read_error_count_threshold failures. - /// In this case, we will stop trying to read from the sensor for a while. - /// Wait this long until trying to read from the sensor again - var telemetryModuleEnvironmentRecoveryInterval: UInt32 { - get {return _storage._telemetryModuleEnvironmentRecoveryInterval} - set {_uniqueStorage()._telemetryModuleEnvironmentRecoveryInterval = newValue} - } - - /// - /// We'll always read the sensor in Celsius, but sometimes we might want to - /// display the results in Fahrenheit as a "user preference". - var telemetryModuleEnvironmentDisplayFahrenheit: Bool { - get {return _storage._telemetryModuleEnvironmentDisplayFahrenheit} - set {_uniqueStorage()._telemetryModuleEnvironmentDisplayFahrenheit = newValue} - } - - /// - /// Specify the sensor type - var telemetryModuleEnvironmentSensorType: RadioConfig.UserPreferences.TelemetrySensorType { - get {return _storage._telemetryModuleEnvironmentSensorType} - set {_uniqueStorage()._telemetryModuleEnvironmentSensorType = newValue} - } - - /// - /// Specify the peferred GPIO Pin for sensor readings - var telemetryModuleEnvironmentSensorPin: UInt32 { - get {return _storage._telemetryModuleEnvironmentSensorPin} - set {_uniqueStorage()._telemetryModuleEnvironmentSensorPin = newValue} - } - /// /// Bit field of boolean configuration options for POSITION messages /// (bitwise OR of PositionFlags) @@ -1336,14 +1272,6 @@ struct RadioConfig { set {_uniqueStorage()._adcMultiplierOverride = newValue} } - /// - /// Interval in seconds of how often we should try to send our - /// environent measurements to the mesh - var telemetryModuleEnvironmentUpdateInterval: UInt32 { - get {return _storage._telemetryModuleEnvironmentUpdateInterval} - set {_uniqueStorage()._telemetryModuleEnvironmentUpdateInterval = newValue} - } - var unknownFields = SwiftProtobuf.UnknownStorage() /// @@ -1451,90 +1379,6 @@ struct RadioConfig { } - /// - /// TODO: REPLACE - enum TelemetrySensorType: SwiftProtobuf.Enum { - typealias RawValue = Int - - /// - /// No external telemetry sensor - case none // = 0 - - /// - /// TODO: REPLACE - case dht11 // = 1 - - /// - /// TODO: REPLACE - case ds18B20 // = 2 - - /// - /// TODO: REPLACE - case dht12 // = 3 - - /// - /// TODO: REPLACE - case dht21 // = 4 - - /// - /// TODO: REPLACE - case dht22 // = 5 - - /// - /// TODO: REPLACE - case bme280 // = 6 - - /// - /// TODO: REPLACE - case bme680 // = 7 - - /// - /// TODO: REPLACE - case mcp9808 // = 8 - - /// - /// TODO: REPLACE - case shtc3 // = 9 - case UNRECOGNIZED(Int) - - init() { - self = .none - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .none - case 1: self = .dht11 - case 2: self = .ds18B20 - case 3: self = .dht12 - case 4: self = .dht21 - case 5: self = .dht22 - case 6: self = .bme280 - case 7: self = .bme680 - case 8: self = .mcp9808 - case 9: self = .shtc3 - default: self = .UNRECOGNIZED(rawValue) - } - } - - var rawValue: Int { - switch self { - case .none: return 0 - case .dht11: return 1 - case .ds18B20: return 2 - case .dht12: return 3 - case .dht21: return 4 - case .dht22: return 5 - case .bme280: return 6 - case .bme680: return 7 - case .mcp9808: return 8 - case .shtc3: return 9 - case .UNRECOGNIZED(let i): return i - } - } - - } - init() {} fileprivate var _storage = _StorageClass.defaultInstance @@ -1578,22 +1422,6 @@ extension RadioConfig.UserPreferences.Serial_Mode: CaseIterable { ] } -extension RadioConfig.UserPreferences.TelemetrySensorType: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - static var allCases: [RadioConfig.UserPreferences.TelemetrySensorType] = [ - .none, - .dht11, - .ds18B20, - .dht12, - .dht21, - .dht22, - .bme280, - .bme680, - .mcp9808, - .shtc3, - ] -} - #endif // swift(>=4.2) #if swift(>=5.5) && canImport(_Concurrency) @@ -1607,7 +1435,6 @@ extension RadioConfig: @unchecked Sendable {} extension RadioConfig.UserPreferences: @unchecked Sendable {} extension RadioConfig.UserPreferences.Serial_Baud: @unchecked Sendable {} extension RadioConfig.UserPreferences.Serial_Mode: @unchecked Sendable {} -extension RadioConfig.UserPreferences.TelemetrySensorType: @unchecked Sendable {} #endif // swift(>=5.5) && canImport(_Concurrency) // MARK: - Code below here is support for the SwiftProtobuf runtime. @@ -1791,14 +1618,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes 137: .standard(proto: "store_forward_module_records"), 138: .standard(proto: "store_forward_module_history_return_max"), 139: .standard(proto: "store_forward_module_history_return_window"), - 140: .standard(proto: "telemetry_module_environment_measurement_enabled"), - 141: .standard(proto: "telemetry_module_environment_screen_enabled"), - 142: .standard(proto: "telemetry_module_environment_read_error_count_threshold"), - 143: .standard(proto: "telemetry_module_device_update_interval"), - 144: .standard(proto: "telemetry_module_environment_recovery_interval"), - 145: .standard(proto: "telemetry_module_environment_display_fahrenheit"), - 146: .standard(proto: "telemetry_module_environment_sensor_type"), - 147: .standard(proto: "telemetry_module_environment_sensor_pin"), 150: .standard(proto: "position_flags"), 151: .standard(proto: "is_always_powered"), 152: .standard(proto: "auto_screen_carousel_secs"), @@ -1821,7 +1640,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes 173: .standard(proto: "canned_message_module_send_bell"), 174: .standard(proto: "mqtt_encryption_enabled"), 175: .standard(proto: "adc_multiplier_override"), - 177: .standard(proto: "telemetry_module_environment_update_interval"), ] fileprivate class _StorageClass { @@ -1877,14 +1695,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes var _storeForwardModuleRecords: UInt32 = 0 var _storeForwardModuleHistoryReturnMax: UInt32 = 0 var _storeForwardModuleHistoryReturnWindow: UInt32 = 0 - var _telemetryModuleEnvironmentMeasurementEnabled: Bool = false - var _telemetryModuleEnvironmentScreenEnabled: Bool = false - var _telemetryModuleEnvironmentReadErrorCountThreshold: UInt32 = 0 - var _telemetryModuleDeviceUpdateInterval: UInt32 = 0 - var _telemetryModuleEnvironmentRecoveryInterval: UInt32 = 0 - var _telemetryModuleEnvironmentDisplayFahrenheit: Bool = false - var _telemetryModuleEnvironmentSensorType: RadioConfig.UserPreferences.TelemetrySensorType = .none - var _telemetryModuleEnvironmentSensorPin: UInt32 = 0 var _positionFlags: UInt32 = 0 var _isAlwaysPowered: Bool = false var _autoScreenCarouselSecs: UInt32 = 0 @@ -1907,7 +1717,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes var _cannedMessageModuleSendBell: Bool = false var _mqttEncryptionEnabled: Bool = false var _adcMultiplierOverride: Float = 0 - var _telemetryModuleEnvironmentUpdateInterval: UInt32 = 0 static let defaultInstance = _StorageClass() @@ -1966,14 +1775,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes _storeForwardModuleRecords = source._storeForwardModuleRecords _storeForwardModuleHistoryReturnMax = source._storeForwardModuleHistoryReturnMax _storeForwardModuleHistoryReturnWindow = source._storeForwardModuleHistoryReturnWindow - _telemetryModuleEnvironmentMeasurementEnabled = source._telemetryModuleEnvironmentMeasurementEnabled - _telemetryModuleEnvironmentScreenEnabled = source._telemetryModuleEnvironmentScreenEnabled - _telemetryModuleEnvironmentReadErrorCountThreshold = source._telemetryModuleEnvironmentReadErrorCountThreshold - _telemetryModuleDeviceUpdateInterval = source._telemetryModuleDeviceUpdateInterval - _telemetryModuleEnvironmentRecoveryInterval = source._telemetryModuleEnvironmentRecoveryInterval - _telemetryModuleEnvironmentDisplayFahrenheit = source._telemetryModuleEnvironmentDisplayFahrenheit - _telemetryModuleEnvironmentSensorType = source._telemetryModuleEnvironmentSensorType - _telemetryModuleEnvironmentSensorPin = source._telemetryModuleEnvironmentSensorPin _positionFlags = source._positionFlags _isAlwaysPowered = source._isAlwaysPowered _autoScreenCarouselSecs = source._autoScreenCarouselSecs @@ -1996,7 +1797,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes _cannedMessageModuleSendBell = source._cannedMessageModuleSendBell _mqttEncryptionEnabled = source._mqttEncryptionEnabled _adcMultiplierOverride = source._adcMultiplierOverride - _telemetryModuleEnvironmentUpdateInterval = source._telemetryModuleEnvironmentUpdateInterval } } @@ -2064,14 +1864,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes case 137: try { try decoder.decodeSingularUInt32Field(value: &_storage._storeForwardModuleRecords) }() case 138: try { try decoder.decodeSingularUInt32Field(value: &_storage._storeForwardModuleHistoryReturnMax) }() case 139: try { try decoder.decodeSingularUInt32Field(value: &_storage._storeForwardModuleHistoryReturnWindow) }() - case 140: try { try decoder.decodeSingularBoolField(value: &_storage._telemetryModuleEnvironmentMeasurementEnabled) }() - case 141: try { try decoder.decodeSingularBoolField(value: &_storage._telemetryModuleEnvironmentScreenEnabled) }() - case 142: try { try decoder.decodeSingularUInt32Field(value: &_storage._telemetryModuleEnvironmentReadErrorCountThreshold) }() - case 143: try { try decoder.decodeSingularUInt32Field(value: &_storage._telemetryModuleDeviceUpdateInterval) }() - case 144: try { try decoder.decodeSingularUInt32Field(value: &_storage._telemetryModuleEnvironmentRecoveryInterval) }() - case 145: try { try decoder.decodeSingularBoolField(value: &_storage._telemetryModuleEnvironmentDisplayFahrenheit) }() - case 146: try { try decoder.decodeSingularEnumField(value: &_storage._telemetryModuleEnvironmentSensorType) }() - case 147: try { try decoder.decodeSingularUInt32Field(value: &_storage._telemetryModuleEnvironmentSensorPin) }() case 148: try { try decoder.decodeSingularBoolField(value: &_storage._storeForwardModuleEnabled) }() case 149: try { try decoder.decodeSingularBoolField(value: &_storage._storeForwardModuleHeartbeat) }() case 150: try { try decoder.decodeSingularUInt32Field(value: &_storage._positionFlags) }() @@ -2097,7 +1889,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes case 174: try { try decoder.decodeSingularBoolField(value: &_storage._mqttEncryptionEnabled) }() case 175: try { try decoder.decodeSingularFloatField(value: &_storage._adcMultiplierOverride) }() case 176: try { try decoder.decodeSingularEnumField(value: &_storage._serialModuleBaud) }() - case 177: try { try decoder.decodeSingularUInt32Field(value: &_storage._telemetryModuleEnvironmentUpdateInterval) }() default: break } } @@ -2253,30 +2044,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._storeForwardModuleHistoryReturnWindow != 0 { try visitor.visitSingularUInt32Field(value: _storage._storeForwardModuleHistoryReturnWindow, fieldNumber: 139) } - if _storage._telemetryModuleEnvironmentMeasurementEnabled != false { - try visitor.visitSingularBoolField(value: _storage._telemetryModuleEnvironmentMeasurementEnabled, fieldNumber: 140) - } - if _storage._telemetryModuleEnvironmentScreenEnabled != false { - try visitor.visitSingularBoolField(value: _storage._telemetryModuleEnvironmentScreenEnabled, fieldNumber: 141) - } - if _storage._telemetryModuleEnvironmentReadErrorCountThreshold != 0 { - try visitor.visitSingularUInt32Field(value: _storage._telemetryModuleEnvironmentReadErrorCountThreshold, fieldNumber: 142) - } - if _storage._telemetryModuleDeviceUpdateInterval != 0 { - try visitor.visitSingularUInt32Field(value: _storage._telemetryModuleDeviceUpdateInterval, fieldNumber: 143) - } - if _storage._telemetryModuleEnvironmentRecoveryInterval != 0 { - try visitor.visitSingularUInt32Field(value: _storage._telemetryModuleEnvironmentRecoveryInterval, fieldNumber: 144) - } - if _storage._telemetryModuleEnvironmentDisplayFahrenheit != false { - try visitor.visitSingularBoolField(value: _storage._telemetryModuleEnvironmentDisplayFahrenheit, fieldNumber: 145) - } - if _storage._telemetryModuleEnvironmentSensorType != .none { - try visitor.visitSingularEnumField(value: _storage._telemetryModuleEnvironmentSensorType, fieldNumber: 146) - } - if _storage._telemetryModuleEnvironmentSensorPin != 0 { - try visitor.visitSingularUInt32Field(value: _storage._telemetryModuleEnvironmentSensorPin, fieldNumber: 147) - } if _storage._storeForwardModuleEnabled != false { try visitor.visitSingularBoolField(value: _storage._storeForwardModuleEnabled, fieldNumber: 148) } @@ -2352,9 +2119,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._serialModuleBaud != .baudDefault { try visitor.visitSingularEnumField(value: _storage._serialModuleBaud, fieldNumber: 176) } - if _storage._telemetryModuleEnvironmentUpdateInterval != 0 { - try visitor.visitSingularUInt32Field(value: _storage._telemetryModuleEnvironmentUpdateInterval, fieldNumber: 177) - } } try unknownFields.traverse(visitor: &visitor) } @@ -2416,14 +2180,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._storeForwardModuleRecords != rhs_storage._storeForwardModuleRecords {return false} if _storage._storeForwardModuleHistoryReturnMax != rhs_storage._storeForwardModuleHistoryReturnMax {return false} if _storage._storeForwardModuleHistoryReturnWindow != rhs_storage._storeForwardModuleHistoryReturnWindow {return false} - if _storage._telemetryModuleEnvironmentMeasurementEnabled != rhs_storage._telemetryModuleEnvironmentMeasurementEnabled {return false} - if _storage._telemetryModuleEnvironmentScreenEnabled != rhs_storage._telemetryModuleEnvironmentScreenEnabled {return false} - if _storage._telemetryModuleEnvironmentReadErrorCountThreshold != rhs_storage._telemetryModuleEnvironmentReadErrorCountThreshold {return false} - if _storage._telemetryModuleDeviceUpdateInterval != rhs_storage._telemetryModuleDeviceUpdateInterval {return false} - if _storage._telemetryModuleEnvironmentRecoveryInterval != rhs_storage._telemetryModuleEnvironmentRecoveryInterval {return false} - if _storage._telemetryModuleEnvironmentDisplayFahrenheit != rhs_storage._telemetryModuleEnvironmentDisplayFahrenheit {return false} - if _storage._telemetryModuleEnvironmentSensorType != rhs_storage._telemetryModuleEnvironmentSensorType {return false} - if _storage._telemetryModuleEnvironmentSensorPin != rhs_storage._telemetryModuleEnvironmentSensorPin {return false} if _storage._positionFlags != rhs_storage._positionFlags {return false} if _storage._isAlwaysPowered != rhs_storage._isAlwaysPowered {return false} if _storage._autoScreenCarouselSecs != rhs_storage._autoScreenCarouselSecs {return false} @@ -2446,7 +2202,6 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._cannedMessageModuleSendBell != rhs_storage._cannedMessageModuleSendBell {return false} if _storage._mqttEncryptionEnabled != rhs_storage._mqttEncryptionEnabled {return false} if _storage._adcMultiplierOverride != rhs_storage._adcMultiplierOverride {return false} - if _storage._telemetryModuleEnvironmentUpdateInterval != rhs_storage._telemetryModuleEnvironmentUpdateInterval {return false} return true } if !storagesAreEqual {return false} @@ -2484,18 +2239,3 @@ extension RadioConfig.UserPreferences.Serial_Mode: SwiftProtobuf._ProtoNameProvi 2: .same(proto: "MODE_PROTO"), ] } - -extension RadioConfig.UserPreferences.TelemetrySensorType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "None"), - 1: .same(proto: "DHT11"), - 2: .same(proto: "DS18B20"), - 3: .same(proto: "DHT12"), - 4: .same(proto: "DHT21"), - 5: .same(proto: "DHT22"), - 6: .same(proto: "BME280"), - 7: .same(proto: "BME680"), - 8: .same(proto: "MCP9808"), - 9: .same(proto: "SHTC3"), - ] -} diff --git a/MeshtasticClient/Protobufs/telemetry.pb.swift b/MeshtasticClient/Protobufs/telemetry.pb.swift index 9f22221c..3dfbd79e 100644 --- a/MeshtasticClient/Protobufs/telemetry.pb.swift +++ b/MeshtasticClient/Protobufs/telemetry.pb.swift @@ -20,6 +20,110 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } +/// +/// TODO: REPLACE +enum TelemetrySensorType: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// No external telemetry sensor + case notSet // = 0 + + /// + /// TODO: REPLACE + case dht11 // = 1 + + /// + /// TODO: REPLACE + case ds18B20 // = 2 + + /// + /// TODO: REPLACE + case dht12 // = 3 + + /// + /// TODO: REPLACE + case dht21 // = 4 + + /// + /// TODO: REPLACE + case dht22 // = 5 + + /// + /// TODO: REPLACE + case bme280 // = 6 + + /// + /// TODO: REPLACE + case bme680 // = 7 + + /// + /// TODO: REPLACE + case mcp9808 // = 8 + + /// + /// TODO: REPLACE + case shtc3 // = 9 + case UNRECOGNIZED(Int) + + init() { + self = .notSet + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .notSet + case 1: self = .dht11 + case 2: self = .ds18B20 + case 3: self = .dht12 + case 4: self = .dht21 + case 5: self = .dht22 + case 6: self = .bme280 + case 7: self = .bme680 + case 8: self = .mcp9808 + case 9: self = .shtc3 + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .notSet: return 0 + case .dht11: return 1 + case .ds18B20: return 2 + case .dht12: return 3 + case .dht21: return 4 + case .dht22: return 5 + case .bme280: return 6 + case .bme680: return 7 + case .mcp9808: return 8 + case .shtc3: return 9 + case .UNRECOGNIZED(let i): return i + } + } + +} + +#if swift(>=4.2) + +extension TelemetrySensorType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [TelemetrySensorType] = [ + .notSet, + .dht11, + .ds18B20, + .dht12, + .dht21, + .dht22, + .bme280, + .bme680, + .mcp9808, + .shtc3, + ] +} + +#endif // swift(>=4.2) + /// /// Key native device metrics such as battery level struct DeviceMetrics { @@ -155,6 +259,7 @@ struct Telemetry { } #if swift(>=5.5) && canImport(_Concurrency) +extension TelemetrySensorType: @unchecked Sendable {} extension DeviceMetrics: @unchecked Sendable {} extension EnvironmentMetrics: @unchecked Sendable {} extension Telemetry: @unchecked Sendable {} @@ -163,6 +268,21 @@ extension Telemetry.OneOf_Variant: @unchecked Sendable {} // MARK: - Code below here is support for the SwiftProtobuf runtime. +extension TelemetrySensorType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "NotSet"), + 1: .same(proto: "DHT11"), + 2: .same(proto: "DS18B20"), + 3: .same(proto: "DHT12"), + 4: .same(proto: "DHT21"), + 5: .same(proto: "DHT22"), + 6: .same(proto: "BME280"), + 7: .same(proto: "BME680"), + 8: .same(proto: "MCP9808"), + 9: .same(proto: "SHTC3"), + ] +} + extension DeviceMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "DeviceMetrics" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ diff --git a/MeshtasticClient/Views/Nodes/NodeDetail.swift b/MeshtasticClient/Views/Nodes/NodeDetail.swift index 6bd11342..e3bd2df1 100644 --- a/MeshtasticClient/Views/Nodes/NodeDetail.swift +++ b/MeshtasticClient/Views/Nodes/NodeDetail.swift @@ -123,15 +123,15 @@ struct NodeDetail: View { .padding(5) } - if node.positions?.count ?? 0 >= 1 { + if node.telemetries?.count ?? 0 >= 1 { - let mostRecent = node.positions?.lastObject as! PositionEntity + let mostRecent = node.telemetries?.lastObject as! TelemetryEntity Divider() VStack(alignment: .center) { - BatteryIcon(batteryLevel: 100, font: .title, color: .accentColor) + BatteryIcon(batteryLevel: mostRecent.batteryLevel, font: .title, color: .accentColor) .padding(.bottom) } diff --git a/gen_protos.sh b/gen_protos.sh index ec9f89be..a07c2b40 100755 --- a/gen_protos.sh +++ b/gen_protos.sh @@ -15,7 +15,7 @@ fi pdir=$(realpath "../Meshtastic-protobufs") sdir=$(realpath "./MeshtasticClient/Protobufs") echo "pdir:$pdir sdir:$sdir" -pfiles="admin.proto apponly.proto cannedmessages.proto channel.proto deviceonly.proto mesh.proto mqtt.proto portnums.proto radioconfig.proto remote_hardware.proto storeforward.proto telemetry.proto" +pfiles="admin.proto apponly.proto cannedmessages.proto channel.proto config.proto deviceonly.proto mesh.proto module_config.proto mqtt.proto portnums.proto radioconfig.proto remote_hardware.proto storeforward.proto telemetry.proto" for pf in $pfiles do echo "Generating $pf..." From b4a76c3ed21747a5e993fbab552de8113421273a Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 5 May 2022 18:50:03 -0700 Subject: [PATCH 15/21] Add new config photos --- MeshtasticClient/Protobufs/config.pb.swift | 1210 +++++++++++++++++ .../Protobufs/module_config.pb.swift | 665 +++++++++ 2 files changed, 1875 insertions(+) create mode 100644 MeshtasticClient/Protobufs/config.pb.swift create mode 100644 MeshtasticClient/Protobufs/module_config.pb.swift diff --git a/MeshtasticClient/Protobufs/config.pb.swift b/MeshtasticClient/Protobufs/config.pb.swift new file mode 100644 index 00000000..97689ce2 --- /dev/null +++ b/MeshtasticClient/Protobufs/config.pb.swift @@ -0,0 +1,1210 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: config.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// 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. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +struct Config { + // 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. + + /// + /// TODO: REPLACE + var payloadVariant: Config.OneOf_PayloadVariant? = nil + + /// + /// TODO: REPLACE + var deviceConfig: Config.DeviceConfig { + get { + if case .deviceConfig(let v)? = payloadVariant {return v} + return Config.DeviceConfig() + } + set {payloadVariant = .deviceConfig(newValue)} + } + + /// + /// TODO: REPLACE + var gpsConfig: Config.GpsConfig { + get { + if case .gpsConfig(let v)? = payloadVariant {return v} + return Config.GpsConfig() + } + set {payloadVariant = .gpsConfig(newValue)} + } + + /// + /// TODO: REPLACE + var powerConfig: Config.PowerConfig { + get { + if case .powerConfig(let v)? = payloadVariant {return v} + return Config.PowerConfig() + } + set {payloadVariant = .powerConfig(newValue)} + } + + /// + /// TODO: REPLACE + var wifiConfig: Config.WiFiConfig { + get { + if case .wifiConfig(let v)? = payloadVariant {return v} + return Config.WiFiConfig() + } + set {payloadVariant = .wifiConfig(newValue)} + } + + /// + /// TODO: REPLACE + var displayConfig: Config.DisplayConfig { + get { + if case .displayConfig(let v)? = payloadVariant {return v} + return Config.DisplayConfig() + } + set {payloadVariant = .displayConfig(newValue)} + } + + /// + /// TODO: REPLACE + var loraConfig: Config.LoRaConfig { + get { + if case .loraConfig(let v)? = payloadVariant {return v} + return Config.LoRaConfig() + } + set {payloadVariant = .loraConfig(newValue)} + } + + /// + /// TODO: REPLACE + var moduleConfig: Config.ModuleConfig { + get { + if case .moduleConfig(let v)? = payloadVariant {return v} + return Config.ModuleConfig() + } + set {payloadVariant = .moduleConfig(newValue)} + } + + var unknownFields = SwiftProtobuf.UnknownStorage() + + /// + /// TODO: REPLACE + enum OneOf_PayloadVariant: Equatable { + /// + /// TODO: REPLACE + case deviceConfig(Config.DeviceConfig) + /// + /// TODO: REPLACE + case gpsConfig(Config.GpsConfig) + /// + /// TODO: REPLACE + case powerConfig(Config.PowerConfig) + /// + /// TODO: REPLACE + case wifiConfig(Config.WiFiConfig) + /// + /// TODO: REPLACE + case displayConfig(Config.DisplayConfig) + /// + /// TODO: REPLACE + case loraConfig(Config.LoRaConfig) + /// + /// TODO: REPLACE + case moduleConfig(Config.ModuleConfig) + + #if !swift(>=4.1) + static func ==(lhs: Config.OneOf_PayloadVariant, rhs: Config.OneOf_PayloadVariant) -> Bool { + // 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 (lhs, rhs) { + case (.deviceConfig, .deviceConfig): return { + guard case .deviceConfig(let l) = lhs, case .deviceConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.gpsConfig, .gpsConfig): return { + guard case .gpsConfig(let l) = lhs, case .gpsConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.powerConfig, .powerConfig): return { + guard case .powerConfig(let l) = lhs, case .powerConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.wifiConfig, .wifiConfig): return { + guard case .wifiConfig(let l) = lhs, case .wifiConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.displayConfig, .displayConfig): return { + guard case .displayConfig(let l) = lhs, case .displayConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.loraConfig, .loraConfig): return { + guard case .loraConfig(let l) = lhs, case .loraConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.moduleConfig, .moduleConfig): return { + guard case .moduleConfig(let l) = lhs, case .moduleConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif + } + + /// + /// TODO: REPLACE + struct DeviceConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct GpsConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct PowerConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct WiFiConfig { + // 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. + + /// + /// If set, this node will try to join the specified wifi network and + /// acquire an address via DHCP + var wifiSsid: String = String() + + /// + /// If set, will be use to authenticate to the named wifi + var wifiPassword: String = String() + + /// + /// If set, the node will operate as an AP (and DHCP server), otherwise it + /// will be a station + var wifiApMode: Bool = false + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct DisplayConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct LoRaConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct ModuleConfig { + // 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. + + /// + /// TODO: REPLACE + var payloadVariant: Config.ModuleConfig.OneOf_PayloadVariant? = nil + + /// + /// TODO: REPLACE + var mqttConfig: Config.ModuleConfig.MQTTConfig { + get { + if case .mqttConfig(let v)? = payloadVariant {return v} + return Config.ModuleConfig.MQTTConfig() + } + set {payloadVariant = .mqttConfig(newValue)} + } + + /// + /// TODO: REPLACE + var serialConfig: Config.ModuleConfig.SerialConfig { + get { + if case .serialConfig(let v)? = payloadVariant {return v} + return Config.ModuleConfig.SerialConfig() + } + set {payloadVariant = .serialConfig(newValue)} + } + + /// + /// TODO: REPLACE + var externalNotificationConfig: Config.ModuleConfig.ExternalNotificationConfig { + get { + if case .externalNotificationConfig(let v)? = payloadVariant {return v} + return Config.ModuleConfig.ExternalNotificationConfig() + } + set {payloadVariant = .externalNotificationConfig(newValue)} + } + + /// + /// TODO: REPLACE + var storeForwardConfig: Config.ModuleConfig.StoreForwardConfig { + get { + if case .storeForwardConfig(let v)? = payloadVariant {return v} + return Config.ModuleConfig.StoreForwardConfig() + } + set {payloadVariant = .storeForwardConfig(newValue)} + } + + /// + /// TODO: REPLACE + var rangeTestConfig: Config.ModuleConfig.RangeTestConfig { + get { + if case .rangeTestConfig(let v)? = payloadVariant {return v} + return Config.ModuleConfig.RangeTestConfig() + } + set {payloadVariant = .rangeTestConfig(newValue)} + } + + /// + /// TODO: REPLACE + var telemetryConfig: Config.ModuleConfig.TelemetryConfig { + get { + if case .telemetryConfig(let v)? = payloadVariant {return v} + return Config.ModuleConfig.TelemetryConfig() + } + set {payloadVariant = .telemetryConfig(newValue)} + } + + /// + /// TODO: REPLACE + var cannedMessageConfig: Config.ModuleConfig.CannedMessageConfig { + get { + if case .cannedMessageConfig(let v)? = payloadVariant {return v} + return Config.ModuleConfig.CannedMessageConfig() + } + set {payloadVariant = .cannedMessageConfig(newValue)} + } + + var unknownFields = SwiftProtobuf.UnknownStorage() + + /// + /// TODO: REPLACE + enum OneOf_PayloadVariant: Equatable { + /// + /// TODO: REPLACE + case mqttConfig(Config.ModuleConfig.MQTTConfig) + /// + /// TODO: REPLACE + case serialConfig(Config.ModuleConfig.SerialConfig) + /// + /// TODO: REPLACE + case externalNotificationConfig(Config.ModuleConfig.ExternalNotificationConfig) + /// + /// TODO: REPLACE + case storeForwardConfig(Config.ModuleConfig.StoreForwardConfig) + /// + /// TODO: REPLACE + case rangeTestConfig(Config.ModuleConfig.RangeTestConfig) + /// + /// TODO: REPLACE + case telemetryConfig(Config.ModuleConfig.TelemetryConfig) + /// + /// TODO: REPLACE + case cannedMessageConfig(Config.ModuleConfig.CannedMessageConfig) + + #if !swift(>=4.1) + static func ==(lhs: Config.ModuleConfig.OneOf_PayloadVariant, rhs: Config.ModuleConfig.OneOf_PayloadVariant) -> Bool { + // 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 (lhs, rhs) { + case (.mqttConfig, .mqttConfig): return { + guard case .mqttConfig(let l) = lhs, case .mqttConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.serialConfig, .serialConfig): return { + guard case .serialConfig(let l) = lhs, case .serialConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.externalNotificationConfig, .externalNotificationConfig): return { + guard case .externalNotificationConfig(let l) = lhs, case .externalNotificationConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.storeForwardConfig, .storeForwardConfig): return { + guard case .storeForwardConfig(let l) = lhs, case .storeForwardConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.rangeTestConfig, .rangeTestConfig): return { + guard case .rangeTestConfig(let l) = lhs, case .rangeTestConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.telemetryConfig, .telemetryConfig): return { + guard case .telemetryConfig(let l) = lhs, case .telemetryConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.cannedMessageConfig, .cannedMessageConfig): return { + guard case .cannedMessageConfig(let l) = lhs, case .cannedMessageConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif + } + + /// + /// TODO: REPLACE + struct MQTTConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct SerialConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct ExternalNotificationConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct StoreForwardConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct RangeTestConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// Configuration for both device and environment metrics + struct TelemetryConfig { + // 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. + + /// + /// Interval in seconds of how often we should try to send our + /// device measurements to the mesh + var deviceUpdateInterval: UInt32 = 0 + + /// + /// Interval in seconds of how often we should try to send our + /// environment measurements to the mesh + var environmentUpdateInterval: UInt32 = 0 + + /// + /// Preferences for the Telemetry Module (Environment) + /// Enable/Disable the telemetry measurement module measurement collection + var environmentMeasurementEnabled: Bool = false + + /// + /// Enable/Disable the telemetry measurement module on-device display + var environmentScreenEnabled: Bool = false + + /// + /// Sometimes sensor reads can fail. + /// If this happens, we will retry a configurable number of attempts, + /// each attempt will be delayed by the minimum required refresh rate for that sensor + var environmentReadErrorCountThreshold: UInt32 = 0 + + /// + /// Sometimes we can end up with more than read_error_count_threshold failures. + /// In this case, we will stop trying to read from the sensor for a while. + /// Wait this long until trying to read from the sensor again + var environmentRecoveryInterval: UInt32 = 0 + + /// + /// We'll always read the sensor in Celsius, but sometimes we might want to + /// display the results in Fahrenheit as a "user preference". + var environmentDisplayFahrenheit: Bool = false + + /// + /// Specify the sensor type + var environmentSensorType: TelemetrySensorType = .notSet + + /// + /// Specify the peferred GPIO Pin for sensor readings + var environmentSensorPin: UInt32 = 0 + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct CannedMessageConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + init() {} + } + + init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Config: @unchecked Sendable {} +extension Config.OneOf_PayloadVariant: @unchecked Sendable {} +extension Config.DeviceConfig: @unchecked Sendable {} +extension Config.GpsConfig: @unchecked Sendable {} +extension Config.PowerConfig: @unchecked Sendable {} +extension Config.WiFiConfig: @unchecked Sendable {} +extension Config.DisplayConfig: @unchecked Sendable {} +extension Config.LoRaConfig: @unchecked Sendable {} +extension Config.ModuleConfig: @unchecked Sendable {} +extension Config.ModuleConfig.OneOf_PayloadVariant: @unchecked Sendable {} +extension Config.ModuleConfig.MQTTConfig: @unchecked Sendable {} +extension Config.ModuleConfig.SerialConfig: @unchecked Sendable {} +extension Config.ModuleConfig.ExternalNotificationConfig: @unchecked Sendable {} +extension Config.ModuleConfig.StoreForwardConfig: @unchecked Sendable {} +extension Config.ModuleConfig.RangeTestConfig: @unchecked Sendable {} +extension Config.ModuleConfig.TelemetryConfig: @unchecked Sendable {} +extension Config.ModuleConfig.CannedMessageConfig: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = "Config" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "device_config"), + 2: .standard(proto: "gps_config"), + 3: .standard(proto: "power_config"), + 4: .standard(proto: "wifi_config"), + 5: .standard(proto: "display_config"), + 6: .standard(proto: "lora_config"), + 7: .standard(proto: "module_config"), + ] + + 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 { + var v: Config.DeviceConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .deviceConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .deviceConfig(v) + } + }() + case 2: try { + var v: Config.GpsConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .gpsConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .gpsConfig(v) + } + }() + case 3: try { + var v: Config.PowerConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .powerConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .powerConfig(v) + } + }() + case 4: try { + var v: Config.WiFiConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .wifiConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .wifiConfig(v) + } + }() + case 5: try { + var v: Config.DisplayConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .displayConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .displayConfig(v) + } + }() + case 6: try { + var v: Config.LoRaConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .loraConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .loraConfig(v) + } + }() + case 7: try { + var v: Config.ModuleConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .moduleConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .moduleConfig(v) + } + }() + 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 + switch self.payloadVariant { + case .deviceConfig?: try { + guard case .deviceConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + }() + case .gpsConfig?: try { + guard case .gpsConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + }() + case .powerConfig?: try { + guard case .powerConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + }() + case .wifiConfig?: try { + guard case .wifiConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + }() + case .displayConfig?: try { + guard case .displayConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + }() + case .loraConfig?: try { + guard case .loraConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + }() + case .moduleConfig?: try { + guard case .moduleConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + }() + case nil: break + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config, rhs: Config) -> Bool { + if lhs.payloadVariant != rhs.payloadVariant {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.protoMessageName + ".DeviceConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.DeviceConfig, rhs: Config.DeviceConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.GpsConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.protoMessageName + ".GpsConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.GpsConfig, rhs: Config.GpsConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.protoMessageName + ".PowerConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.PowerConfig, rhs: Config.PowerConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.WiFiConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.protoMessageName + ".WiFiConfig" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "wifi_ssid"), + 2: .standard(proto: "wifi_password"), + 3: .standard(proto: "wifi_ap_mode"), + ] + + 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.decodeSingularStringField(value: &self.wifiSsid) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.wifiPassword) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.wifiApMode) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if !self.wifiSsid.isEmpty { + try visitor.visitSingularStringField(value: self.wifiSsid, fieldNumber: 1) + } + if !self.wifiPassword.isEmpty { + try visitor.visitSingularStringField(value: self.wifiPassword, fieldNumber: 2) + } + if self.wifiApMode != false { + try visitor.visitSingularBoolField(value: self.wifiApMode, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.WiFiConfig, rhs: Config.WiFiConfig) -> Bool { + if lhs.wifiSsid != rhs.wifiSsid {return false} + if lhs.wifiPassword != rhs.wifiPassword {return false} + if lhs.wifiApMode != rhs.wifiApMode {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.DisplayConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.protoMessageName + ".DisplayConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.DisplayConfig, rhs: Config.DisplayConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.protoMessageName + ".LoRaConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.LoRaConfig, rhs: Config.LoRaConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.protoMessageName + ".ModuleConfig" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "mqtt_config"), + 2: .standard(proto: "serial_config"), + 3: .standard(proto: "external_notification_config"), + 4: .standard(proto: "store_forward_config"), + 5: .standard(proto: "range_test_config"), + 6: .standard(proto: "telemetry_config"), + 7: .standard(proto: "canned_message_config"), + ] + + 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 { + var v: Config.ModuleConfig.MQTTConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .mqttConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .mqttConfig(v) + } + }() + case 2: try { + var v: Config.ModuleConfig.SerialConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .serialConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .serialConfig(v) + } + }() + case 3: try { + var v: Config.ModuleConfig.ExternalNotificationConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .externalNotificationConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .externalNotificationConfig(v) + } + }() + case 4: try { + var v: Config.ModuleConfig.StoreForwardConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .storeForwardConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .storeForwardConfig(v) + } + }() + case 5: try { + var v: Config.ModuleConfig.RangeTestConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .rangeTestConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .rangeTestConfig(v) + } + }() + case 6: try { + var v: Config.ModuleConfig.TelemetryConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .telemetryConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .telemetryConfig(v) + } + }() + case 7: try { + var v: Config.ModuleConfig.CannedMessageConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .cannedMessageConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .cannedMessageConfig(v) + } + }() + 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 + switch self.payloadVariant { + case .mqttConfig?: try { + guard case .mqttConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + }() + case .serialConfig?: try { + guard case .serialConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + }() + case .externalNotificationConfig?: try { + guard case .externalNotificationConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + }() + case .storeForwardConfig?: try { + guard case .storeForwardConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + }() + case .rangeTestConfig?: try { + guard case .rangeTestConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + }() + case .telemetryConfig?: try { + guard case .telemetryConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + }() + case .cannedMessageConfig?: try { + guard case .cannedMessageConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + }() + case nil: break + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.ModuleConfig, rhs: Config.ModuleConfig) -> Bool { + if lhs.payloadVariant != rhs.payloadVariant {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.ModuleConfig.MQTTConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".MQTTConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.ModuleConfig.MQTTConfig, rhs: Config.ModuleConfig.MQTTConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.ModuleConfig.SerialConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".SerialConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.ModuleConfig.SerialConfig, rhs: Config.ModuleConfig.SerialConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.ModuleConfig.ExternalNotificationConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".ExternalNotificationConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.ModuleConfig.ExternalNotificationConfig, rhs: Config.ModuleConfig.ExternalNotificationConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.ModuleConfig.StoreForwardConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".StoreForwardConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.ModuleConfig.StoreForwardConfig, rhs: Config.ModuleConfig.StoreForwardConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.ModuleConfig.RangeTestConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".RangeTestConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.ModuleConfig.RangeTestConfig, rhs: Config.ModuleConfig.RangeTestConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.ModuleConfig.TelemetryConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".TelemetryConfig" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "device_update_interval"), + 2: .standard(proto: "environment_update_interval"), + 3: .standard(proto: "environment_measurement_enabled"), + 4: .standard(proto: "environment_screen_enabled"), + 5: .standard(proto: "environment_read_error_count_threshold"), + 6: .standard(proto: "environment_recovery_interval"), + 7: .standard(proto: "environment_display_fahrenheit"), + 8: .standard(proto: "environment_sensor_type"), + 9: .standard(proto: "environment_sensor_pin"), + ] + + 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.deviceUpdateInterval) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.environmentUpdateInterval) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.environmentMeasurementEnabled) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self.environmentScreenEnabled) }() + case 5: try { try decoder.decodeSingularUInt32Field(value: &self.environmentReadErrorCountThreshold) }() + case 6: try { try decoder.decodeSingularUInt32Field(value: &self.environmentRecoveryInterval) }() + case 7: try { try decoder.decodeSingularBoolField(value: &self.environmentDisplayFahrenheit) }() + case 8: try { try decoder.decodeSingularEnumField(value: &self.environmentSensorType) }() + case 9: try { try decoder.decodeSingularUInt32Field(value: &self.environmentSensorPin) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.deviceUpdateInterval != 0 { + try visitor.visitSingularUInt32Field(value: self.deviceUpdateInterval, fieldNumber: 1) + } + if self.environmentUpdateInterval != 0 { + try visitor.visitSingularUInt32Field(value: self.environmentUpdateInterval, fieldNumber: 2) + } + if self.environmentMeasurementEnabled != false { + try visitor.visitSingularBoolField(value: self.environmentMeasurementEnabled, fieldNumber: 3) + } + if self.environmentScreenEnabled != false { + try visitor.visitSingularBoolField(value: self.environmentScreenEnabled, fieldNumber: 4) + } + if self.environmentReadErrorCountThreshold != 0 { + try visitor.visitSingularUInt32Field(value: self.environmentReadErrorCountThreshold, fieldNumber: 5) + } + if self.environmentRecoveryInterval != 0 { + try visitor.visitSingularUInt32Field(value: self.environmentRecoveryInterval, fieldNumber: 6) + } + if self.environmentDisplayFahrenheit != false { + try visitor.visitSingularBoolField(value: self.environmentDisplayFahrenheit, fieldNumber: 7) + } + if self.environmentSensorType != .notSet { + try visitor.visitSingularEnumField(value: self.environmentSensorType, fieldNumber: 8) + } + if self.environmentSensorPin != 0 { + try visitor.visitSingularUInt32Field(value: self.environmentSensorPin, fieldNumber: 9) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.ModuleConfig.TelemetryConfig, rhs: Config.ModuleConfig.TelemetryConfig) -> Bool { + if lhs.deviceUpdateInterval != rhs.deviceUpdateInterval {return false} + if lhs.environmentUpdateInterval != rhs.environmentUpdateInterval {return false} + if lhs.environmentMeasurementEnabled != rhs.environmentMeasurementEnabled {return false} + if lhs.environmentScreenEnabled != rhs.environmentScreenEnabled {return false} + if lhs.environmentReadErrorCountThreshold != rhs.environmentReadErrorCountThreshold {return false} + if lhs.environmentRecoveryInterval != rhs.environmentRecoveryInterval {return false} + if lhs.environmentDisplayFahrenheit != rhs.environmentDisplayFahrenheit {return false} + if lhs.environmentSensorType != rhs.environmentSensorType {return false} + if lhs.environmentSensorPin != rhs.environmentSensorPin {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.ModuleConfig.CannedMessageConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".CannedMessageConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.ModuleConfig.CannedMessageConfig, rhs: Config.ModuleConfig.CannedMessageConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/MeshtasticClient/Protobufs/module_config.pb.swift b/MeshtasticClient/Protobufs/module_config.pb.swift new file mode 100644 index 00000000..6a2c4041 --- /dev/null +++ b/MeshtasticClient/Protobufs/module_config.pb.swift @@ -0,0 +1,665 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: module_config.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// 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. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// +/// TODO: REPLACE +struct ModuleConfig { + // 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. + + /// + /// TODO: REPLACE + var payloadVariant: ModuleConfig.OneOf_PayloadVariant? = nil + + /// + /// TODO: REPLACE + var mqttConfig: ModuleConfig.MQTTConfig { + get { + if case .mqttConfig(let v)? = payloadVariant {return v} + return ModuleConfig.MQTTConfig() + } + set {payloadVariant = .mqttConfig(newValue)} + } + + /// + /// TODO: REPLACE + var serialConfig: ModuleConfig.SerialConfig { + get { + if case .serialConfig(let v)? = payloadVariant {return v} + return ModuleConfig.SerialConfig() + } + set {payloadVariant = .serialConfig(newValue)} + } + + /// + /// TODO: REPLACE + var externalNotificationConfig: ModuleConfig.ExternalNotificationConfig { + get { + if case .externalNotificationConfig(let v)? = payloadVariant {return v} + return ModuleConfig.ExternalNotificationConfig() + } + set {payloadVariant = .externalNotificationConfig(newValue)} + } + + /// + /// TODO: REPLACE + var storeForwardConfig: ModuleConfig.StoreForwardConfig { + get { + if case .storeForwardConfig(let v)? = payloadVariant {return v} + return ModuleConfig.StoreForwardConfig() + } + set {payloadVariant = .storeForwardConfig(newValue)} + } + + /// + /// TODO: REPLACE + var rangeTestConfig: ModuleConfig.RangeTestConfig { + get { + if case .rangeTestConfig(let v)? = payloadVariant {return v} + return ModuleConfig.RangeTestConfig() + } + set {payloadVariant = .rangeTestConfig(newValue)} + } + + /// + /// TODO: REPLACE + var telemetryConfig: ModuleConfig.TelemetryConfig { + get { + if case .telemetryConfig(let v)? = payloadVariant {return v} + return ModuleConfig.TelemetryConfig() + } + set {payloadVariant = .telemetryConfig(newValue)} + } + + /// + /// TODO: REPLACE + var cannedMessageConfig: ModuleConfig.CannedMessageConfig { + get { + if case .cannedMessageConfig(let v)? = payloadVariant {return v} + return ModuleConfig.CannedMessageConfig() + } + set {payloadVariant = .cannedMessageConfig(newValue)} + } + + var unknownFields = SwiftProtobuf.UnknownStorage() + + /// + /// TODO: REPLACE + enum OneOf_PayloadVariant: Equatable { + /// + /// TODO: REPLACE + case mqttConfig(ModuleConfig.MQTTConfig) + /// + /// TODO: REPLACE + case serialConfig(ModuleConfig.SerialConfig) + /// + /// TODO: REPLACE + case externalNotificationConfig(ModuleConfig.ExternalNotificationConfig) + /// + /// TODO: REPLACE + case storeForwardConfig(ModuleConfig.StoreForwardConfig) + /// + /// TODO: REPLACE + case rangeTestConfig(ModuleConfig.RangeTestConfig) + /// + /// TODO: REPLACE + case telemetryConfig(ModuleConfig.TelemetryConfig) + /// + /// TODO: REPLACE + case cannedMessageConfig(ModuleConfig.CannedMessageConfig) + + #if !swift(>=4.1) + static func ==(lhs: ModuleConfig.OneOf_PayloadVariant, rhs: ModuleConfig.OneOf_PayloadVariant) -> Bool { + // 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 (lhs, rhs) { + case (.mqttConfig, .mqttConfig): return { + guard case .mqttConfig(let l) = lhs, case .mqttConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.serialConfig, .serialConfig): return { + guard case .serialConfig(let l) = lhs, case .serialConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.externalNotificationConfig, .externalNotificationConfig): return { + guard case .externalNotificationConfig(let l) = lhs, case .externalNotificationConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.storeForwardConfig, .storeForwardConfig): return { + guard case .storeForwardConfig(let l) = lhs, case .storeForwardConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.rangeTestConfig, .rangeTestConfig): return { + guard case .rangeTestConfig(let l) = lhs, case .rangeTestConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.telemetryConfig, .telemetryConfig): return { + guard case .telemetryConfig(let l) = lhs, case .telemetryConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.cannedMessageConfig, .cannedMessageConfig): return { + guard case .cannedMessageConfig(let l) = lhs, case .cannedMessageConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif + } + + /// + /// TODO: REPLACE + struct MQTTConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct SerialConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct ExternalNotificationConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct StoreForwardConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct RangeTestConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// Configuration for both device and environment metrics + struct TelemetryConfig { + // 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. + + /// + /// Interval in seconds of how often we should try to send our + /// device measurements to the mesh + var deviceUpdateInterval: UInt32 = 0 + + var environmentUpdateInterval: UInt32 = 0 + + /// + /// Preferences for the Telemetry Module (Environment) + /// Enable/Disable the telemetry measurement module measurement collection + var environmentMeasurementEnabled: Bool = false + + /// + /// Enable/Disable the telemetry measurement module on-device display + var environmentScreenEnabled: Bool = false + + /// + /// Sometimes sensor reads can fail. + /// If this happens, we will retry a configurable number of attempts, + /// each attempt will be delayed by the minimum required refresh rate for that sensor + var environmentReadErrorCountThreshold: UInt32 = 0 + + /// + /// Sometimes we can end up with more than read_error_count_threshold failures. + /// In this case, we will stop trying to read from the sensor for a while. + /// Wait this long until trying to read from the sensor again + var environmentRecoveryInterval: UInt32 = 0 + + /// + /// We'll always read the sensor in Celsius, but sometimes we might want to + /// display the results in Fahrenheit as a "user preference". + var environmentDisplayFahrenheit: Bool = false + + /// + /// Specify the sensor type + var environmentSensorType: TelemetrySensorType = .notSet + + /// + /// Specify the peferred GPIO Pin for sensor readings + var environmentSensorPin: UInt32 = 0 + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + /// + /// TODO: REPLACE + struct CannedMessageConfig { + // 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 unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + init() {} +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension ModuleConfig: @unchecked Sendable {} +extension ModuleConfig.OneOf_PayloadVariant: @unchecked Sendable {} +extension ModuleConfig.MQTTConfig: @unchecked Sendable {} +extension ModuleConfig.SerialConfig: @unchecked Sendable {} +extension ModuleConfig.ExternalNotificationConfig: @unchecked Sendable {} +extension ModuleConfig.StoreForwardConfig: @unchecked Sendable {} +extension ModuleConfig.RangeTestConfig: @unchecked Sendable {} +extension ModuleConfig.TelemetryConfig: @unchecked Sendable {} +extension ModuleConfig.CannedMessageConfig: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = "ModuleConfig" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "mqtt_config"), + 2: .standard(proto: "serial_config"), + 3: .standard(proto: "external_notification_config"), + 4: .standard(proto: "store_forward_config"), + 5: .standard(proto: "range_test_config"), + 6: .standard(proto: "telemetry_config"), + 7: .standard(proto: "canned_message_config"), + ] + + 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 { + var v: ModuleConfig.MQTTConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .mqttConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .mqttConfig(v) + } + }() + case 2: try { + var v: ModuleConfig.SerialConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .serialConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .serialConfig(v) + } + }() + case 3: try { + var v: ModuleConfig.ExternalNotificationConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .externalNotificationConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .externalNotificationConfig(v) + } + }() + case 4: try { + var v: ModuleConfig.StoreForwardConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .storeForwardConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .storeForwardConfig(v) + } + }() + case 5: try { + var v: ModuleConfig.RangeTestConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .rangeTestConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .rangeTestConfig(v) + } + }() + case 6: try { + var v: ModuleConfig.TelemetryConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .telemetryConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .telemetryConfig(v) + } + }() + case 7: try { + var v: ModuleConfig.CannedMessageConfig? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .cannedMessageConfig(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .cannedMessageConfig(v) + } + }() + 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 + switch self.payloadVariant { + case .mqttConfig?: try { + guard case .mqttConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + }() + case .serialConfig?: try { + guard case .serialConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + }() + case .externalNotificationConfig?: try { + guard case .externalNotificationConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + }() + case .storeForwardConfig?: try { + guard case .storeForwardConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + }() + case .rangeTestConfig?: try { + guard case .rangeTestConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + }() + case .telemetryConfig?: try { + guard case .telemetryConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + }() + case .cannedMessageConfig?: try { + guard case .cannedMessageConfig(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + }() + case nil: break + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: ModuleConfig, rhs: ModuleConfig) -> Bool { + if lhs.payloadVariant != rhs.payloadVariant {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension ModuleConfig.MQTTConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = ModuleConfig.protoMessageName + ".MQTTConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: ModuleConfig.MQTTConfig, rhs: ModuleConfig.MQTTConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension ModuleConfig.SerialConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = ModuleConfig.protoMessageName + ".SerialConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: ModuleConfig.SerialConfig, rhs: ModuleConfig.SerialConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension ModuleConfig.ExternalNotificationConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = ModuleConfig.protoMessageName + ".ExternalNotificationConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: ModuleConfig.ExternalNotificationConfig, rhs: ModuleConfig.ExternalNotificationConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension ModuleConfig.StoreForwardConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = ModuleConfig.protoMessageName + ".StoreForwardConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: ModuleConfig.StoreForwardConfig, rhs: ModuleConfig.StoreForwardConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension ModuleConfig.RangeTestConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = ModuleConfig.protoMessageName + ".RangeTestConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: ModuleConfig.RangeTestConfig, rhs: ModuleConfig.RangeTestConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension ModuleConfig.TelemetryConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = ModuleConfig.protoMessageName + ".TelemetryConfig" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "device_update_interval"), + 2: .standard(proto: "environment_update_interval"), + 3: .standard(proto: "environment_measurement_enabled"), + 4: .standard(proto: "environment_screen_enabled"), + 5: .standard(proto: "environment_read_error_count_threshold"), + 6: .standard(proto: "environment_recovery_interval"), + 7: .standard(proto: "environment_display_fahrenheit"), + 8: .standard(proto: "environment_sensor_type"), + 9: .standard(proto: "environment_sensor_pin"), + ] + + 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.deviceUpdateInterval) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.environmentUpdateInterval) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.environmentMeasurementEnabled) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self.environmentScreenEnabled) }() + case 5: try { try decoder.decodeSingularUInt32Field(value: &self.environmentReadErrorCountThreshold) }() + case 6: try { try decoder.decodeSingularUInt32Field(value: &self.environmentRecoveryInterval) }() + case 7: try { try decoder.decodeSingularBoolField(value: &self.environmentDisplayFahrenheit) }() + case 8: try { try decoder.decodeSingularEnumField(value: &self.environmentSensorType) }() + case 9: try { try decoder.decodeSingularUInt32Field(value: &self.environmentSensorPin) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.deviceUpdateInterval != 0 { + try visitor.visitSingularUInt32Field(value: self.deviceUpdateInterval, fieldNumber: 1) + } + if self.environmentUpdateInterval != 0 { + try visitor.visitSingularUInt32Field(value: self.environmentUpdateInterval, fieldNumber: 2) + } + if self.environmentMeasurementEnabled != false { + try visitor.visitSingularBoolField(value: self.environmentMeasurementEnabled, fieldNumber: 3) + } + if self.environmentScreenEnabled != false { + try visitor.visitSingularBoolField(value: self.environmentScreenEnabled, fieldNumber: 4) + } + if self.environmentReadErrorCountThreshold != 0 { + try visitor.visitSingularUInt32Field(value: self.environmentReadErrorCountThreshold, fieldNumber: 5) + } + if self.environmentRecoveryInterval != 0 { + try visitor.visitSingularUInt32Field(value: self.environmentRecoveryInterval, fieldNumber: 6) + } + if self.environmentDisplayFahrenheit != false { + try visitor.visitSingularBoolField(value: self.environmentDisplayFahrenheit, fieldNumber: 7) + } + if self.environmentSensorType != .notSet { + try visitor.visitSingularEnumField(value: self.environmentSensorType, fieldNumber: 8) + } + if self.environmentSensorPin != 0 { + try visitor.visitSingularUInt32Field(value: self.environmentSensorPin, fieldNumber: 9) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: ModuleConfig.TelemetryConfig, rhs: ModuleConfig.TelemetryConfig) -> Bool { + if lhs.deviceUpdateInterval != rhs.deviceUpdateInterval {return false} + if lhs.environmentUpdateInterval != rhs.environmentUpdateInterval {return false} + if lhs.environmentMeasurementEnabled != rhs.environmentMeasurementEnabled {return false} + if lhs.environmentScreenEnabled != rhs.environmentScreenEnabled {return false} + if lhs.environmentReadErrorCountThreshold != rhs.environmentReadErrorCountThreshold {return false} + if lhs.environmentRecoveryInterval != rhs.environmentRecoveryInterval {return false} + if lhs.environmentDisplayFahrenheit != rhs.environmentDisplayFahrenheit {return false} + if lhs.environmentSensorType != rhs.environmentSensorType {return false} + if lhs.environmentSensorPin != rhs.environmentSensorPin {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension ModuleConfig.CannedMessageConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = ModuleConfig.protoMessageName + ".CannedMessageConfig" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: ModuleConfig.CannedMessageConfig, rhs: ModuleConfig.CannedMessageConfig) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} From aa77009ee68cd22e7172437c19245d6b914d7555 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 7 May 2022 17:59:06 -0700 Subject: [PATCH 16/21] Remove wallet capability, requires a server to make passes --- Meshtastic Client.xcodeproj/project.pbxproj | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index bba66583..8afefa09 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -56,6 +56,7 @@ DDC2E18F26CE25FE0042C5E4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */; }; DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */; }; DDC4D568275499A500A4208E /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC4D567275499A500A4208E /* Persistence.swift */; }; + DDCA31322826009C00207175 /* PassKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDCA31312826009C00207175 /* PassKit.framework */; }; DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF924C926FBB953009FE055 /* ConnectedDevice.swift */; }; /* End PBXBuildFile section */ @@ -133,6 +134,7 @@ DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationHelper.swift; sourceTree = ""; }; DDC4D567275499A500A4208E /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; + DDCA31312826009C00207175 /* PassKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PassKit.framework; path = System/Library/Frameworks/PassKit.framework; sourceTree = SDKROOT; }; DDF924C926FBB953009FE055 /* ConnectedDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectedDevice.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -141,6 +143,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DDCA31322826009C00207175 /* PassKit.framework in Frameworks */, C9697FA527933B8C00250207 /* SQLite in Frameworks */, DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */, ); @@ -214,6 +217,7 @@ DD8EDE9226F97A2B00A5A10B /* Frameworks */ = { isa = PBXGroup; children = ( + DDCA31312826009C00207175 /* PassKit.framework */, ); name = Frameworks; sourceTree = ""; @@ -743,7 +747,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; @@ -775,7 +779,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; From 590f1fd783e1f08cece1154408b82f68a08e0229 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 12 May 2022 19:31:58 -0700 Subject: [PATCH 17/21] Add From num case --- MeshtasticClient/Helpers/BLEManager.swift | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 712ef706..9a1969b2 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -626,7 +626,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph fetchedNode[0].user!.macaddr = decodedInfo.nodeInfo.user.macaddr fetchedNode[0].user!.hwModel = String(describing: decodedInfo.nodeInfo.user.hwModel).uppercased() } - + if decodedInfo.nodeInfo.hasDeviceMetrics { let newTelemetry = TelemetryEntity(context: context!) @@ -1049,8 +1049,17 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph peripherals.removeAll(where: { $0.peripheral.state == CBPeripheralState.disconnected }) } + case FROMNUM_UUID : + print("🚨 FROMNUM Characteristic UUID: \(characteristic.uuid)") + if characteristic.value == nil || characteristic.value!.isEmpty { + return + } + + var decodedInfo = FromRadio() + + decodedInfo = try! FromRadio(serializedData: characteristic.value!) + default: - // Likely FROMNUM_UUID print("🚨 Unhandled Characteristic UUID: \(characteristic.uuid)") } peripheral.readValue(for: FROMRADIO_characteristic) From 7e163c863cc0dcc6c3ef2df07bffc376a622912d Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 24 May 2022 07:19:40 -0700 Subject: [PATCH 18/21] Update Protobufs Add GPS Timestamp to LocationHelper Use GPS Timestamp for position updates --- .../xcshareddata/swiftpm/Package.resolved | 4 +- MeshtasticClient/Helpers/BLEManager.swift | 6 +- MeshtasticClient/Helpers/LocationHelper.swift | 10 + MeshtasticClient/Protobufs/admin.pb.swift | 110 +- MeshtasticClient/Protobufs/channel.pb.swift | 161 +- MeshtasticClient/Protobufs/config.pb.swift | 2059 ++++++++++------- .../Protobufs/deviceonly.pb.swift | 197 +- MeshtasticClient/Protobufs/mesh.pb.swift | 698 +++--- MeshtasticClient/Protobufs/portnums.pb.swift | 9 +- 9 files changed, 1783 insertions(+), 1471 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 55b7b56c..6685f05b 100644 --- a/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Meshtastic Client.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/stephencelis/SQLite.swift.git", "state": { "branch": null, - "revision": "4d543d811ee644fa4cc4bfa0be996b4dd6ba0f54", - "version": "0.13.3" + "revision": "60a65015f6402b7c34b9a924f755ca0a73afeeaa", + "version": "0.13.1" } }, { diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 9a1969b2..1c401b24 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -1057,7 +1057,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph var decodedInfo = FromRadio() - decodedInfo = try! FromRadio(serializedData: characteristic.value!) + //decodedInfo = try! FromRadio(serializedData: characteristic.value!) default: print("🚨 Unhandled Characteristic UUID: \(characteristic.uuid)") @@ -1216,7 +1216,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph var positionPacket = Position() positionPacket.latitudeI = Int32(LocationHelper.currentLocation.latitude * 1e7) positionPacket.longitudeI = Int32(LocationHelper.currentLocation.longitude * 1e7) - positionPacket.time = UInt32(Date().timeIntervalSince1970) + positionPacket.time = UInt32(LocationHelper.currentTimestamp.timeIntervalSince1970) positionPacket.altitude = Int32(LocationHelper.currentAltitude) var meshPacket = MeshPacket() @@ -1274,7 +1274,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph public func getSettings() -> Bool { var adminPacket = AdminMessage() - adminPacket.getRadioRequest = true + //adminPacket.getRadioRequest = true var meshPacket: MeshPacket = MeshPacket() meshPacket.to = UInt32(connectedPeripheral.num) diff --git a/MeshtasticClient/Helpers/LocationHelper.swift b/MeshtasticClient/Helpers/LocationHelper.swift index 3210680b..b4ec565d 100644 --- a/MeshtasticClient/Helpers/LocationHelper.swift +++ b/MeshtasticClient/Helpers/LocationHelper.swift @@ -24,6 +24,16 @@ class LocationHelper: NSObject, ObservableObject { } return altitude } + + static var currentTimestamp: Date { + + guard let timestamp = shared.locationManager.location?.timestamp else { + return Date.now + } + return timestamp + } + + private let locationManager = CLLocationManager() diff --git a/MeshtasticClient/Protobufs/admin.pb.swift b/MeshtasticClient/Protobufs/admin.pb.swift index e6d15c24..0e69a453 100644 --- a/MeshtasticClient/Protobufs/admin.pb.swift +++ b/MeshtasticClient/Protobufs/admin.pb.swift @@ -33,16 +33,6 @@ struct AdminMessage { /// TODO: REPLACE var variant: AdminMessage.OneOf_Variant? = nil - /// - /// Set the radio provisioning for this node - var setRadio: RadioConfig { - get { - if case .setRadio(let v)? = variant {return v} - return RadioConfig() - } - set {variant = .setRadio(newValue)} - } - /// /// Set the owner for this node var setOwner: User { @@ -67,26 +57,6 @@ struct AdminMessage { set {variant = .setChannel(newValue)} } - /// - /// Send the current RadioConfig in the response to this message. - var getRadioRequest: Bool { - get { - if case .getRadioRequest(let v)? = variant {return v} - return false - } - set {variant = .getRadioRequest(newValue)} - } - - /// - /// TODO: REPLACE - var getRadioResponse: RadioConfig { - get { - if case .getRadioResponse(let v)? = variant {return v} - return RadioConfig() - } - set {variant = .getRadioResponse(newValue)} - } - /// /// 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) @@ -387,9 +357,6 @@ struct AdminMessage { /// /// TODO: REPLACE enum OneOf_Variant: Equatable { - /// - /// Set the radio provisioning for this node - case setRadio(RadioConfig) /// /// Set the owner for this node case setOwner(User) @@ -401,12 +368,6 @@ 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 to this message. - case getRadioRequest(Bool) - /// - /// TODO: REPLACE - case getRadioResponse(RadioConfig) - /// /// 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) @@ -505,10 +466,6 @@ struct AdminMessage { // allocates stack space for every case branch when no optimizations are // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch (lhs, rhs) { - case (.setRadio, .setRadio): return { - guard case .setRadio(let l) = lhs, case .setRadio(let r) = rhs else { preconditionFailure() } - return l == r - }() case (.setOwner, .setOwner): return { guard case .setOwner(let l) = lhs, case .setOwner(let r) = rhs else { preconditionFailure() } return l == r @@ -517,14 +474,6 @@ struct AdminMessage { guard case .setChannel(let l) = lhs, case .setChannel(let r) = rhs else { preconditionFailure() } return l == r }() - case (.getRadioRequest, .getRadioRequest): return { - guard case .getRadioRequest(let l) = lhs, case .getRadioRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getRadioResponse, .getRadioResponse): return { - guard case .getRadioResponse(let l) = lhs, case .getRadioResponse(let r) = rhs else { preconditionFailure() } - return l == r - }() case (.getChannelRequest, .getChannelRequest): return { guard case .getChannelRequest(let l) = lhs, case .getChannelRequest(let r) = rhs else { preconditionFailure() } return l == r @@ -658,7 +607,7 @@ struct AdminMessage { /// /// TODO: REPLACE - case gpsConfig // = 1 + case positionConfig // = 1 /// /// TODO: REPLACE @@ -684,7 +633,7 @@ struct AdminMessage { init?(rawValue: Int) { switch rawValue { case 0: self = .deviceConfig - case 1: self = .gpsConfig + case 1: self = .positionConfig case 2: self = .powerConfig case 3: self = .wifiConfig case 4: self = .displayConfig @@ -696,7 +645,7 @@ struct AdminMessage { var rawValue: Int { switch self { case .deviceConfig: return 0 - case .gpsConfig: return 1 + case .positionConfig: return 1 case .powerConfig: return 2 case .wifiConfig: return 3 case .displayConfig: return 4 @@ -782,7 +731,7 @@ extension AdminMessage.ConfigType: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. static var allCases: [AdminMessage.ConfigType] = [ .deviceConfig, - .gpsConfig, + .positionConfig, .powerConfig, .wifiConfig, .displayConfig, @@ -817,11 +766,8 @@ extension AdminMessage.ModuleConfigType: @unchecked Sendable {} extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "AdminMessage" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "set_radio"), 2: .standard(proto: "set_owner"), 3: .standard(proto: "set_channel"), - 4: .standard(proto: "get_radio_request"), - 5: .standard(proto: "get_radio_response"), 6: .standard(proto: "get_channel_request"), 7: .standard(proto: "get_channel_response"), 8: .standard(proto: "get_owner_request"), @@ -859,19 +805,6 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat // 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 { - var v: RadioConfig? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .setRadio(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .setRadio(v) - } - }() case 2: try { var v: User? var hadOneofValue = false @@ -898,27 +831,6 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat self.variant = .setChannel(v) } }() - case 4: try { - var v: Bool? - try decoder.decodeSingularBoolField(value: &v) - if let v = v { - if self.variant != nil {try decoder.handleConflictingOneOf()} - self.variant = .getRadioRequest(v) - } - }() - case 5: try { - var v: RadioConfig? - var hadOneofValue = false - if let current = self.variant { - hadOneofValue = true - if case .getRadioResponse(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.variant = .getRadioResponse(v) - } - }() case 6: try { var v: UInt32? try decoder.decodeSingularUInt32Field(value: &v) @@ -1192,10 +1104,6 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and // https://github.com/apple/swift-protobuf/issues/1182 switch self.variant { - case .setRadio?: try { - guard case .setRadio(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - }() case .setOwner?: try { guard case .setOwner(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 2) @@ -1204,14 +1112,6 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat guard case .setChannel(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 3) }() - case .getRadioRequest?: try { - guard case .getRadioRequest(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularBoolField(value: v, fieldNumber: 4) - }() - case .getRadioResponse?: try { - guard case .getRadioResponse(let v)? = self.variant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 5) - }() case .getChannelRequest?: try { guard case .getChannelRequest(let v)? = self.variant else { preconditionFailure() } try visitor.visitSingularUInt32Field(value: v, fieldNumber: 6) @@ -1343,7 +1243,7 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat extension AdminMessage.ConfigType: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 0: .same(proto: "DEVICE_CONFIG"), - 1: .same(proto: "GPS_CONFIG"), + 1: .same(proto: "POSITION_CONFIG"), 2: .same(proto: "POWER_CONFIG"), 3: .same(proto: "WIFI_CONFIG"), 4: .same(proto: "DISPLAY_CONFIG"), diff --git a/MeshtasticClient/Protobufs/channel.pb.swift b/MeshtasticClient/Protobufs/channel.pb.swift index bb901196..ec08f301 100644 --- a/MeshtasticClient/Protobufs/channel.pb.swift +++ b/MeshtasticClient/Protobufs/channel.pb.swift @@ -45,38 +45,6 @@ struct ChannelSettings { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. - /// - /// If zero then, use default max legal continuous power (ie. something that won't - /// burn out the radio hardware) - /// In most cases you should use zero here. - /// Units are in dBm. - var txPower: Int32 = 0 - - /// - /// Note: This is the 'old' mechanism for specifying channel parameters. - /// Either modem_config or bandwidth/spreading/coding will be specified - NOT BOTH. - /// As a heuristic: If bandwidth is specified, do not use modem_config. - /// Because protobufs take ZERO space when the value is zero this works out nicely. - /// This value is replaced by bandwidth/spread_factor/coding_rate. - /// If you'd like to experiment with other options add them to MeshRadio.cpp in the device code. - var modemConfig: ChannelSettings.ModemConfig = .vlongSlow - - /// - /// Bandwidth in MHz - /// Certain bandwidth numbers are 'special' and will be converted to the - /// appropriate floating point value: 31 -> 31.25MHz - var bandwidth: UInt32 = 0 - - /// - /// A number from 7 to 12. - /// Indicates number of chirps per symbol as 1<=4.2) - -extension ChannelSettings.ModemConfig: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - static var allCases: [ChannelSettings.ModemConfig] = [ - .vlongSlow, - .longSlow, - .longFast, - .midSlow, - .midFast, - .shortSlow, - .shortFast, - ] -} - -#endif // swift(>=4.2) - /// /// A pair of a channel number, mode and the (sharable) settings for that channel struct Channel { @@ -334,7 +218,6 @@ extension Channel.Role: CaseIterable { #if swift(>=5.5) && canImport(_Concurrency) extension ChannelSettings: @unchecked Sendable {} -extension ChannelSettings.ModemConfig: @unchecked Sendable {} extension Channel: @unchecked Sendable {} extension Channel.Role: @unchecked Sendable {} #endif // swift(>=5.5) && canImport(_Concurrency) @@ -344,11 +227,6 @@ extension Channel.Role: @unchecked Sendable {} extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "ChannelSettings" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "tx_power"), - 3: .standard(proto: "modem_config"), - 6: .same(proto: "bandwidth"), - 7: .standard(proto: "spread_factor"), - 8: .standard(proto: "coding_rate"), 9: .standard(proto: "channel_num"), 4: .same(proto: "psk"), 5: .same(proto: "name"), @@ -363,13 +241,8 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen // 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.decodeSingularInt32Field(value: &self.txPower) }() - case 3: try { try decoder.decodeSingularEnumField(value: &self.modemConfig) }() case 4: try { try decoder.decodeSingularBytesField(value: &self.psk) }() case 5: try { try decoder.decodeSingularStringField(value: &self.name) }() - case 6: try { try decoder.decodeSingularUInt32Field(value: &self.bandwidth) }() - case 7: try { try decoder.decodeSingularUInt32Field(value: &self.spreadFactor) }() - case 8: try { try decoder.decodeSingularUInt32Field(value: &self.codingRate) }() case 9: try { try decoder.decodeSingularUInt32Field(value: &self.channelNum) }() case 10: try { try decoder.decodeSingularFixed32Field(value: &self.id) }() case 16: try { try decoder.decodeSingularBoolField(value: &self.uplinkEnabled) }() @@ -380,27 +253,12 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen } func traverse(visitor: inout V) throws { - if self.txPower != 0 { - try visitor.visitSingularInt32Field(value: self.txPower, fieldNumber: 1) - } - if self.modemConfig != .vlongSlow { - try visitor.visitSingularEnumField(value: self.modemConfig, fieldNumber: 3) - } if !self.psk.isEmpty { try visitor.visitSingularBytesField(value: self.psk, fieldNumber: 4) } if !self.name.isEmpty { try visitor.visitSingularStringField(value: self.name, fieldNumber: 5) } - if self.bandwidth != 0 { - try visitor.visitSingularUInt32Field(value: self.bandwidth, fieldNumber: 6) - } - if self.spreadFactor != 0 { - try visitor.visitSingularUInt32Field(value: self.spreadFactor, fieldNumber: 7) - } - if self.codingRate != 0 { - try visitor.visitSingularUInt32Field(value: self.codingRate, fieldNumber: 8) - } if self.channelNum != 0 { try visitor.visitSingularUInt32Field(value: self.channelNum, fieldNumber: 9) } @@ -417,11 +275,6 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen } static func ==(lhs: ChannelSettings, rhs: ChannelSettings) -> Bool { - if lhs.txPower != rhs.txPower {return false} - if lhs.modemConfig != rhs.modemConfig {return false} - if lhs.bandwidth != rhs.bandwidth {return false} - if lhs.spreadFactor != rhs.spreadFactor {return false} - if lhs.codingRate != rhs.codingRate {return false} if lhs.channelNum != rhs.channelNum {return false} if lhs.psk != rhs.psk {return false} if lhs.name != rhs.name {return false} @@ -433,18 +286,6 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen } } -extension ChannelSettings.ModemConfig: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "VLongSlow"), - 1: .same(proto: "LongSlow"), - 2: .same(proto: "LongFast"), - 3: .same(proto: "MidSlow"), - 4: .same(proto: "MidFast"), - 5: .same(proto: "ShortSlow"), - 6: .same(proto: "ShortFast"), - ] -} - extension Channel: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "Channel" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ diff --git a/MeshtasticClient/Protobufs/config.pb.swift b/MeshtasticClient/Protobufs/config.pb.swift index 97689ce2..b2d08a49 100644 --- a/MeshtasticClient/Protobufs/config.pb.swift +++ b/MeshtasticClient/Protobufs/config.pb.swift @@ -31,72 +31,62 @@ struct Config { /// /// TODO: REPLACE - var deviceConfig: Config.DeviceConfig { + var device: Config.DeviceConfig { get { - if case .deviceConfig(let v)? = payloadVariant {return v} + if case .device(let v)? = payloadVariant {return v} return Config.DeviceConfig() } - set {payloadVariant = .deviceConfig(newValue)} + set {payloadVariant = .device(newValue)} } /// /// TODO: REPLACE - var gpsConfig: Config.GpsConfig { + var position: Config.PositionConfig { get { - if case .gpsConfig(let v)? = payloadVariant {return v} - return Config.GpsConfig() + if case .position(let v)? = payloadVariant {return v} + return Config.PositionConfig() } - set {payloadVariant = .gpsConfig(newValue)} + set {payloadVariant = .position(newValue)} } /// /// TODO: REPLACE - var powerConfig: Config.PowerConfig { + var power: Config.PowerConfig { get { - if case .powerConfig(let v)? = payloadVariant {return v} + if case .power(let v)? = payloadVariant {return v} return Config.PowerConfig() } - set {payloadVariant = .powerConfig(newValue)} + set {payloadVariant = .power(newValue)} } /// /// TODO: REPLACE - var wifiConfig: Config.WiFiConfig { + var wifi: Config.WiFiConfig { get { - if case .wifiConfig(let v)? = payloadVariant {return v} + if case .wifi(let v)? = payloadVariant {return v} return Config.WiFiConfig() } - set {payloadVariant = .wifiConfig(newValue)} + set {payloadVariant = .wifi(newValue)} } /// /// TODO: REPLACE - var displayConfig: Config.DisplayConfig { + var display: Config.DisplayConfig { get { - if case .displayConfig(let v)? = payloadVariant {return v} + if case .display(let v)? = payloadVariant {return v} return Config.DisplayConfig() } - set {payloadVariant = .displayConfig(newValue)} + set {payloadVariant = .display(newValue)} } /// /// TODO: REPLACE - var loraConfig: Config.LoRaConfig { + var lora: Config.LoRaConfig { get { - if case .loraConfig(let v)? = payloadVariant {return v} + if case .lora(let v)? = payloadVariant {return v} return Config.LoRaConfig() } - set {payloadVariant = .loraConfig(newValue)} - } - - /// - /// TODO: REPLACE - var moduleConfig: Config.ModuleConfig { - get { - if case .moduleConfig(let v)? = payloadVariant {return v} - return Config.ModuleConfig() - } - set {payloadVariant = .moduleConfig(newValue)} + set {payloadVariant = .lora(newValue)} } var unknownFields = SwiftProtobuf.UnknownStorage() @@ -106,25 +96,22 @@ struct Config { enum OneOf_PayloadVariant: Equatable { /// /// TODO: REPLACE - case deviceConfig(Config.DeviceConfig) + case device(Config.DeviceConfig) /// /// TODO: REPLACE - case gpsConfig(Config.GpsConfig) + case position(Config.PositionConfig) /// /// TODO: REPLACE - case powerConfig(Config.PowerConfig) + case power(Config.PowerConfig) /// /// TODO: REPLACE - case wifiConfig(Config.WiFiConfig) + case wifi(Config.WiFiConfig) /// /// TODO: REPLACE - case displayConfig(Config.DisplayConfig) + case display(Config.DisplayConfig) /// /// TODO: REPLACE - case loraConfig(Config.LoRaConfig) - /// - /// TODO: REPLACE - case moduleConfig(Config.ModuleConfig) + case lora(Config.LoRaConfig) #if !swift(>=4.1) static func ==(lhs: Config.OneOf_PayloadVariant, rhs: Config.OneOf_PayloadVariant) -> Bool { @@ -132,32 +119,28 @@ struct Config { // allocates stack space for every case branch when no optimizations are // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch (lhs, rhs) { - case (.deviceConfig, .deviceConfig): return { - guard case .deviceConfig(let l) = lhs, case .deviceConfig(let r) = rhs else { preconditionFailure() } + case (.device, .device): return { + guard case .device(let l) = lhs, case .device(let r) = rhs else { preconditionFailure() } return l == r }() - case (.gpsConfig, .gpsConfig): return { - guard case .gpsConfig(let l) = lhs, case .gpsConfig(let r) = rhs else { preconditionFailure() } + case (.position, .position): return { + guard case .position(let l) = lhs, case .position(let r) = rhs else { preconditionFailure() } return l == r }() - case (.powerConfig, .powerConfig): return { - guard case .powerConfig(let l) = lhs, case .powerConfig(let r) = rhs else { preconditionFailure() } + case (.power, .power): return { + guard case .power(let l) = lhs, case .power(let r) = rhs else { preconditionFailure() } return l == r }() - case (.wifiConfig, .wifiConfig): return { - guard case .wifiConfig(let l) = lhs, case .wifiConfig(let r) = rhs else { preconditionFailure() } + case (.wifi, .wifi): return { + guard case .wifi(let l) = lhs, case .wifi(let r) = rhs else { preconditionFailure() } return l == r }() - case (.displayConfig, .displayConfig): return { - guard case .displayConfig(let l) = lhs, case .displayConfig(let r) = rhs else { preconditionFailure() } + case (.display, .display): return { + guard case .display(let l) = lhs, case .display(let r) = rhs else { preconditionFailure() } return l == r }() - case (.loraConfig, .loraConfig): return { - guard case .loraConfig(let l) = lhs, case .loraConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.moduleConfig, .moduleConfig): return { - guard case .moduleConfig(let l) = lhs, case .moduleConfig(let r) = rhs else { preconditionFailure() } + case (.lora, .lora): return { + guard case .lora(let l) = lhs, case .lora(let r) = rhs else { preconditionFailure() } return l == r }() default: return false @@ -173,20 +156,240 @@ struct Config { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// Sets the role of node + var role: Config.DeviceConfig.Role = .client + + /// + /// If set, this will disable the SerialConsole by not initilizing the StreamAPI + var serialDisabled: Bool = false + + /// + /// This setting is never saved to disk, but if set, all device settings will be returned to factory defaults. + /// (Region, serial number etc... will be preserved) + var factoryReset: Bool = false + + /// + /// By default we turn off logging as soon as an API client connects (to keep shared serial link quiet). + /// Set this to true to leave the debug log outputting even when API is active. + var debugLogEnabled: Bool = false + + /// + /// NTP server to use if WiFi is conneced, defaults to `0.pool.ntp.org` + var ntpServer: String = String() + var unknownFields = SwiftProtobuf.UnknownStorage() + /// + /// Defines the device's role on the Mesh network + /// unset + /// Behave normally. + /// Router + /// Functions as a router + enum Role: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// Client device role + case client // = 0 + + /// + /// ClientMute device role + /// This is like the client but packets will not hop over this node. Would be + /// useful if you want to save power by not contributing to the mesh. + case clientMute // = 1 + + /// + /// Router device role. + /// Uses an agressive algirithem for the flood networking so packets will + /// prefer to be routed over this node. Also assume that this will be generally + /// unattended and so will turn off the wifi/ble radio as well as the oled screen. + case router // = 2 + + /// + /// RouterClient device role + /// Uses an agressive algirithem for the flood networking so packets will + /// prefer to be routed over this node. Similiar power management as a regular + /// client, so the RouterClient can be used as both a Router and a Client. Useful + /// as a well placed base station that you could also use to send messages. + case routerClient // = 3 + case UNRECOGNIZED(Int) + + init() { + self = .client + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .client + case 1: self = .clientMute + case 2: self = .router + case 3: self = .routerClient + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .client: return 0 + case .clientMute: return 1 + case .router: return 2 + case .routerClient: return 3 + case .UNRECOGNIZED(let i): return i + } + } + + } + init() {} } /// /// TODO: REPLACE - struct GpsConfig { + struct PositionConfig { // 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. + /// + /// We should send our position this often (but only if it has changed significantly) + /// Defaults to 15 minutes + var positionBroadcastSecs: UInt32 = 0 + + /// + /// We should send our position this often (but only if it has changed significantly) + var positionBroadcastSmartDisabled: Bool = false + + /// + /// If set, this node is at a fixed position. + /// We will generate GPS position updates at the regular interval, but use whatever the last lat/lon/alt we have for the node. + /// The lat/lon/alt can be set by an internal GPS or with the help of the app. + var fixedPosition: Bool = false + + /// + /// Should we disbale location sharing with other nodes (or the local phone) + var locationShareDisabled: Bool = false + + /// + /// Should the GPS be disabled for this node? + var gpsDisabled: Bool = false + + /// + /// How often should we try to get GPS position (in seconds) + /// or zero for the default of once every 30 seconds + /// or a very large value (maxint) to update only once at boot. + var gpsUpdateInterval: UInt32 = 0 + + /// + /// 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. + var gpsAttemptTime: UInt32 = 0 + + /// + /// Shall we accept 2D GPS fixes? By default, only 3D fixes are accepted + /// (during a 2D fix, altitude values are unreliable and will be excluded) + var gpsAccept2D: Bool = false + + /// + /// GPS maximum DOP accepted (dilution of precision) + /// Set a rejection threshold for GPS readings based on their precision, + /// relative to the GPS rated accuracy (which is typically ~3m) + /// Solutions above this value will be treated as retryable errors! + /// Useful range is between 1 - 64 (3m - <~200m) + /// By default (if zero), accept all GPS readings + var gpsMaxDop: UInt32 = 0 + + /// + /// Bit field of boolean configuration options for POSITION messages + /// (bitwise OR of PositionFlags) + var positionFlags: UInt32 = 0 + var unknownFields = SwiftProtobuf.UnknownStorage() + /// + /// 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) + /// NOTE: the more fields are included, the larger the message will be - + /// leading to longer airtime and a higher risk of packet loss + enum PositionFlags: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// Required for compilation + case posUndefined // = 0 + + /// + /// Include an altitude value (if available) + case posAltitude // = 1 + + /// + /// Altitude value is MSL + case posAltMsl // = 2 + + /// + /// Include geoidal separation + case posGeoSep // = 4 + + /// + /// Include the DOP value ; PDOP used by default, see below + case posDop // = 8 + + /// + /// If POS_DOP set, send separate HDOP / VDOP values instead of PDOP + case posHvdop // = 16 + + /// + /// Include number of "satellites in view" + case posSatinview // = 32 + + /// + /// Include a sequence number incremented per packet + case posSeqNos // = 64 + + /// + /// Include positional timestamp (from GPS solution) + case posTimestamp // = 128 + case UNRECOGNIZED(Int) + + init() { + self = .posUndefined + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .posUndefined + case 1: self = .posAltitude + case 2: self = .posAltMsl + case 4: self = .posGeoSep + case 8: self = .posDop + case 16: self = .posHvdop + case 32: self = .posSatinview + case 64: self = .posSeqNos + case 128: self = .posTimestamp + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .posUndefined: return 0 + case .posAltitude: return 1 + case .posAltMsl: return 2 + case .posGeoSep: return 4 + case .posDop: return 8 + case .posHvdop: return 16 + case .posSatinview: return 32 + case .posSeqNos: return 64 + case .posTimestamp: return 128 + case .UNRECOGNIZED(let i): return i + } + } + + } + init() {} } @@ -197,8 +400,200 @@ struct Config { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// Sets the current of the battery charger + var chargeCurrent: Config.PowerConfig.ChargeCurrent = .maunset + + /// + /// If set, we are powered from a low-current source (i.e. solar), so even if it looks like we have power flowing in + /// we should try to minimize power consumption as much as possible. + /// YOU DO NOT NEED TO SET THIS IF YOU'VE set is_router (it is implied in that case). + var isLowPower: Bool = false + + /// + /// 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 = false + + /// + /// If non-zero, the device will fully power off this many seconds after external power is removed. + var onBatteryShutdownAfterSecs: UInt32 = 0 + + /// + /// If set to true, enable power saving features of the esp32 + var isPowerSaving: Bool = false + + /// + /// Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k) + /// Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation. + var adcMultiplierOverride: Float = 0 + + /// + /// Power management state machine option. + /// See [power management](/docs/software/other/power) for details. + /// 0 for default of 1 minute + var waitBluetoothSecs: UInt32 = 0 + + /// + /// Power management state machine option. + /// See [power management](/docs/software/other/power) for details. + /// 0 for default of 15 minutes + /// IMPORTANT NOTE FOR DEVICE CLIENTS: YOU MUST SEND SOME SORT OF PACKET TO THE PHONE AT LEAST THIS OFTEN OR THE DEVICE WILL DECIDE YOU ARE GONE! + var phoneTimeoutSecs: UInt32 = 0 + + /// + /// Power management state machine option. + /// See [power management](/docs/software/other/power) for details. + /// 0 for default of two hours, MAXUINT for disabled + var meshSdsTimeoutSecs: UInt32 = 0 + + /// + /// Power management state machine option. + /// See [power management](/docs/software/other/power) for details. + /// 0 for default of one year + var sdsSecs: UInt32 = 0 + + /// + /// Power management state machine option. + /// See [power management](/docs/software/other/power) for details. + /// 0 for default of 3600 + var lsSecs: UInt32 = 0 + + /// + /// Power management state machine option. + /// See [power management](/docs/software/other/power) for details. + /// 0 for default of 10 seconds + var minWakeSecs: UInt32 = 0 + var unknownFields = SwiftProtobuf.UnknownStorage() + /// + /// Sets the charge control current of devices with a battery charger that can be + /// configured. This is passed into the axp power management chip like on the tbeam. + enum ChargeCurrent: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// TODO: REPLACE + case maunset // = 0 + + /// + /// TODO: REPLACE + case ma100 // = 1 + + /// + /// TODO: REPLACE + case ma190 // = 2 + + /// + /// TODO: REPLACE + case ma280 // = 3 + + /// + /// TODO: REPLACE + case ma360 // = 4 + + /// + /// TODO: REPLACE + case ma450 // = 5 + + /// + /// TODO: REPLACE + case ma550 // = 6 + + /// + /// TODO: REPLACE + case ma630 // = 7 + + /// + /// TODO: REPLACE + case ma700 // = 8 + + /// + /// TODO: REPLACE + case ma780 // = 9 + + /// + /// TODO: REPLACE + case ma880 // = 10 + + /// + /// TODO: REPLACE + case ma960 // = 11 + + /// + /// TODO: REPLACE + case ma1000 // = 12 + + /// + /// TODO: REPLACE + case ma1080 // = 13 + + /// + /// TODO: REPLACE + case ma1160 // = 14 + + /// + /// TODO: REPLACE + case ma1240 // = 15 + + /// + /// TODO: REPLACE + case ma1320 // = 16 + case UNRECOGNIZED(Int) + + init() { + self = .maunset + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .maunset + case 1: self = .ma100 + case 2: self = .ma190 + case 3: self = .ma280 + case 4: self = .ma360 + case 5: self = .ma450 + case 6: self = .ma550 + case 7: self = .ma630 + case 8: self = .ma700 + case 9: self = .ma780 + case 10: self = .ma880 + case 11: self = .ma960 + case 12: self = .ma1000 + case 13: self = .ma1080 + case 14: self = .ma1160 + case 15: self = .ma1240 + case 16: self = .ma1320 + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .maunset: return 0 + case .ma100: return 1 + case .ma190: return 2 + case .ma280: return 3 + case .ma360: return 4 + case .ma450: return 5 + case .ma550: return 6 + case .ma630: return 7 + case .ma700: return 8 + case .ma780: return 9 + case .ma880: return 10 + case .ma960: return 11 + case .ma1000: return 12 + case .ma1080: return 13 + case .ma1160: return 14 + case .ma1240: return 15 + case .ma1320: return 16 + case .UNRECOGNIZED(let i): return i + } + } + + } + init() {} } @@ -212,16 +607,16 @@ struct Config { /// /// If set, this node will try to join the specified wifi network and /// acquire an address via DHCP - var wifiSsid: String = String() + var ssid: String = String() /// /// If set, will be use to authenticate to the named wifi - var wifiPassword: String = String() + var psk: String = String() /// /// If set, the node will operate as an AP (and DHCP server), otherwise it /// will be a station - var wifiApMode: Bool = false + var apMode: Bool = false var unknownFields = SwiftProtobuf.UnknownStorage() @@ -235,8 +630,90 @@ struct Config { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// Power management state machine option. + /// See [power management](/docs/software/other/power) for details. + /// 0 for default of one minute + var screenOnSecs: UInt32 = 0 + + /// + /// How the GPS coordinates are displayed on the OLED screen. + var gpsFormat: Config.DisplayConfig.GpsCoordinateFormat = .gpsFormatDec + + /// + /// 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 = 0 + var unknownFields = SwiftProtobuf.UnknownStorage() + /// + /// How the GPS coordinates are displayed on the OLED screen. + enum GpsCoordinateFormat: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// 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: + /// 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: + /// 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, + /// E is easting, N is northing + case gpsFormatMgrs // = 3 + + /// + /// GPS coordinates are displayed in Open Location Code (aka Plus Codes). + case gpsFormatOlc // = 4 + + /// + /// GPS coordinates are displayed in Ordnance Survey Grid Reference (the National Grid System of the UK). + /// Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square, E is the easting, + /// N is the northing + case gpsFormatOsgr // = 5 + case UNRECOGNIZED(Int) + + init() { + self = .gpsFormatDec + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .gpsFormatDec + case 1: self = .gpsFormatDms + case 2: self = .gpsFormatUtm + case 3: self = .gpsFormatMgrs + case 4: self = .gpsFormatOlc + case 5: self = .gpsFormatOsgr + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .gpsFormatDec: return 0 + case .gpsFormatDms: return 1 + case .gpsFormatUtm: return 2 + case .gpsFormatMgrs: return 3 + case .gpsFormatOlc: return 4 + case .gpsFormatOsgr: return 5 + case .UNRECOGNIZED(let i): return i + } + } + + } + init() {} } @@ -247,285 +724,237 @@ struct Config { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - } - - /// - /// TODO: REPLACE - struct ModuleConfig { - // 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. + /// + /// If zero then, use default max legal continuous power (ie. something that won't + /// burn out the radio hardware) + /// In most cases you should use zero here. + /// Units are in dBm. + var txPower: Int32 = 0 /// - /// TODO: REPLACE - var payloadVariant: Config.ModuleConfig.OneOf_PayloadVariant? = nil + /// Note: This is the 'old' mechanism for specifying channel parameters. + /// Either modem_config or bandwidth/spreading/coding will be specified - NOT BOTH. + /// As a heuristic: If bandwidth is specified, do not use modem_config. + /// Because protobufs take ZERO space when the value is zero this works out nicely. + /// This value is replaced by bandwidth/spread_factor/coding_rate. + /// If you'd like to experiment with other options add them to MeshRadio.cpp in the device code. + var modemPreset: Config.LoRaConfig.ModemPreset = .vlongSlow /// - /// TODO: REPLACE - var mqttConfig: Config.ModuleConfig.MQTTConfig { - get { - if case .mqttConfig(let v)? = payloadVariant {return v} - return Config.ModuleConfig.MQTTConfig() - } - set {payloadVariant = .mqttConfig(newValue)} - } + /// Bandwidth in MHz + /// Certain bandwidth numbers are 'special' and will be converted to the + /// appropriate floating point value: 31 -> 31.25MHz + var bandwidth: UInt32 = 0 /// - /// TODO: REPLACE - var serialConfig: Config.ModuleConfig.SerialConfig { - get { - if case .serialConfig(let v)? = payloadVariant {return v} - return Config.ModuleConfig.SerialConfig() - } - set {payloadVariant = .serialConfig(newValue)} - } + /// A number from 7 to 12. + /// Indicates number of chirps per symbol as 1<=4.1) - static func ==(lhs: Config.ModuleConfig.OneOf_PayloadVariant, rhs: Config.ModuleConfig.OneOf_PayloadVariant) -> Bool { - // 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 (lhs, rhs) { - case (.mqttConfig, .mqttConfig): return { - guard case .mqttConfig(let l) = lhs, case .mqttConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.serialConfig, .serialConfig): return { - guard case .serialConfig(let l) = lhs, case .serialConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.externalNotificationConfig, .externalNotificationConfig): return { - guard case .externalNotificationConfig(let l) = lhs, case .externalNotificationConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.storeForwardConfig, .storeForwardConfig): return { - guard case .storeForwardConfig(let l) = lhs, case .storeForwardConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.rangeTestConfig, .rangeTestConfig): return { - guard case .rangeTestConfig(let l) = lhs, case .rangeTestConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.telemetryConfig, .telemetryConfig): return { - guard case .telemetryConfig(let l) = lhs, case .telemetryConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.cannedMessageConfig, .cannedMessageConfig): return { - guard case .cannedMessageConfig(let l) = lhs, case .cannedMessageConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false + /// + /// TODO: REPLACE + case unset // = 0 + + /// + /// TODO: REPLACE + case us // = 1 + + /// + /// TODO: REPLACE + case eu433 // = 2 + + /// + /// TODO: REPLACE + case eu868 // = 3 + + /// + /// TODO: REPLACE + case cn // = 4 + + /// + /// TODO: REPLACE + case jp // = 5 + + /// + /// TODO: REPLACE + case anz // = 6 + + /// + /// TODO: REPLACE + case kr // = 7 + + /// + /// TODO: REPLACE + case tw // = 8 + + /// + /// TODO: REPLACE + case ru // = 9 + + /// + /// TODO: REPLACE + case `in` // = 10 + + /// + /// TODO: REPLACE + case nz865 // = 11 + + /// + /// TODO: REPLACE + case th // = 12 + case UNRECOGNIZED(Int) + + init() { + self = .unset + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unset + case 1: self = .us + case 2: self = .eu433 + case 3: self = .eu868 + case 4: self = .cn + case 5: self = .jp + case 6: self = .anz + case 7: self = .kr + case 8: self = .tw + case 9: self = .ru + case 10: self = .in + case 11: self = .nz865 + case 12: self = .th + default: self = .UNRECOGNIZED(rawValue) } } - #endif + + var rawValue: Int { + switch self { + case .unset: return 0 + case .us: return 1 + case .eu433: return 2 + case .eu868: return 3 + case .cn: return 4 + case .jp: return 5 + case .anz: return 6 + case .kr: return 7 + case .tw: return 8 + case .ru: return 9 + case .in: return 10 + case .nz865: return 11 + case .th: return 12 + case .UNRECOGNIZED(let i): return i + } + } + } /// - /// TODO: REPLACE - struct MQTTConfig { - // 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 unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - } - - /// - /// TODO: REPLACE - struct SerialConfig { - // 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 unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - } - - /// - /// TODO: REPLACE - struct ExternalNotificationConfig { - // 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 unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - } - - /// - /// TODO: REPLACE - struct StoreForwardConfig { - // 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 unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - } - - /// - /// TODO: REPLACE - struct RangeTestConfig { - // 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 unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - } - - /// - /// Configuration for both device and environment metrics - struct TelemetryConfig { - // 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. + /// Standard predefined channel settings + /// Note: these mappings must match ModemPreset Choice in the device code. + enum ModemPreset: SwiftProtobuf.Enum { + typealias RawValue = Int /// - /// Interval in seconds of how often we should try to send our - /// device measurements to the mesh - var deviceUpdateInterval: UInt32 = 0 + /// TODO: REPLACE + case vlongSlow // = 0 /// - /// Interval in seconds of how often we should try to send our - /// environment measurements to the mesh - var environmentUpdateInterval: UInt32 = 0 + /// TODO: REPLACE + case longSlow // = 1 /// - /// Preferences for the Telemetry Module (Environment) - /// Enable/Disable the telemetry measurement module measurement collection - var environmentMeasurementEnabled: Bool = false + /// TODO: REPLACE + case longFast // = 2 /// - /// Enable/Disable the telemetry measurement module on-device display - var environmentScreenEnabled: Bool = false + /// TODO: REPLACE + case midSlow // = 3 /// - /// Sometimes sensor reads can fail. - /// If this happens, we will retry a configurable number of attempts, - /// each attempt will be delayed by the minimum required refresh rate for that sensor - var environmentReadErrorCountThreshold: UInt32 = 0 + /// TODO: REPLACE + case midFast // = 4 /// - /// Sometimes we can end up with more than read_error_count_threshold failures. - /// In this case, we will stop trying to read from the sensor for a while. - /// Wait this long until trying to read from the sensor again - var environmentRecoveryInterval: UInt32 = 0 + /// TODO: REPLACE + case shortSlow // = 5 /// - /// We'll always read the sensor in Celsius, but sometimes we might want to - /// display the results in Fahrenheit as a "user preference". - var environmentDisplayFahrenheit: Bool = false + /// TODO: REPLACE + case shortFast // = 6 + case UNRECOGNIZED(Int) - /// - /// Specify the sensor type - var environmentSensorType: TelemetrySensorType = .notSet + init() { + self = .vlongSlow + } - /// - /// Specify the peferred GPIO Pin for sensor readings - var environmentSensorPin: UInt32 = 0 + init?(rawValue: Int) { + switch rawValue { + case 0: self = .vlongSlow + case 1: self = .longSlow + case 2: self = .longFast + case 3: self = .midSlow + case 4: self = .midFast + case 5: self = .shortSlow + case 6: self = .shortFast + default: self = .UNRECOGNIZED(rawValue) + } + } - var unknownFields = SwiftProtobuf.UnknownStorage() + var rawValue: Int { + switch self { + case .vlongSlow: return 0 + case .longSlow: return 1 + case .longFast: return 2 + case .midSlow: return 3 + case .midFast: return 4 + case .shortSlow: return 5 + case .shortFast: return 6 + case .UNRECOGNIZED(let i): return i + } + } - init() {} - } - - /// - /// TODO: REPLACE - struct CannedMessageConfig { - // 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 unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} } init() {} @@ -534,24 +963,117 @@ struct Config { init() {} } +#if swift(>=4.2) + +extension Config.DeviceConfig.Role: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [Config.DeviceConfig.Role] = [ + .client, + .clientMute, + .router, + .routerClient, + ] +} + +extension Config.PositionConfig.PositionFlags: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [Config.PositionConfig.PositionFlags] = [ + .posUndefined, + .posAltitude, + .posAltMsl, + .posGeoSep, + .posDop, + .posHvdop, + .posSatinview, + .posSeqNos, + .posTimestamp, + ] +} + +extension Config.PowerConfig.ChargeCurrent: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [Config.PowerConfig.ChargeCurrent] = [ + .maunset, + .ma100, + .ma190, + .ma280, + .ma360, + .ma450, + .ma550, + .ma630, + .ma700, + .ma780, + .ma880, + .ma960, + .ma1000, + .ma1080, + .ma1160, + .ma1240, + .ma1320, + ] +} + +extension Config.DisplayConfig.GpsCoordinateFormat: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [Config.DisplayConfig.GpsCoordinateFormat] = [ + .gpsFormatDec, + .gpsFormatDms, + .gpsFormatUtm, + .gpsFormatMgrs, + .gpsFormatOlc, + .gpsFormatOsgr, + ] +} + +extension Config.LoRaConfig.RegionCode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [Config.LoRaConfig.RegionCode] = [ + .unset, + .us, + .eu433, + .eu868, + .cn, + .jp, + .anz, + .kr, + .tw, + .ru, + .in, + .nz865, + .th, + ] +} + +extension Config.LoRaConfig.ModemPreset: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [Config.LoRaConfig.ModemPreset] = [ + .vlongSlow, + .longSlow, + .longFast, + .midSlow, + .midFast, + .shortSlow, + .shortFast, + ] +} + +#endif // swift(>=4.2) + #if swift(>=5.5) && canImport(_Concurrency) extension Config: @unchecked Sendable {} extension Config.OneOf_PayloadVariant: @unchecked Sendable {} extension Config.DeviceConfig: @unchecked Sendable {} -extension Config.GpsConfig: @unchecked Sendable {} +extension Config.DeviceConfig.Role: @unchecked Sendable {} +extension Config.PositionConfig: @unchecked Sendable {} +extension Config.PositionConfig.PositionFlags: @unchecked Sendable {} extension Config.PowerConfig: @unchecked Sendable {} +extension Config.PowerConfig.ChargeCurrent: @unchecked Sendable {} extension Config.WiFiConfig: @unchecked Sendable {} extension Config.DisplayConfig: @unchecked Sendable {} +extension Config.DisplayConfig.GpsCoordinateFormat: @unchecked Sendable {} extension Config.LoRaConfig: @unchecked Sendable {} -extension Config.ModuleConfig: @unchecked Sendable {} -extension Config.ModuleConfig.OneOf_PayloadVariant: @unchecked Sendable {} -extension Config.ModuleConfig.MQTTConfig: @unchecked Sendable {} -extension Config.ModuleConfig.SerialConfig: @unchecked Sendable {} -extension Config.ModuleConfig.ExternalNotificationConfig: @unchecked Sendable {} -extension Config.ModuleConfig.StoreForwardConfig: @unchecked Sendable {} -extension Config.ModuleConfig.RangeTestConfig: @unchecked Sendable {} -extension Config.ModuleConfig.TelemetryConfig: @unchecked Sendable {} -extension Config.ModuleConfig.CannedMessageConfig: @unchecked Sendable {} +extension Config.LoRaConfig.RegionCode: @unchecked Sendable {} +extension Config.LoRaConfig.ModemPreset: @unchecked Sendable {} #endif // swift(>=5.5) && canImport(_Concurrency) // MARK: - Code below here is support for the SwiftProtobuf runtime. @@ -559,13 +1081,12 @@ extension Config.ModuleConfig.CannedMessageConfig: @unchecked Sendable {} extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "Config" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "device_config"), - 2: .standard(proto: "gps_config"), - 3: .standard(proto: "power_config"), - 4: .standard(proto: "wifi_config"), - 5: .standard(proto: "display_config"), - 6: .standard(proto: "lora_config"), - 7: .standard(proto: "module_config"), + 1: .same(proto: "device"), + 2: .same(proto: "position"), + 3: .same(proto: "power"), + 4: .same(proto: "wifi"), + 5: .same(proto: "display"), + 6: .same(proto: "lora"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -579,25 +1100,25 @@ extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .deviceConfig(let m) = current {v = m} + if case .device(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .deviceConfig(v) + self.payloadVariant = .device(v) } }() case 2: try { - var v: Config.GpsConfig? + var v: Config.PositionConfig? var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .gpsConfig(let m) = current {v = m} + if case .position(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .gpsConfig(v) + self.payloadVariant = .position(v) } }() case 3: try { @@ -605,12 +1126,12 @@ extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .powerConfig(let m) = current {v = m} + if case .power(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .powerConfig(v) + self.payloadVariant = .power(v) } }() case 4: try { @@ -618,12 +1139,12 @@ extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .wifiConfig(let m) = current {v = m} + if case .wifi(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .wifiConfig(v) + self.payloadVariant = .wifi(v) } }() case 5: try { @@ -631,12 +1152,12 @@ extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .displayConfig(let m) = current {v = m} + if case .display(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .displayConfig(v) + self.payloadVariant = .display(v) } }() case 6: try { @@ -644,25 +1165,12 @@ extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .loraConfig(let m) = current {v = m} + if case .lora(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .loraConfig(v) - } - }() - case 7: try { - var v: Config.ModuleConfig? - var hadOneofValue = false - if let current = self.payloadVariant { - hadOneofValue = true - if case .moduleConfig(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .moduleConfig(v) + self.payloadVariant = .lora(v) } }() default: break @@ -676,34 +1184,30 @@ extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and // https://github.com/apple/swift-protobuf/issues/1182 switch self.payloadVariant { - case .deviceConfig?: try { - guard case .deviceConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .device?: try { + guard case .device(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 1) }() - case .gpsConfig?: try { - guard case .gpsConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .position?: try { + guard case .position(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 2) }() - case .powerConfig?: try { - guard case .powerConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .power?: try { + guard case .power(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 3) }() - case .wifiConfig?: try { - guard case .wifiConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .wifi?: try { + guard case .wifi(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 4) }() - case .displayConfig?: try { - guard case .displayConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .display?: try { + guard case .display(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 5) }() - case .loraConfig?: try { - guard case .loraConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .lora?: try { + guard case .lora(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 6) }() - case .moduleConfig?: try { - guard case .moduleConfig(let v)? = self.payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - }() case nil: break } try unknownFields.traverse(visitor: &visitor) @@ -718,67 +1222,12 @@ extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = Config.protoMessageName + ".DeviceConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } - } - - func traverse(visitor: inout V) throws { - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Config.DeviceConfig, rhs: Config.DeviceConfig) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Config.GpsConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.protoMessageName + ".GpsConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } - } - - func traverse(visitor: inout V) throws { - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Config.GpsConfig, rhs: Config.GpsConfig) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.protoMessageName + ".PowerConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } - } - - func traverse(visitor: inout V) throws { - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Config.PowerConfig, rhs: Config.PowerConfig) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Config.WiFiConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.protoMessageName + ".WiFiConfig" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "wifi_ssid"), - 2: .standard(proto: "wifi_password"), - 3: .standard(proto: "wifi_ap_mode"), + 1: .same(proto: "role"), + 2: .standard(proto: "serial_disabled"), + 3: .standard(proto: "factory_reset"), + 4: .standard(proto: "debug_log_enabled"), + 5: .standard(proto: "ntp_server"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -787,31 +1236,314 @@ extension Config.WiFiConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem // 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.decodeSingularStringField(value: &self.wifiSsid) }() - case 2: try { try decoder.decodeSingularStringField(value: &self.wifiPassword) }() - case 3: try { try decoder.decodeSingularBoolField(value: &self.wifiApMode) }() + case 1: try { try decoder.decodeSingularEnumField(value: &self.role) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.serialDisabled) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.factoryReset) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self.debugLogEnabled) }() + case 5: try { try decoder.decodeSingularStringField(value: &self.ntpServer) }() default: break } } } func traverse(visitor: inout V) throws { - if !self.wifiSsid.isEmpty { - try visitor.visitSingularStringField(value: self.wifiSsid, fieldNumber: 1) + if self.role != .client { + try visitor.visitSingularEnumField(value: self.role, fieldNumber: 1) } - if !self.wifiPassword.isEmpty { - try visitor.visitSingularStringField(value: self.wifiPassword, fieldNumber: 2) + if self.serialDisabled != false { + try visitor.visitSingularBoolField(value: self.serialDisabled, fieldNumber: 2) } - if self.wifiApMode != false { - try visitor.visitSingularBoolField(value: self.wifiApMode, fieldNumber: 3) + if self.factoryReset != false { + try visitor.visitSingularBoolField(value: self.factoryReset, fieldNumber: 3) + } + if self.debugLogEnabled != false { + try visitor.visitSingularBoolField(value: self.debugLogEnabled, fieldNumber: 4) + } + if !self.ntpServer.isEmpty { + try visitor.visitSingularStringField(value: self.ntpServer, fieldNumber: 5) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.DeviceConfig, rhs: Config.DeviceConfig) -> Bool { + if lhs.role != rhs.role {return false} + if lhs.serialDisabled != rhs.serialDisabled {return false} + if lhs.factoryReset != rhs.factoryReset {return false} + if lhs.debugLogEnabled != rhs.debugLogEnabled {return false} + if lhs.ntpServer != rhs.ntpServer {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.DeviceConfig.Role: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "Client"), + 1: .same(proto: "ClientMute"), + 2: .same(proto: "Router"), + 3: .same(proto: "RouterClient"), + ] +} + +extension Config.PositionConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.protoMessageName + ".PositionConfig" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "position_broadcast_secs"), + 2: .standard(proto: "position_broadcast_smart_disabled"), + 3: .standard(proto: "fixed_position"), + 4: .standard(proto: "location_share_disabled"), + 5: .standard(proto: "gps_disabled"), + 6: .standard(proto: "gps_update_interval"), + 7: .standard(proto: "gps_attempt_time"), + 8: .standard(proto: "gps_accept_2d"), + 9: .standard(proto: "gps_max_dop"), + 10: .standard(proto: "position_flags"), + ] + + 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.positionBroadcastSecs) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.positionBroadcastSmartDisabled) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.fixedPosition) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self.locationShareDisabled) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self.gpsDisabled) }() + case 6: try { try decoder.decodeSingularUInt32Field(value: &self.gpsUpdateInterval) }() + case 7: try { try decoder.decodeSingularUInt32Field(value: &self.gpsAttemptTime) }() + case 8: try { try decoder.decodeSingularBoolField(value: &self.gpsAccept2D) }() + case 9: try { try decoder.decodeSingularUInt32Field(value: &self.gpsMaxDop) }() + case 10: try { try decoder.decodeSingularUInt32Field(value: &self.positionFlags) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.positionBroadcastSecs != 0 { + try visitor.visitSingularUInt32Field(value: self.positionBroadcastSecs, fieldNumber: 1) + } + if self.positionBroadcastSmartDisabled != false { + try visitor.visitSingularBoolField(value: self.positionBroadcastSmartDisabled, fieldNumber: 2) + } + if self.fixedPosition != false { + try visitor.visitSingularBoolField(value: self.fixedPosition, fieldNumber: 3) + } + if self.locationShareDisabled != false { + try visitor.visitSingularBoolField(value: self.locationShareDisabled, fieldNumber: 4) + } + if self.gpsDisabled != false { + try visitor.visitSingularBoolField(value: self.gpsDisabled, fieldNumber: 5) + } + if self.gpsUpdateInterval != 0 { + try visitor.visitSingularUInt32Field(value: self.gpsUpdateInterval, fieldNumber: 6) + } + if self.gpsAttemptTime != 0 { + try visitor.visitSingularUInt32Field(value: self.gpsAttemptTime, fieldNumber: 7) + } + if self.gpsAccept2D != false { + try visitor.visitSingularBoolField(value: self.gpsAccept2D, fieldNumber: 8) + } + if self.gpsMaxDop != 0 { + try visitor.visitSingularUInt32Field(value: self.gpsMaxDop, fieldNumber: 9) + } + if self.positionFlags != 0 { + try visitor.visitSingularUInt32Field(value: self.positionFlags, fieldNumber: 10) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.PositionConfig, rhs: Config.PositionConfig) -> Bool { + if lhs.positionBroadcastSecs != rhs.positionBroadcastSecs {return false} + if lhs.positionBroadcastSmartDisabled != rhs.positionBroadcastSmartDisabled {return false} + if lhs.fixedPosition != rhs.fixedPosition {return false} + if lhs.locationShareDisabled != rhs.locationShareDisabled {return false} + if lhs.gpsDisabled != rhs.gpsDisabled {return false} + if lhs.gpsUpdateInterval != rhs.gpsUpdateInterval {return false} + if lhs.gpsAttemptTime != rhs.gpsAttemptTime {return false} + if lhs.gpsAccept2D != rhs.gpsAccept2D {return false} + if lhs.gpsMaxDop != rhs.gpsMaxDop {return false} + if lhs.positionFlags != rhs.positionFlags {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.PositionConfig.PositionFlags: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "POS_UNDEFINED"), + 1: .same(proto: "POS_ALTITUDE"), + 2: .same(proto: "POS_ALT_MSL"), + 4: .same(proto: "POS_GEO_SEP"), + 8: .same(proto: "POS_DOP"), + 16: .same(proto: "POS_HVDOP"), + 32: .same(proto: "POS_SATINVIEW"), + 64: .same(proto: "POS_SEQ_NOS"), + 128: .same(proto: "POS_TIMESTAMP"), + ] +} + +extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.protoMessageName + ".PowerConfig" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "charge_current"), + 2: .standard(proto: "is_low_power"), + 3: .standard(proto: "is_always_powered"), + 4: .standard(proto: "on_battery_shutdown_after_secs"), + 5: .standard(proto: "is_power_saving"), + 6: .standard(proto: "adc_multiplier_override"), + 7: .standard(proto: "wait_bluetooth_secs"), + 8: .standard(proto: "phone_timeout_secs"), + 9: .standard(proto: "mesh_sds_timeout_secs"), + 10: .standard(proto: "sds_secs"), + 11: .standard(proto: "ls_secs"), + 12: .standard(proto: "min_wake_secs"), + ] + + 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.decodeSingularEnumField(value: &self.chargeCurrent) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.isLowPower) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.isAlwaysPowered) }() + case 4: try { try decoder.decodeSingularUInt32Field(value: &self.onBatteryShutdownAfterSecs) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self.isPowerSaving) }() + case 6: try { try decoder.decodeSingularFloatField(value: &self.adcMultiplierOverride) }() + case 7: try { try decoder.decodeSingularUInt32Field(value: &self.waitBluetoothSecs) }() + case 8: try { try decoder.decodeSingularUInt32Field(value: &self.phoneTimeoutSecs) }() + case 9: try { try decoder.decodeSingularUInt32Field(value: &self.meshSdsTimeoutSecs) }() + case 10: try { try decoder.decodeSingularUInt32Field(value: &self.sdsSecs) }() + case 11: try { try decoder.decodeSingularUInt32Field(value: &self.lsSecs) }() + case 12: try { try decoder.decodeSingularUInt32Field(value: &self.minWakeSecs) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.chargeCurrent != .maunset { + try visitor.visitSingularEnumField(value: self.chargeCurrent, fieldNumber: 1) + } + if self.isLowPower != false { + try visitor.visitSingularBoolField(value: self.isLowPower, fieldNumber: 2) + } + if self.isAlwaysPowered != false { + try visitor.visitSingularBoolField(value: self.isAlwaysPowered, fieldNumber: 3) + } + if self.onBatteryShutdownAfterSecs != 0 { + try visitor.visitSingularUInt32Field(value: self.onBatteryShutdownAfterSecs, fieldNumber: 4) + } + if self.isPowerSaving != false { + try visitor.visitSingularBoolField(value: self.isPowerSaving, fieldNumber: 5) + } + if self.adcMultiplierOverride != 0 { + try visitor.visitSingularFloatField(value: self.adcMultiplierOverride, fieldNumber: 6) + } + if self.waitBluetoothSecs != 0 { + try visitor.visitSingularUInt32Field(value: self.waitBluetoothSecs, fieldNumber: 7) + } + if self.phoneTimeoutSecs != 0 { + try visitor.visitSingularUInt32Field(value: self.phoneTimeoutSecs, fieldNumber: 8) + } + if self.meshSdsTimeoutSecs != 0 { + try visitor.visitSingularUInt32Field(value: self.meshSdsTimeoutSecs, fieldNumber: 9) + } + if self.sdsSecs != 0 { + try visitor.visitSingularUInt32Field(value: self.sdsSecs, fieldNumber: 10) + } + if self.lsSecs != 0 { + try visitor.visitSingularUInt32Field(value: self.lsSecs, fieldNumber: 11) + } + if self.minWakeSecs != 0 { + try visitor.visitSingularUInt32Field(value: self.minWakeSecs, fieldNumber: 12) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Config.PowerConfig, rhs: Config.PowerConfig) -> Bool { + if lhs.chargeCurrent != rhs.chargeCurrent {return false} + if lhs.isLowPower != rhs.isLowPower {return false} + if lhs.isAlwaysPowered != rhs.isAlwaysPowered {return false} + if lhs.onBatteryShutdownAfterSecs != rhs.onBatteryShutdownAfterSecs {return false} + if lhs.isPowerSaving != rhs.isPowerSaving {return false} + if lhs.adcMultiplierOverride != rhs.adcMultiplierOverride {return false} + if lhs.waitBluetoothSecs != rhs.waitBluetoothSecs {return false} + if lhs.phoneTimeoutSecs != rhs.phoneTimeoutSecs {return false} + if lhs.meshSdsTimeoutSecs != rhs.meshSdsTimeoutSecs {return false} + if lhs.sdsSecs != rhs.sdsSecs {return false} + if lhs.lsSecs != rhs.lsSecs {return false} + if lhs.minWakeSecs != rhs.minWakeSecs {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Config.PowerConfig.ChargeCurrent: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "MAUnset"), + 1: .same(proto: "MA100"), + 2: .same(proto: "MA190"), + 3: .same(proto: "MA280"), + 4: .same(proto: "MA360"), + 5: .same(proto: "MA450"), + 6: .same(proto: "MA550"), + 7: .same(proto: "MA630"), + 8: .same(proto: "MA700"), + 9: .same(proto: "MA780"), + 10: .same(proto: "MA880"), + 11: .same(proto: "MA960"), + 12: .same(proto: "MA1000"), + 13: .same(proto: "MA1080"), + 14: .same(proto: "MA1160"), + 15: .same(proto: "MA1240"), + 16: .same(proto: "MA1320"), + ] +} + +extension Config.WiFiConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.protoMessageName + ".WiFiConfig" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "ssid"), + 2: .same(proto: "psk"), + 3: .standard(proto: "ap_mode"), + ] + + 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.decodeSingularStringField(value: &self.ssid) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.psk) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.apMode) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if !self.ssid.isEmpty { + try visitor.visitSingularStringField(value: self.ssid, fieldNumber: 1) + } + if !self.psk.isEmpty { + try visitor.visitSingularStringField(value: self.psk, fieldNumber: 2) + } + if self.apMode != false { + try visitor.visitSingularBoolField(value: self.apMode, fieldNumber: 3) } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: Config.WiFiConfig, rhs: Config.WiFiConfig) -> Bool { - if lhs.wifiSsid != rhs.wifiSsid {return false} - if lhs.wifiPassword != rhs.wifiPassword {return false} - if lhs.wifiApMode != rhs.wifiApMode {return false} + if lhs.ssid != rhs.ssid {return false} + if lhs.psk != rhs.psk {return false} + if lhs.apMode != rhs.apMode {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -819,392 +1551,171 @@ extension Config.WiFiConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem extension Config.DisplayConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = Config.protoMessageName + ".DisplayConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "screen_on_secs"), + 2: .standard(proto: "gps_format"), + 3: .standard(proto: "auto_screen_carousel_secs"), + ] mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { + 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.screenOnSecs) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self.gpsFormat) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self.autoScreenCarouselSecs) }() + default: break + } } } func traverse(visitor: inout V) throws { + if self.screenOnSecs != 0 { + try visitor.visitSingularUInt32Field(value: self.screenOnSecs, fieldNumber: 1) + } + if self.gpsFormat != .gpsFormatDec { + try visitor.visitSingularEnumField(value: self.gpsFormat, fieldNumber: 2) + } + if self.autoScreenCarouselSecs != 0 { + try visitor.visitSingularUInt32Field(value: self.autoScreenCarouselSecs, fieldNumber: 3) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: Config.DisplayConfig, rhs: Config.DisplayConfig) -> Bool { + if lhs.screenOnSecs != rhs.screenOnSecs {return false} + if lhs.gpsFormat != rhs.gpsFormat {return false} + if lhs.autoScreenCarouselSecs != rhs.autoScreenCarouselSecs {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } } +extension Config.DisplayConfig.GpsCoordinateFormat: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "GpsFormatDec"), + 1: .same(proto: "GpsFormatDMS"), + 2: .same(proto: "GpsFormatUTM"), + 3: .same(proto: "GpsFormatMGRS"), + 4: .same(proto: "GpsFormatOLC"), + 5: .same(proto: "GpsFormatOSGR"), + ] +} + extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = Config.protoMessageName + ".LoRaConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "tx_power"), + 2: .standard(proto: "modem_preset"), + 3: .same(proto: "bandwidth"), + 4: .standard(proto: "spread_factor"), + 5: .standard(proto: "coding_rate"), + 6: .standard(proto: "frequency_offset"), + 7: .same(proto: "region"), + 8: .standard(proto: "hop_limit"), + 9: .standard(proto: "tx_disabled"), + 103: .standard(proto: "ignore_incoming"), + ] mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { + 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.decodeSingularInt32Field(value: &self.txPower) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self.modemPreset) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self.bandwidth) }() + case 4: try { try decoder.decodeSingularUInt32Field(value: &self.spreadFactor) }() + case 5: try { try decoder.decodeSingularUInt32Field(value: &self.codingRate) }() + case 6: try { try decoder.decodeSingularFloatField(value: &self.frequencyOffset) }() + case 7: try { try decoder.decodeSingularEnumField(value: &self.region) }() + case 8: try { try decoder.decodeSingularUInt32Field(value: &self.hopLimit) }() + case 9: try { try decoder.decodeSingularBoolField(value: &self.txDisabled) }() + case 103: try { try decoder.decodeRepeatedUInt32Field(value: &self.ignoreIncoming) }() + default: break + } } } func traverse(visitor: inout V) throws { + if self.txPower != 0 { + try visitor.visitSingularInt32Field(value: self.txPower, fieldNumber: 1) + } + if self.modemPreset != .vlongSlow { + try visitor.visitSingularEnumField(value: self.modemPreset, fieldNumber: 2) + } + if self.bandwidth != 0 { + try visitor.visitSingularUInt32Field(value: self.bandwidth, fieldNumber: 3) + } + if self.spreadFactor != 0 { + try visitor.visitSingularUInt32Field(value: self.spreadFactor, fieldNumber: 4) + } + if self.codingRate != 0 { + try visitor.visitSingularUInt32Field(value: self.codingRate, fieldNumber: 5) + } + if self.frequencyOffset != 0 { + try visitor.visitSingularFloatField(value: self.frequencyOffset, fieldNumber: 6) + } + if self.region != .unset { + try visitor.visitSingularEnumField(value: self.region, fieldNumber: 7) + } + if self.hopLimit != 0 { + try visitor.visitSingularUInt32Field(value: self.hopLimit, fieldNumber: 8) + } + if self.txDisabled != false { + try visitor.visitSingularBoolField(value: self.txDisabled, fieldNumber: 9) + } + if !self.ignoreIncoming.isEmpty { + try visitor.visitPackedUInt32Field(value: self.ignoreIncoming, fieldNumber: 103) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: Config.LoRaConfig, rhs: Config.LoRaConfig) -> Bool { + if lhs.txPower != rhs.txPower {return false} + if lhs.modemPreset != rhs.modemPreset {return false} + if lhs.bandwidth != rhs.bandwidth {return false} + if lhs.spreadFactor != rhs.spreadFactor {return false} + if lhs.codingRate != rhs.codingRate {return false} + if lhs.frequencyOffset != rhs.frequencyOffset {return false} + if lhs.region != rhs.region {return false} + if lhs.hopLimit != rhs.hopLimit {return false} + if lhs.txDisabled != rhs.txDisabled {return false} + if lhs.ignoreIncoming != rhs.ignoreIncoming {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } } -extension Config.ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.protoMessageName + ".ModuleConfig" +extension Config.LoRaConfig.RegionCode: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "mqtt_config"), - 2: .standard(proto: "serial_config"), - 3: .standard(proto: "external_notification_config"), - 4: .standard(proto: "store_forward_config"), - 5: .standard(proto: "range_test_config"), - 6: .standard(proto: "telemetry_config"), - 7: .standard(proto: "canned_message_config"), + 0: .same(proto: "Unset"), + 1: .same(proto: "US"), + 2: .same(proto: "EU433"), + 3: .same(proto: "EU868"), + 4: .same(proto: "CN"), + 5: .same(proto: "JP"), + 6: .same(proto: "ANZ"), + 7: .same(proto: "KR"), + 8: .same(proto: "TW"), + 9: .same(proto: "RU"), + 10: .same(proto: "IN"), + 11: .same(proto: "NZ865"), + 12: .same(proto: "TH"), ] - - 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 { - var v: Config.ModuleConfig.MQTTConfig? - var hadOneofValue = false - if let current = self.payloadVariant { - hadOneofValue = true - if case .mqttConfig(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .mqttConfig(v) - } - }() - case 2: try { - var v: Config.ModuleConfig.SerialConfig? - var hadOneofValue = false - if let current = self.payloadVariant { - hadOneofValue = true - if case .serialConfig(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .serialConfig(v) - } - }() - case 3: try { - var v: Config.ModuleConfig.ExternalNotificationConfig? - var hadOneofValue = false - if let current = self.payloadVariant { - hadOneofValue = true - if case .externalNotificationConfig(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .externalNotificationConfig(v) - } - }() - case 4: try { - var v: Config.ModuleConfig.StoreForwardConfig? - var hadOneofValue = false - if let current = self.payloadVariant { - hadOneofValue = true - if case .storeForwardConfig(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .storeForwardConfig(v) - } - }() - case 5: try { - var v: Config.ModuleConfig.RangeTestConfig? - var hadOneofValue = false - if let current = self.payloadVariant { - hadOneofValue = true - if case .rangeTestConfig(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .rangeTestConfig(v) - } - }() - case 6: try { - var v: Config.ModuleConfig.TelemetryConfig? - var hadOneofValue = false - if let current = self.payloadVariant { - hadOneofValue = true - if case .telemetryConfig(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .telemetryConfig(v) - } - }() - case 7: try { - var v: Config.ModuleConfig.CannedMessageConfig? - var hadOneofValue = false - if let current = self.payloadVariant { - hadOneofValue = true - if case .cannedMessageConfig(let m) = current {v = m} - } - try decoder.decodeSingularMessageField(value: &v) - if let v = v { - if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .cannedMessageConfig(v) - } - }() - 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 - switch self.payloadVariant { - case .mqttConfig?: try { - guard case .mqttConfig(let v)? = self.payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - }() - case .serialConfig?: try { - guard case .serialConfig(let v)? = self.payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - }() - case .externalNotificationConfig?: try { - guard case .externalNotificationConfig(let v)? = self.payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - }() - case .storeForwardConfig?: try { - guard case .storeForwardConfig(let v)? = self.payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - }() - case .rangeTestConfig?: try { - guard case .rangeTestConfig(let v)? = self.payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 5) - }() - case .telemetryConfig?: try { - guard case .telemetryConfig(let v)? = self.payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 6) - }() - case .cannedMessageConfig?: try { - guard case .cannedMessageConfig(let v)? = self.payloadVariant else { preconditionFailure() } - try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - }() - case nil: break - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Config.ModuleConfig, rhs: Config.ModuleConfig) -> Bool { - if lhs.payloadVariant != rhs.payloadVariant {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } } -extension Config.ModuleConfig.MQTTConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".MQTTConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } - } - - func traverse(visitor: inout V) throws { - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Config.ModuleConfig.MQTTConfig, rhs: Config.ModuleConfig.MQTTConfig) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Config.ModuleConfig.SerialConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".SerialConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } - } - - func traverse(visitor: inout V) throws { - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Config.ModuleConfig.SerialConfig, rhs: Config.ModuleConfig.SerialConfig) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Config.ModuleConfig.ExternalNotificationConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".ExternalNotificationConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } - } - - func traverse(visitor: inout V) throws { - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Config.ModuleConfig.ExternalNotificationConfig, rhs: Config.ModuleConfig.ExternalNotificationConfig) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Config.ModuleConfig.StoreForwardConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".StoreForwardConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } - } - - func traverse(visitor: inout V) throws { - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Config.ModuleConfig.StoreForwardConfig, rhs: Config.ModuleConfig.StoreForwardConfig) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Config.ModuleConfig.RangeTestConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".RangeTestConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } - } - - func traverse(visitor: inout V) throws { - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Config.ModuleConfig.RangeTestConfig, rhs: Config.ModuleConfig.RangeTestConfig) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Config.ModuleConfig.TelemetryConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".TelemetryConfig" +extension Config.LoRaConfig.ModemPreset: SwiftProtobuf._ProtoNameProviding { static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "device_update_interval"), - 2: .standard(proto: "environment_update_interval"), - 3: .standard(proto: "environment_measurement_enabled"), - 4: .standard(proto: "environment_screen_enabled"), - 5: .standard(proto: "environment_read_error_count_threshold"), - 6: .standard(proto: "environment_recovery_interval"), - 7: .standard(proto: "environment_display_fahrenheit"), - 8: .standard(proto: "environment_sensor_type"), - 9: .standard(proto: "environment_sensor_pin"), + 0: .same(proto: "VLongSlow"), + 1: .same(proto: "LongSlow"), + 2: .same(proto: "LongFast"), + 3: .same(proto: "MidSlow"), + 4: .same(proto: "MidFast"), + 5: .same(proto: "ShortSlow"), + 6: .same(proto: "ShortFast"), ] - - 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.deviceUpdateInterval) }() - case 2: try { try decoder.decodeSingularUInt32Field(value: &self.environmentUpdateInterval) }() - case 3: try { try decoder.decodeSingularBoolField(value: &self.environmentMeasurementEnabled) }() - case 4: try { try decoder.decodeSingularBoolField(value: &self.environmentScreenEnabled) }() - case 5: try { try decoder.decodeSingularUInt32Field(value: &self.environmentReadErrorCountThreshold) }() - case 6: try { try decoder.decodeSingularUInt32Field(value: &self.environmentRecoveryInterval) }() - case 7: try { try decoder.decodeSingularBoolField(value: &self.environmentDisplayFahrenheit) }() - case 8: try { try decoder.decodeSingularEnumField(value: &self.environmentSensorType) }() - case 9: try { try decoder.decodeSingularUInt32Field(value: &self.environmentSensorPin) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if self.deviceUpdateInterval != 0 { - try visitor.visitSingularUInt32Field(value: self.deviceUpdateInterval, fieldNumber: 1) - } - if self.environmentUpdateInterval != 0 { - try visitor.visitSingularUInt32Field(value: self.environmentUpdateInterval, fieldNumber: 2) - } - if self.environmentMeasurementEnabled != false { - try visitor.visitSingularBoolField(value: self.environmentMeasurementEnabled, fieldNumber: 3) - } - if self.environmentScreenEnabled != false { - try visitor.visitSingularBoolField(value: self.environmentScreenEnabled, fieldNumber: 4) - } - if self.environmentReadErrorCountThreshold != 0 { - try visitor.visitSingularUInt32Field(value: self.environmentReadErrorCountThreshold, fieldNumber: 5) - } - if self.environmentRecoveryInterval != 0 { - try visitor.visitSingularUInt32Field(value: self.environmentRecoveryInterval, fieldNumber: 6) - } - if self.environmentDisplayFahrenheit != false { - try visitor.visitSingularBoolField(value: self.environmentDisplayFahrenheit, fieldNumber: 7) - } - if self.environmentSensorType != .notSet { - try visitor.visitSingularEnumField(value: self.environmentSensorType, fieldNumber: 8) - } - if self.environmentSensorPin != 0 { - try visitor.visitSingularUInt32Field(value: self.environmentSensorPin, fieldNumber: 9) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Config.ModuleConfig.TelemetryConfig, rhs: Config.ModuleConfig.TelemetryConfig) -> Bool { - if lhs.deviceUpdateInterval != rhs.deviceUpdateInterval {return false} - if lhs.environmentUpdateInterval != rhs.environmentUpdateInterval {return false} - if lhs.environmentMeasurementEnabled != rhs.environmentMeasurementEnabled {return false} - if lhs.environmentScreenEnabled != rhs.environmentScreenEnabled {return false} - if lhs.environmentReadErrorCountThreshold != rhs.environmentReadErrorCountThreshold {return false} - if lhs.environmentRecoveryInterval != rhs.environmentRecoveryInterval {return false} - if lhs.environmentDisplayFahrenheit != rhs.environmentDisplayFahrenheit {return false} - if lhs.environmentSensorType != rhs.environmentSensorType {return false} - if lhs.environmentSensorPin != rhs.environmentSensorPin {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Config.ModuleConfig.CannedMessageConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.ModuleConfig.protoMessageName + ".CannedMessageConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } - } - - func traverse(visitor: inout V) throws { - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Config.ModuleConfig.CannedMessageConfig, rhs: Config.ModuleConfig.CannedMessageConfig) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } } diff --git a/MeshtasticClient/Protobufs/deviceonly.pb.swift b/MeshtasticClient/Protobufs/deviceonly.pb.swift index a8e59f76..52a31d33 100644 --- a/MeshtasticClient/Protobufs/deviceonly.pb.swift +++ b/MeshtasticClient/Protobufs/deviceonly.pb.swift @@ -89,68 +89,81 @@ struct DeviceState { /// /// Read only settings/info about this node var myNode: MyNodeInfo { - get {return _myNode ?? MyNodeInfo()} - set {_myNode = newValue} + get {return _storage._myNode ?? MyNodeInfo()} + set {_uniqueStorage()._myNode = newValue} } /// Returns true if `myNode` has been explicitly set. - var hasMyNode: Bool {return self._myNode != nil} + var hasMyNode: Bool {return _storage._myNode != nil} /// Clears the value of `myNode`. Subsequent reads from it will return its default value. - mutating func clearMyNode() {self._myNode = nil} + mutating func clearMyNode() {_uniqueStorage()._myNode = nil} /// /// My owner info var owner: User { - get {return _owner ?? User()} - set {_owner = newValue} + get {return _storage._owner ?? User()} + set {_uniqueStorage()._owner = newValue} } /// Returns true if `owner` has been explicitly set. - var hasOwner: Bool {return self._owner != nil} + var hasOwner: Bool {return _storage._owner != nil} /// Clears the value of `owner`. Subsequent reads from it will return its default value. - mutating func clearOwner() {self._owner = nil} + mutating func clearOwner() {_uniqueStorage()._owner = nil} /// /// TODO: REPLACE - var nodeDb: [NodeInfo] = [] + var nodeDb: [NodeInfo] { + get {return _storage._nodeDb} + set {_uniqueStorage()._nodeDb = newValue} + } /// /// Received packets saved for delivery to the phone - var receiveQueue: [MeshPacket] = [] + var receiveQueue: [MeshPacket] { + get {return _storage._receiveQueue} + set {_uniqueStorage()._receiveQueue = newValue} + } /// /// A version integer used to invalidate old save files when we make /// incompatible changes This integer is set at build time and is private to /// NodeDB.cpp in the device code. - var version: UInt32 = 0 + var version: UInt32 { + get {return _storage._version} + set {_uniqueStorage()._version = newValue} + } /// /// We keep the last received text message (only) stored in the device flash, /// so we can show it on the screen. /// Might be null var rxTextMessage: MeshPacket { - get {return _rxTextMessage ?? MeshPacket()} - set {_rxTextMessage = newValue} + get {return _storage._rxTextMessage ?? MeshPacket()} + set {_uniqueStorage()._rxTextMessage = newValue} } /// Returns true if `rxTextMessage` has been explicitly set. - var hasRxTextMessage: Bool {return self._rxTextMessage != nil} + var hasRxTextMessage: Bool {return _storage._rxTextMessage != nil} /// Clears the value of `rxTextMessage`. Subsequent reads from it will return its default value. - mutating func clearRxTextMessage() {self._rxTextMessage = nil} + mutating func clearRxTextMessage() {_uniqueStorage()._rxTextMessage = nil} /// /// Used only during development. /// Indicates developer is testing and changes should never be saved to flash. - var noSave: Bool = false + var noSave: Bool { + get {return _storage._noSave} + set {_uniqueStorage()._noSave = newValue} + } /// /// Some GPSes seem to have bogus settings from the factory, so we always do one factory reset. - var didGpsReset: Bool = false + var didGpsReset: Bool { + get {return _storage._didGpsReset} + set {_uniqueStorage()._didGpsReset = newValue} + } var unknownFields = SwiftProtobuf.UnknownStorage() init() {} - fileprivate var _myNode: MyNodeInfo? = nil - fileprivate var _owner: User? = nil - fileprivate var _rxTextMessage: MeshPacket? = nil + fileprivate var _storage = _StorageClass.defaultInstance } /// @@ -232,66 +245,112 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati 11: .standard(proto: "did_gps_reset"), ] + fileprivate class _StorageClass { + var _myNode: MyNodeInfo? = nil + var _owner: User? = nil + var _nodeDb: [NodeInfo] = [] + var _receiveQueue: [MeshPacket] = [] + var _version: UInt32 = 0 + var _rxTextMessage: MeshPacket? = nil + var _noSave: Bool = false + var _didGpsReset: Bool = false + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _myNode = source._myNode + _owner = source._owner + _nodeDb = source._nodeDb + _receiveQueue = source._receiveQueue + _version = source._version + _rxTextMessage = source._rxTextMessage + _noSave = source._noSave + _didGpsReset = source._didGpsReset + } + } + + 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 2: try { try decoder.decodeSingularMessageField(value: &self._myNode) }() - case 3: try { try decoder.decodeSingularMessageField(value: &self._owner) }() - case 4: try { try decoder.decodeRepeatedMessageField(value: &self.nodeDb) }() - case 5: try { try decoder.decodeRepeatedMessageField(value: &self.receiveQueue) }() - case 7: try { try decoder.decodeSingularMessageField(value: &self._rxTextMessage) }() - case 8: try { try decoder.decodeSingularUInt32Field(value: &self.version) }() - case 9: try { try decoder.decodeSingularBoolField(value: &self.noSave) }() - case 11: try { try decoder.decodeSingularBoolField(value: &self.didGpsReset) }() - 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 2: try { try decoder.decodeSingularMessageField(value: &_storage._myNode) }() + case 3: try { try decoder.decodeSingularMessageField(value: &_storage._owner) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &_storage._nodeDb) }() + case 5: try { try decoder.decodeRepeatedMessageField(value: &_storage._receiveQueue) }() + case 7: try { try decoder.decodeSingularMessageField(value: &_storage._rxTextMessage) }() + case 8: try { try decoder.decodeSingularUInt32Field(value: &_storage._version) }() + case 9: try { try decoder.decodeSingularBoolField(value: &_storage._noSave) }() + case 11: try { try decoder.decodeSingularBoolField(value: &_storage._didGpsReset) }() + 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 - try { if let v = self._myNode { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { if let v = self._owner { - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } }() - if !self.nodeDb.isEmpty { - try visitor.visitRepeatedMessageField(value: self.nodeDb, fieldNumber: 4) - } - if !self.receiveQueue.isEmpty { - try visitor.visitRepeatedMessageField(value: self.receiveQueue, fieldNumber: 5) - } - try { if let v = self._rxTextMessage { - try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - } }() - if self.version != 0 { - try visitor.visitSingularUInt32Field(value: self.version, fieldNumber: 8) - } - if self.noSave != false { - try visitor.visitSingularBoolField(value: self.noSave, fieldNumber: 9) - } - if self.didGpsReset != false { - try visitor.visitSingularBoolField(value: self.didGpsReset, fieldNumber: 11) + 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._myNode { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try { 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 { + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + } }() + if _storage._version != 0 { + try visitor.visitSingularUInt32Field(value: _storage._version, fieldNumber: 8) + } + if _storage._noSave != false { + try visitor.visitSingularBoolField(value: _storage._noSave, fieldNumber: 9) + } + if _storage._didGpsReset != false { + try visitor.visitSingularBoolField(value: _storage._didGpsReset, fieldNumber: 11) + } } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: DeviceState, rhs: DeviceState) -> Bool { - if lhs._myNode != rhs._myNode {return false} - if lhs._owner != rhs._owner {return false} - if lhs.nodeDb != rhs.nodeDb {return false} - if lhs.receiveQueue != rhs.receiveQueue {return false} - if lhs.version != rhs.version {return false} - if lhs._rxTextMessage != rhs._rxTextMessage {return false} - if lhs.noSave != rhs.noSave {return false} - if lhs.didGpsReset != rhs.didGpsReset {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._myNode != rhs_storage._myNode {return false} + if _storage._owner != rhs_storage._owner {return false} + if _storage._nodeDb != rhs_storage._nodeDb {return false} + if _storage._receiveQueue != rhs_storage._receiveQueue {return false} + if _storage._version != rhs_storage._version {return false} + if _storage._rxTextMessage != rhs_storage._rxTextMessage {return false} + if _storage._noSave != rhs_storage._noSave {return false} + if _storage._didGpsReset != rhs_storage._didGpsReset {return false} + return true + } + if !storagesAreEqual {return false} + } if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/MeshtasticClient/Protobufs/mesh.pb.swift b/MeshtasticClient/Protobufs/mesh.pb.swift index c3f77995..c53f4a8c 100644 --- a/MeshtasticClient/Protobufs/mesh.pb.swift +++ b/MeshtasticClient/Protobufs/mesh.pb.swift @@ -122,6 +122,14 @@ enum HardwareModel: SwiftProtobuf.Enum { /// nRF52840 Dongle : https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle/ case nrf52840Pca10059 // = 42 + /// + /// Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio/tree/master/hardware/board_esp32_v3 + case drDev // = 43 + + /// + /// M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ + case m5Stack // = 44 + /// /// Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. case privateHw // = 255 @@ -156,6 +164,8 @@ enum HardwareModel: SwiftProtobuf.Enum { case 40: self = .rak11200 case 41: self = .nanoG1 case 42: self = .nrf52840Pca10059 + case 43: self = .drDev + case 44: self = .m5Stack case 255: self = .privateHw default: self = .UNRECOGNIZED(rawValue) } @@ -186,6 +196,8 @@ enum HardwareModel: SwiftProtobuf.Enum { case .rak11200: return 40 case .nanoG1: return 41 case .nrf52840Pca10059: return 42 + case .drDev: return 43 + case .m5Stack: return 44 case .privateHw: return 255 case .UNRECOGNIZED(let i): return i } @@ -221,6 +233,8 @@ extension HardwareModel: CaseIterable { .rak11200, .nanoG1, .nrf52840Pca10059, + .drDev, + .m5Stack, .privateHw, ] } @@ -1590,45 +1604,20 @@ 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 { - get {return _storage._myNodeNum} - set {_uniqueStorage()._myNodeNum = newValue} - } + var myNodeNum: UInt32 = 0 /// /// Note: This flag merely means we detected a hardware GPS in our node. /// Not the same as UserPreferences.location_sharing - var hasGps_p: Bool { - get {return _storage._hasGps_p} - set {_uniqueStorage()._hasGps_p = newValue} - } + var hasGps_p: Bool = false /// /// 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. - /// The region code for my radio (US, CN, etc...) - /// Note: This string is deprecated. - /// The 1.0 builds populate it based on the flashed firmware name. - /// 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 { - get {return _storage._region} - set {_uniqueStorage()._region = newValue} - } + var maxChannels: UInt32 = 0 /// /// 0.0.5 etc... - var firmwareVersion: String { - get {return _storage._firmwareVersion} - set {_uniqueStorage()._firmwareVersion = newValue} - } + var firmwareVersion: String = String() /// /// An error message we'd like to report back to the mothership through analytics. @@ -1637,99 +1626,61 @@ 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 { - get {return _storage._errorCode} - set {_uniqueStorage()._errorCode = newValue} - } + var errorCode: CriticalErrorCode = .none /// /// A numeric error address (nonzero if available) - var errorAddress: UInt32 { - get {return _storage._errorAddress} - set {_uniqueStorage()._errorAddress = newValue} - } + var errorAddress: UInt32 = 0 /// /// The total number of errors this node has ever encountered /// (well - since the last time we discarded preferences) - var errorCount: UInt32 { - get {return _storage._errorCount} - set {_uniqueStorage()._errorCount = newValue} - } + var errorCount: UInt32 = 0 /// /// The total number of reboots this node has ever encountered /// (well - since the last time we discarded preferences) - var rebootCount: UInt32 { - get {return _storage._rebootCount} - set {_uniqueStorage()._rebootCount = newValue} - } + var rebootCount: UInt32 = 0 /// /// Calculated bitrate of the current channel (in Bytes Per Second) - var bitrate: Float { - get {return _storage._bitrate} - set {_uniqueStorage()._bitrate = newValue} - } + var bitrate: Float = 0 /// /// 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 { - get {return _storage._messageTimeoutMsec} - set {_uniqueStorage()._messageTimeoutMsec = newValue} - } + var messageTimeoutMsec: UInt32 = 0 /// /// 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 { - get {return _storage._minAppVersion} - set {_uniqueStorage()._minAppVersion = newValue} - } + var minAppVersion: UInt32 = 0 /// /// 24 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} - } + var airPeriodTx: [UInt32] = [] /// /// 24 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} - } + var airPeriodRx: [UInt32] = [] /// /// Is the device wifi capable? - var hasWifi_p: Bool { - get {return _storage._hasWifi_p} - set {_uniqueStorage()._hasWifi_p = newValue} - } + var hasWifi_p: Bool = false /// /// 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 channelUtilization: Float = 0 /// /// Percent of airtime for transmission used within the last hour. - var airUtilTx: Float { - get {return _storage._airUtilTx} - set {_uniqueStorage()._airUtilTx = newValue} - } + var airUtilTx: Float = 0 var unknownFields = SwiftProtobuf.UnknownStorage() init() {} - - fileprivate var _storage = _StorageClass.defaultInstance } /// @@ -1860,20 +1811,26 @@ struct FromRadio { /// /// The packet id, used to allow the phone to request missing read packets from the FIFO, /// see our bluetooth docs - var id: UInt32 = 0 + var id: UInt32 { + get {return _storage._id} + set {_uniqueStorage()._id = newValue} + } /// /// Log levels, chosen to match python logging conventions. - var payloadVariant: FromRadio.OneOf_PayloadVariant? = nil + var payloadVariant: OneOf_PayloadVariant? { + get {return _storage._payloadVariant} + set {_uniqueStorage()._payloadVariant = newValue} + } /// /// Log levels, chosen to match python logging conventions. var packet: MeshPacket { get { - if case .packet(let v)? = payloadVariant {return v} + if case .packet(let v)? = _storage._payloadVariant {return v} return MeshPacket() } - set {payloadVariant = .packet(newValue)} + set {_uniqueStorage()._payloadVariant = .packet(newValue)} } /// @@ -1881,10 +1838,10 @@ 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)? = payloadVariant {return v} + if case .myInfo(let v)? = _storage._payloadVariant {return v} return MyNodeInfo() } - set {payloadVariant = .myInfo(newValue)} + set {_uniqueStorage()._payloadVariant = .myInfo(newValue)} } /// @@ -1892,20 +1849,20 @@ struct FromRadio { /// starts over with the first node in our DB var nodeInfo: NodeInfo { get { - if case .nodeInfo(let v)? = payloadVariant {return v} + if case .nodeInfo(let v)? = _storage._payloadVariant {return v} return NodeInfo() } - set {payloadVariant = .nodeInfo(newValue)} + set {_uniqueStorage()._payloadVariant = .nodeInfo(newValue)} } /// /// Set to send debug console output over our protobuf stream var logRecord: LogRecord { get { - if case .logRecord(let v)? = payloadVariant {return v} + if case .logRecord(let v)? = _storage._payloadVariant {return v} return LogRecord() } - set {payloadVariant = .logRecord(newValue)} + set {_uniqueStorage()._payloadVariant = .logRecord(newValue)} } /// @@ -1915,10 +1872,10 @@ struct FromRadio { /// 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)? = payloadVariant {return v} + if case .configCompleteID(let v)? = _storage._payloadVariant {return v} return 0 } - set {payloadVariant = .configCompleteID(newValue)} + set {_uniqueStorage()._payloadVariant = .configCompleteID(newValue)} } /// @@ -1928,10 +1885,10 @@ struct FromRadio { /// 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)? = payloadVariant {return v} + if case .rebooted(let v)? = _storage._payloadVariant {return v} return false } - set {payloadVariant = .rebooted(newValue)} + set {_uniqueStorage()._payloadVariant = .rebooted(newValue)} } var unknownFields = SwiftProtobuf.UnknownStorage() @@ -2003,6 +1960,8 @@ struct FromRadio { } init() {} + + fileprivate var _storage = _StorageClass.defaultInstance } /// @@ -2150,6 +2109,26 @@ struct ToRadio { init() {} } +/// +/// Compressed message payload +struct Compressed { + // 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. + + /// + /// PortNum to determine the how to handle the compressed payload. + var portnum: PortNum = .unknownApp + + /// + /// Compressed data. + var data: Data = Data() + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + #if swift(>=5.5) && canImport(_Concurrency) extension HardwareModel: @unchecked Sendable {} extension Constants: @unchecked Sendable {} @@ -2178,6 +2157,7 @@ extension FromRadio.OneOf_PayloadVariant: @unchecked Sendable {} extension ToRadio: @unchecked Sendable {} extension ToRadio.OneOf_PayloadVariant: @unchecked Sendable {} extension ToRadio.PeerInfo: @unchecked Sendable {} +extension Compressed: @unchecked Sendable {} #endif // swift(>=5.5) && canImport(_Concurrency) // MARK: - Code below here is support for the SwiftProtobuf runtime. @@ -2207,6 +2187,8 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { 40: .same(proto: "RAK11200"), 41: .same(proto: "NANO_G1"), 42: .same(proto: "NRF52840_PCA10059"), + 43: .same(proto: "DR_DEV"), + 44: .same(proto: "M5STACK"), 255: .same(proto: "PRIVATE_HW"), ] } @@ -3175,7 +3157,6 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 1: .standard(proto: "my_node_num"), 2: .standard(proto: "has_gps"), 15: .standard(proto: "max_channels"), - 4: .same(proto: "region"), 6: .standard(proto: "firmware_version"), 7: .standard(proto: "error_code"), 8: .standard(proto: "error_address"), @@ -3191,171 +3172,102 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 20: .standard(proto: "air_util_tx"), ] - fileprivate class _StorageClass { - var _myNodeNum: UInt32 = 0 - var _hasGps_p: Bool = false - var _maxChannels: UInt32 = 0 - var _region: 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 - var _airUtilTx: Float = 0 - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _myNodeNum = source._myNodeNum - _hasGps_p = source._hasGps_p - _maxChannels = source._maxChannels - _region = source._region - _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 - _airUtilTx = source._airUtilTx - } - } - - 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._myNodeNum) }() - case 2: try { try decoder.decodeSingularBoolField(value: &_storage._hasGps_p) }() - case 4: try { try decoder.decodeSingularStringField(value: &_storage._region) }() - 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) }() - case 20: try { try decoder.decodeSingularFloatField(value: &_storage._airUtilTx) }() - 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.myNodeNum) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.hasGps_p) }() + 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 11: try { try decoder.decodeSingularFloatField(value: &self.bitrate) }() + 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) }() + case 16: try { try decoder.decodeRepeatedUInt32Field(value: &self.airPeriodTx) }() + case 17: try { try decoder.decodeRepeatedUInt32Field(value: &self.airPeriodRx) }() + case 18: try { try decoder.decodeSingularBoolField(value: &self.hasWifi_p) }() + case 19: try { try decoder.decodeSingularFloatField(value: &self.channelUtilization) }() + case 20: try { try decoder.decodeSingularFloatField(value: &self.airUtilTx) }() + default: break } } } func traverse(visitor: inout V) throws { - 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._region.isEmpty { - try visitor.visitSingularStringField(value: _storage._region, fieldNumber: 4) - } - 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) - } - if _storage._airUtilTx != 0 { - try visitor.visitSingularFloatField(value: _storage._airUtilTx, fieldNumber: 20) - } + 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.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.bitrate != 0 { + try visitor.visitSingularFloatField(value: self.bitrate, fieldNumber: 11) + } + 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) + } + if !self.airPeriodTx.isEmpty { + try visitor.visitPackedUInt32Field(value: self.airPeriodTx, fieldNumber: 16) + } + if !self.airPeriodRx.isEmpty { + try visitor.visitPackedUInt32Field(value: self.airPeriodRx, fieldNumber: 17) + } + if self.hasWifi_p != false { + try visitor.visitSingularBoolField(value: self.hasWifi_p, fieldNumber: 18) + } + if self.channelUtilization != 0 { + try visitor.visitSingularFloatField(value: self.channelUtilization, fieldNumber: 19) + } + if self.airUtilTx != 0 { + try visitor.visitSingularFloatField(value: self.airUtilTx, fieldNumber: 20) } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: MyNodeInfo, rhs: MyNodeInfo) -> 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._myNodeNum != rhs_storage._myNodeNum {return false} - if _storage._hasGps_p != rhs_storage._hasGps_p {return false} - if _storage._maxChannels != rhs_storage._maxChannels {return false} - if _storage._region != rhs_storage._region {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} - if _storage._airUtilTx != rhs_storage._airUtilTx {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs.myNodeNum != rhs.myNodeNum {return false} + if lhs.hasGps_p != rhs.hasGps_p {return false} + if lhs.maxChannels != rhs.maxChannels {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.bitrate != rhs.bitrate {return false} + if lhs.messageTimeoutMsec != rhs.messageTimeoutMsec {return false} + if lhs.minAppVersion != rhs.minAppVersion {return false} + if lhs.airPeriodTx != rhs.airPeriodTx {return false} + if lhs.airPeriodRx != rhs.airPeriodRx {return false} + if lhs.hasWifi_p != rhs.hasWifi_p {return false} + if lhs.channelUtilization != rhs.channelUtilization {return false} + if lhs.airUtilTx != rhs.airUtilTx {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -3435,127 +3347,161 @@ extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation 9: .same(proto: "rebooted"), ] + fileprivate class _StorageClass { + var _id: UInt32 = 0 + var _payloadVariant: FromRadio.OneOf_PayloadVariant? + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _id = source._id + _payloadVariant = source._payloadVariant + } + } + + 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.id) }() - case 3: try { - var v: MyNodeInfo? - var hadOneofValue = false - if let current = self.payloadVariant { - hadOneofValue = true - if case .myInfo(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.decodeSingularUInt32Field(value: &_storage._id) }() + 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 } - 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 { - // 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.id != 0 { - try visitor.visitSingularUInt32Field(value: self.id, fieldNumber: 1) - } - 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 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._id != 0 { + try visitor.visitSingularUInt32Field(value: _storage._id, 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 + } } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: FromRadio, rhs: FromRadio) -> Bool { - if lhs.id != rhs.id {return false} - if lhs.payloadVariant != rhs.payloadVariant {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._id != rhs_storage._id {return false} + if _storage._payloadVariant != rhs_storage._payloadVariant {return false} + return true + } + if !storagesAreEqual {return false} + } if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -3694,3 +3640,41 @@ extension ToRadio.PeerInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme return true } } + +extension Compressed: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = "Compressed" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "portnum"), + 2: .same(proto: "data"), + ] + + 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.decodeSingularEnumField(value: &self.portnum) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.data) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.portnum != .unknownApp { + try visitor.visitSingularEnumField(value: self.portnum, fieldNumber: 1) + } + if !self.data.isEmpty { + try visitor.visitSingularBytesField(value: self.data, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Compressed, rhs: Compressed) -> Bool { + if lhs.portnum != rhs.portnum {return false} + if lhs.data != rhs.data {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 57102fd2..db2d73bd 100644 --- a/MeshtasticClient/Protobufs/portnums.pb.swift +++ b/MeshtasticClient/Protobufs/portnums.pb.swift @@ -46,7 +46,6 @@ enum PortNum: SwiftProtobuf.Enum { /// A simple UTF-8 text message, which even the little micros in the mesh /// can understand and show on their screen eventually in some circumstances /// even signal might send messages in this form (see below) - /// Formerly called CLEAR_TEXT case textMessageApp // = 1 /// @@ -111,6 +110,10 @@ enum PortNum: SwiftProtobuf.Enum { /// Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS case zpsApp // = 68 + /// + /// Compressed payloads. + case compressionApp // = 69 + /// /// Private applications should use portnums >= 256. /// To simplify initial development and testing you can use "PRIVATE_APP" @@ -146,6 +149,7 @@ enum PortNum: SwiftProtobuf.Enum { case 66: self = .rangeTestApp case 67: self = .telemetryApp case 68: self = .zpsApp + case 69: self = .compressionApp case 256: self = .privateApp case 257: self = .atakForwarder case 511: self = .max @@ -169,6 +173,7 @@ enum PortNum: SwiftProtobuf.Enum { case .rangeTestApp: return 66 case .telemetryApp: return 67 case .zpsApp: return 68 + case .compressionApp: return 69 case .privateApp: return 256 case .atakForwarder: return 257 case .max: return 511 @@ -197,6 +202,7 @@ extension PortNum: CaseIterable { .rangeTestApp, .telemetryApp, .zpsApp, + .compressionApp, .privateApp, .atakForwarder, .max, @@ -227,6 +233,7 @@ extension PortNum: SwiftProtobuf._ProtoNameProviding { 66: .same(proto: "RANGE_TEST_APP"), 67: .same(proto: "TELEMETRY_APP"), 68: .same(proto: "ZPS_APP"), + 69: .same(proto: "COMPRESSION_APP"), 256: .same(proto: "PRIVATE_APP"), 257: .same(proto: "ATAK_FORWARDER"), 511: .same(proto: "MAX"), From e629e302d6d0e29b81ce061ee6e6a99dc5bf877f Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 24 May 2022 21:22:34 -0700 Subject: [PATCH 19/21] Remove all modifications to dates that come from the firmware. Display will be updated to show no time available for nodes without times from the mesh. --- Meshtastic Client.xcodeproj/project.pbxproj | 4 +- MeshtasticClient/Helpers/BLEManager.swift | 76 +- .../Protobufs/module_config.pb.swift | 877 ++++++++++++++++-- 3 files changed, 798 insertions(+), 159 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 8afefa09..c6e955ef 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -747,7 +747,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; @@ -779,7 +779,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 1c401b24..fec1ea2e 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -537,7 +537,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph newNode.telemetries? = NSOrderedSet(array: newTelemetries) } - // FIXME: Date from the node info, may be a bad date, needs to be fixed upstream in the firmware newNode.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.lastHeard))) newNode.snr = decodedInfo.nodeInfo.snr @@ -565,14 +564,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph position.latitudeI = decodedInfo.nodeInfo.position.latitudeI position.longitudeI = decodedInfo.nodeInfo.position.longitudeI position.altitude = decodedInfo.nodeInfo.position.altitude - - if decodedInfo.nodeInfo.position.time > 0 { - - position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time))) - } - else { - position.time = Date() - } + position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time))) var newPostions = [PositionEntity]() newPostions.append(position) @@ -598,15 +590,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph fetchedNode[0].id = Int64(decodedInfo.nodeInfo.num) fetchedNode[0].num = Int64(decodedInfo.nodeInfo.num) - - if decodedInfo.nodeInfo.lastHeard == 0 { - - fetchedNode[0].lastHeard = Date() - - } else { - - fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.lastHeard))) - } + fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.lastHeard))) fetchedNode[0].snr = decodedInfo.nodeInfo.snr if self.connectedPeripheral != nil && self.connectedPeripheral.num == fetchedNode[0].num { @@ -648,14 +632,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph position.latitudeI = decodedInfo.nodeInfo.position.latitudeI position.longitudeI = decodedInfo.nodeInfo.position.longitudeI position.altitude = decodedInfo.nodeInfo.position.altitude - - if decodedInfo.nodeInfo.position.time > 0 { - - position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time))) - } - else { - position.time = Date() - } + position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time))) let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet @@ -730,16 +707,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let newMessage = MessageEntity(context: context!) newMessage.messageId = Int64(decodedInfo.packet.id) - - - if decodedInfo.packet.rxTime == 0 { - - newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970) - - } else { - - newMessage.messageTimestamp = Int32(bitPattern: decodedInfo.packet.rxTime) - } + newMessage.messageTimestamp = Int32(bitPattern: decodedInfo.packet.rxTime) newMessage.receivedACK = false newMessage.direction = "IN" newMessage.isEmoji = decodedInfo.packet.decoded.emoji == 1 @@ -816,14 +784,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if fetchedNode.count == 1 { fetchedNode[0].id = Int64(decodedInfo.packet.from) fetchedNode[0].num = Int64(decodedInfo.packet.from) - - if decodedInfo.packet.rxTime > 0 { - fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.packet.rxTime))) - } - else { - fetchedNode[0].lastHeard = Date() - } - + fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.packet.rxTime))) fetchedNode[0].snr = decodedInfo.packet.rxSnr } else { @@ -862,15 +823,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if fetchedNode.count == 1 { fetchedNode[0].id = Int64(decodedInfo.packet.from) fetchedNode[0].num = Int64(decodedInfo.packet.from) - if decodedInfo.packet.rxTime == 0 { - - fetchedNode[0].lastHeard = Date() - - } else { - - fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.packet.rxTime))) - - } + fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.packet.rxTime))) fetchedNode[0].snr = decodedInfo.packet.rxSnr if let positionMessage = try? Position(serializedData: decodedInfo.packet.decoded.payload) { @@ -879,15 +832,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph position.latitudeI = positionMessage.latitudeI position.longitudeI = positionMessage.longitudeI position.altitude = positionMessage.altitude - - if positionMessage.time == 0 { + position.time = Date(timeIntervalSince1970: TimeInterval(Int64(positionMessage.time))) - position.time = Date() - - } else { - - position.time = Date(timeIntervalSince1970: TimeInterval(Int64(positionMessage.time))) - } let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet mutablePositions.add(position) @@ -975,15 +921,9 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if fetchedMessage != nil { - fetchedMessage!.receivedACK = true fetchedMessage!.ackSNR = decodedInfo.packet.rxSnr - if decodedInfo.packet.rxTime <= 0 { - fetchedMessage!.ackTimestamp = Int32(Date().timeIntervalSince1970) - } else { - fetchedMessage!.ackTimestamp = Int32(decodedInfo.packet.rxTime) - } - + fetchedMessage!.ackTimestamp = Int32(decodedInfo.packet.rxTime) fetchedMessage!.objectWillChange.send() } diff --git a/MeshtasticClient/Protobufs/module_config.pb.swift b/MeshtasticClient/Protobufs/module_config.pb.swift index 6a2c4041..56bf157d 100644 --- a/MeshtasticClient/Protobufs/module_config.pb.swift +++ b/MeshtasticClient/Protobufs/module_config.pb.swift @@ -33,72 +33,72 @@ struct ModuleConfig { /// /// TODO: REPLACE - var mqttConfig: ModuleConfig.MQTTConfig { + var mqtt: ModuleConfig.MQTTConfig { get { - if case .mqttConfig(let v)? = payloadVariant {return v} + if case .mqtt(let v)? = payloadVariant {return v} return ModuleConfig.MQTTConfig() } - set {payloadVariant = .mqttConfig(newValue)} + set {payloadVariant = .mqtt(newValue)} } /// /// TODO: REPLACE - var serialConfig: ModuleConfig.SerialConfig { + var serial: ModuleConfig.SerialConfig { get { - if case .serialConfig(let v)? = payloadVariant {return v} + if case .serial(let v)? = payloadVariant {return v} return ModuleConfig.SerialConfig() } - set {payloadVariant = .serialConfig(newValue)} + set {payloadVariant = .serial(newValue)} } /// /// TODO: REPLACE - var externalNotificationConfig: ModuleConfig.ExternalNotificationConfig { + var externalNotification: ModuleConfig.ExternalNotificationConfig { get { - if case .externalNotificationConfig(let v)? = payloadVariant {return v} + if case .externalNotification(let v)? = payloadVariant {return v} return ModuleConfig.ExternalNotificationConfig() } - set {payloadVariant = .externalNotificationConfig(newValue)} + set {payloadVariant = .externalNotification(newValue)} } /// /// TODO: REPLACE - var storeForwardConfig: ModuleConfig.StoreForwardConfig { + var storeForward: ModuleConfig.StoreForwardConfig { get { - if case .storeForwardConfig(let v)? = payloadVariant {return v} + if case .storeForward(let v)? = payloadVariant {return v} return ModuleConfig.StoreForwardConfig() } - set {payloadVariant = .storeForwardConfig(newValue)} + set {payloadVariant = .storeForward(newValue)} } /// /// TODO: REPLACE - var rangeTestConfig: ModuleConfig.RangeTestConfig { + var rangeTest: ModuleConfig.RangeTestConfig { get { - if case .rangeTestConfig(let v)? = payloadVariant {return v} + if case .rangeTest(let v)? = payloadVariant {return v} return ModuleConfig.RangeTestConfig() } - set {payloadVariant = .rangeTestConfig(newValue)} + set {payloadVariant = .rangeTest(newValue)} } /// /// TODO: REPLACE - var telemetryConfig: ModuleConfig.TelemetryConfig { + var telemetry: ModuleConfig.TelemetryConfig { get { - if case .telemetryConfig(let v)? = payloadVariant {return v} + if case .telemetry(let v)? = payloadVariant {return v} return ModuleConfig.TelemetryConfig() } - set {payloadVariant = .telemetryConfig(newValue)} + set {payloadVariant = .telemetry(newValue)} } /// /// TODO: REPLACE - var cannedMessageConfig: ModuleConfig.CannedMessageConfig { + var cannedMessage: ModuleConfig.CannedMessageConfig { get { - if case .cannedMessageConfig(let v)? = payloadVariant {return v} + if case .cannedMessage(let v)? = payloadVariant {return v} return ModuleConfig.CannedMessageConfig() } - set {payloadVariant = .cannedMessageConfig(newValue)} + set {payloadVariant = .cannedMessage(newValue)} } var unknownFields = SwiftProtobuf.UnknownStorage() @@ -108,25 +108,25 @@ struct ModuleConfig { enum OneOf_PayloadVariant: Equatable { /// /// TODO: REPLACE - case mqttConfig(ModuleConfig.MQTTConfig) + case mqtt(ModuleConfig.MQTTConfig) /// /// TODO: REPLACE - case serialConfig(ModuleConfig.SerialConfig) + case serial(ModuleConfig.SerialConfig) /// /// TODO: REPLACE - case externalNotificationConfig(ModuleConfig.ExternalNotificationConfig) + case externalNotification(ModuleConfig.ExternalNotificationConfig) /// /// TODO: REPLACE - case storeForwardConfig(ModuleConfig.StoreForwardConfig) + case storeForward(ModuleConfig.StoreForwardConfig) /// /// TODO: REPLACE - case rangeTestConfig(ModuleConfig.RangeTestConfig) + case rangeTest(ModuleConfig.RangeTestConfig) /// /// TODO: REPLACE - case telemetryConfig(ModuleConfig.TelemetryConfig) + case telemetry(ModuleConfig.TelemetryConfig) /// /// TODO: REPLACE - case cannedMessageConfig(ModuleConfig.CannedMessageConfig) + case cannedMessage(ModuleConfig.CannedMessageConfig) #if !swift(>=4.1) static func ==(lhs: ModuleConfig.OneOf_PayloadVariant, rhs: ModuleConfig.OneOf_PayloadVariant) -> Bool { @@ -134,32 +134,32 @@ struct ModuleConfig { // allocates stack space for every case branch when no optimizations are // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch (lhs, rhs) { - case (.mqttConfig, .mqttConfig): return { - guard case .mqttConfig(let l) = lhs, case .mqttConfig(let r) = rhs else { preconditionFailure() } + case (.mqtt, .mqtt): return { + guard case .mqtt(let l) = lhs, case .mqtt(let r) = rhs else { preconditionFailure() } return l == r }() - case (.serialConfig, .serialConfig): return { - guard case .serialConfig(let l) = lhs, case .serialConfig(let r) = rhs else { preconditionFailure() } + case (.serial, .serial): return { + guard case .serial(let l) = lhs, case .serial(let r) = rhs else { preconditionFailure() } return l == r }() - case (.externalNotificationConfig, .externalNotificationConfig): return { - guard case .externalNotificationConfig(let l) = lhs, case .externalNotificationConfig(let r) = rhs else { preconditionFailure() } + case (.externalNotification, .externalNotification): return { + guard case .externalNotification(let l) = lhs, case .externalNotification(let r) = rhs else { preconditionFailure() } return l == r }() - case (.storeForwardConfig, .storeForwardConfig): return { - guard case .storeForwardConfig(let l) = lhs, case .storeForwardConfig(let r) = rhs else { preconditionFailure() } + case (.storeForward, .storeForward): return { + guard case .storeForward(let l) = lhs, case .storeForward(let r) = rhs else { preconditionFailure() } return l == r }() - case (.rangeTestConfig, .rangeTestConfig): return { - guard case .rangeTestConfig(let l) = lhs, case .rangeTestConfig(let r) = rhs else { preconditionFailure() } + case (.rangeTest, .rangeTest): return { + guard case .rangeTest(let l) = lhs, case .rangeTest(let r) = rhs else { preconditionFailure() } return l == r }() - case (.telemetryConfig, .telemetryConfig): return { - guard case .telemetryConfig(let l) = lhs, case .telemetryConfig(let r) = rhs else { preconditionFailure() } + case (.telemetry, .telemetry): return { + guard case .telemetry(let l) = lhs, case .telemetry(let r) = rhs else { preconditionFailure() } return l == r }() - case (.cannedMessageConfig, .cannedMessageConfig): return { - guard case .cannedMessageConfig(let l) = lhs, case .cannedMessageConfig(let r) = rhs else { preconditionFailure() } + case (.cannedMessage, .cannedMessage): return { + guard case .cannedMessage(let l) = lhs, case .cannedMessage(let r) = rhs else { preconditionFailure() } return l == r }() default: return false @@ -175,6 +175,36 @@ struct ModuleConfig { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// If a meshtastic node is able to reach the internet it will normally attempt to gateway any channels that are marked as + /// is_uplink_enabled or is_downlink_enabled. + /// But if this flag is set, all MQTT features will be disabled and no servers will be contacted. + var disabled: Bool = false + + /// + /// The server to use for our MQTT global message gateway feature. + /// If not set, the default server will be used + var address: String = String() + + /// + /// 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 username: String = String() + + /// + /// 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 password: String = String() + + /// + /// Whether to send encrypted or decrypted packets to MQTT. + /// This parameter is only honoured if you also set server + /// (the default official mqtt.meshtastic.org server can handle encrypted packets) + /// Decrypted packets may be useful for external systems that want to consume meshtastic packets + var encryptionEnabled: Bool = false + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -187,8 +217,142 @@ struct ModuleConfig { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// Preferences for the SerialModule + /// FIXME - Move this out of UserPreferences and into a section for module configuration. + var enabled: Bool = false + + /// + /// TODO: REPLACE + var echo: Bool = false + + /// + /// TODO: REPLACE + var rxd: UInt32 = 0 + + /// + /// TODO: REPLACE + var txd: UInt32 = 0 + + /// + /// TODO: REPLACE + var baud: ModuleConfig.SerialConfig.Serial_Baud = .baudDefault + + /// + /// TODO: REPLACE + var timeout: UInt32 = 0 + + /// + /// TODO: REPLACE + var mode: ModuleConfig.SerialConfig.Serial_Mode = .modeDefault + var unknownFields = SwiftProtobuf.UnknownStorage() + /// + /// TODO: REPLACE + enum Serial_Baud: SwiftProtobuf.Enum { + typealias RawValue = Int + case baudDefault // = 0 + case baud2400 // = 1 + case baud4800 // = 2 + case baud9600 // = 3 + case baud19200 // = 4 + case baud38400 // = 5 + case baud57600 // = 6 + case baud115200 // = 7 + case baud230400 // = 8 + case baud460800 // = 9 + case baud576000 // = 10 + case baud921600 // = 11 + case baud110 // = 12 + case baud300 // = 13 + case baud600 // = 14 + case baud1200 // = 15 + case UNRECOGNIZED(Int) + + init() { + self = .baudDefault + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .baudDefault + case 1: self = .baud2400 + case 2: self = .baud4800 + case 3: self = .baud9600 + case 4: self = .baud19200 + case 5: self = .baud38400 + case 6: self = .baud57600 + case 7: self = .baud115200 + case 8: self = .baud230400 + case 9: self = .baud460800 + case 10: self = .baud576000 + case 11: self = .baud921600 + case 12: self = .baud110 + case 13: self = .baud300 + case 14: self = .baud600 + case 15: self = .baud1200 + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .baudDefault: return 0 + case .baud2400: return 1 + case .baud4800: return 2 + case .baud9600: return 3 + case .baud19200: return 4 + case .baud38400: return 5 + case .baud57600: return 6 + case .baud115200: return 7 + case .baud230400: return 8 + case .baud460800: return 9 + case .baud576000: return 10 + case .baud921600: return 11 + case .baud110: return 12 + case .baud300: return 13 + case .baud600: return 14 + case .baud1200: return 15 + case .UNRECOGNIZED(let i): return i + } + } + + } + + /// + /// TODO: REPLACE + enum Serial_Mode: SwiftProtobuf.Enum { + typealias RawValue = Int + case modeDefault // = 0 + case modeSimple // = 1 + case modeProto // = 2 + case UNRECOGNIZED(Int) + + init() { + self = .modeDefault + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .modeDefault + case 1: self = .modeSimple + case 2: self = .modeProto + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .modeDefault: return 0 + case .modeSimple: return 1 + case .modeProto: return 2 + case .UNRECOGNIZED(let i): return i + } + } + + } + init() {} } @@ -199,6 +363,31 @@ struct ModuleConfig { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// Preferences for the ExternalNotificationModule + /// FIXME - Move this out of UserPreferences and into a section for module configuration. + var enabled: Bool = false + + /// + /// TODO: REPLACE + var outputMs: UInt32 = 0 + + /// + /// TODO: REPLACE + var output: UInt32 = 0 + + /// + /// TODO: REPLACE + var active: Bool = false + + /// + /// TODO: REPLACE + var alertMessage: Bool = false + + /// + /// TODO: REPLACE + var alertBell: Bool = false + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -211,6 +400,27 @@ struct ModuleConfig { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// Preferences for the StoreForwardModule + ///FIXME - Move this out of UserPreferences and into a section for module configuration. (was 136) + var enabled: Bool = false + + /// + /// TODO: REPLACE + var heartbeat: Bool = false + + /// + /// TODO: REPLACE + var records: UInt32 = 0 + + /// + /// TODO: REPLACE + var historyReturnMax: UInt32 = 0 + + /// + /// TODO: REPLACE + var historyReturnWindow: UInt32 = 0 + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -223,6 +433,19 @@ struct ModuleConfig { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// Preferences for the RangeTestModule + /// FIXME - Move this out of UserPreferences and into a section for module configuration. + var enabled: Bool = false + + /// + /// TODO: REPLACE + var sender: UInt32 = 0 + + /// + /// TODO: REPLACE + var save: Bool = false + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -288,24 +511,194 @@ struct ModuleConfig { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. + /// + /// Enable the rotary encoder #1. This is a 'dumb' encoder sending pulses on both A and B pins while rotating. + var rotary1Enabled: Bool = false + + /// + /// GPIO pin for rotary encoder A port. + var inputbrokerPinA: UInt32 = 0 + + /// + /// GPIO pin for rotary encoder B port. + var inputbrokerPinB: UInt32 = 0 + + /// + /// GPIO pin for rotary encoder Press port. + var inputbrokerPinPress: UInt32 = 0 + + /// + /// Generate input event on CW of this kind. + var inputbrokerEventCw: ModuleConfig.CannedMessageConfig.InputEventChar = .keyNone + + /// + /// Generate input event on CCW of this kind. + var inputbrokerEventCcw: ModuleConfig.CannedMessageConfig.InputEventChar = .keyNone + + /// + /// Generate input event on Press of this kind. + var inputbrokerEventPress: ModuleConfig.CannedMessageConfig.InputEventChar = .keyNone + + /// + /// Enable the Up/Down/Select input device. Can be RAK rotary encoder or 3 buttons. Uses the a/b/press definitions from inputbroker. + var updown1Enabled: Bool = false + + /// + /// Enable/disable CannedMessageModule. + var enabled: Bool = false + + /// + /// Input event origin accepted by the canned message module. + /// Can be e.g. "rotEnc1", "upDownEnc1" or keyword "_any" + var allowInputSource: String = String() + + /// + /// CannedMessageModule also sends a bell character with the messages. + /// ExternalNotificationModule can benefit from this feature. + var sendBell: Bool = false + var unknownFields = SwiftProtobuf.UnknownStorage() + /// + /// TODO: REPLACE + enum InputEventChar: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// TODO: REPLACE + case keyNone // = 0 + + /// + /// TODO: REPLACE + case keyUp // = 17 + + /// + /// TODO: REPLACE + case keyDown // = 18 + + /// + /// TODO: REPLACE + case keyLeft // = 19 + + /// + /// TODO: REPLACE + case keyRight // = 20 + + /// + /// '\n' + case keySelect // = 10 + + /// + /// TODO: REPLACE + case keyBack // = 27 + + /// + /// TODO: REPLACE + case keyCancel // = 24 + case UNRECOGNIZED(Int) + + init() { + self = .keyNone + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .keyNone + case 10: self = .keySelect + case 17: self = .keyUp + case 18: self = .keyDown + case 19: self = .keyLeft + case 20: self = .keyRight + case 24: self = .keyCancel + case 27: self = .keyBack + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .keyNone: return 0 + case .keySelect: return 10 + case .keyUp: return 17 + case .keyDown: return 18 + case .keyLeft: return 19 + case .keyRight: return 20 + case .keyCancel: return 24 + case .keyBack: return 27 + case .UNRECOGNIZED(let i): return i + } + } + + } + init() {} } init() {} } +#if swift(>=4.2) + +extension ModuleConfig.SerialConfig.Serial_Baud: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [ModuleConfig.SerialConfig.Serial_Baud] = [ + .baudDefault, + .baud2400, + .baud4800, + .baud9600, + .baud19200, + .baud38400, + .baud57600, + .baud115200, + .baud230400, + .baud460800, + .baud576000, + .baud921600, + .baud110, + .baud300, + .baud600, + .baud1200, + ] +} + +extension ModuleConfig.SerialConfig.Serial_Mode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [ModuleConfig.SerialConfig.Serial_Mode] = [ + .modeDefault, + .modeSimple, + .modeProto, + ] +} + +extension ModuleConfig.CannedMessageConfig.InputEventChar: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [ModuleConfig.CannedMessageConfig.InputEventChar] = [ + .keyNone, + .keyUp, + .keyDown, + .keyLeft, + .keyRight, + .keySelect, + .keyBack, + .keyCancel, + ] +} + +#endif // swift(>=4.2) + #if swift(>=5.5) && canImport(_Concurrency) extension ModuleConfig: @unchecked Sendable {} extension ModuleConfig.OneOf_PayloadVariant: @unchecked Sendable {} extension ModuleConfig.MQTTConfig: @unchecked Sendable {} extension ModuleConfig.SerialConfig: @unchecked Sendable {} +extension ModuleConfig.SerialConfig.Serial_Baud: @unchecked Sendable {} +extension ModuleConfig.SerialConfig.Serial_Mode: @unchecked Sendable {} extension ModuleConfig.ExternalNotificationConfig: @unchecked Sendable {} extension ModuleConfig.StoreForwardConfig: @unchecked Sendable {} extension ModuleConfig.RangeTestConfig: @unchecked Sendable {} extension ModuleConfig.TelemetryConfig: @unchecked Sendable {} extension ModuleConfig.CannedMessageConfig: @unchecked Sendable {} +extension ModuleConfig.CannedMessageConfig.InputEventChar: @unchecked Sendable {} #endif // swift(>=5.5) && canImport(_Concurrency) // MARK: - Code below here is support for the SwiftProtobuf runtime. @@ -313,13 +706,13 @@ extension ModuleConfig.CannedMessageConfig: @unchecked Sendable {} extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "ModuleConfig" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "mqtt_config"), - 2: .standard(proto: "serial_config"), - 3: .standard(proto: "external_notification_config"), - 4: .standard(proto: "store_forward_config"), - 5: .standard(proto: "range_test_config"), - 6: .standard(proto: "telemetry_config"), - 7: .standard(proto: "canned_message_config"), + 1: .same(proto: "mqtt"), + 2: .same(proto: "serial"), + 3: .standard(proto: "external_notification"), + 4: .standard(proto: "store_forward"), + 5: .standard(proto: "range_test"), + 6: .same(proto: "telemetry"), + 7: .standard(proto: "canned_message"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -333,12 +726,12 @@ extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .mqttConfig(let m) = current {v = m} + if case .mqtt(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .mqttConfig(v) + self.payloadVariant = .mqtt(v) } }() case 2: try { @@ -346,12 +739,12 @@ extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .serialConfig(let m) = current {v = m} + if case .serial(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .serialConfig(v) + self.payloadVariant = .serial(v) } }() case 3: try { @@ -359,12 +752,12 @@ extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .externalNotificationConfig(let m) = current {v = m} + if case .externalNotification(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .externalNotificationConfig(v) + self.payloadVariant = .externalNotification(v) } }() case 4: try { @@ -372,12 +765,12 @@ extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .storeForwardConfig(let m) = current {v = m} + if case .storeForward(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .storeForwardConfig(v) + self.payloadVariant = .storeForward(v) } }() case 5: try { @@ -385,12 +778,12 @@ extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .rangeTestConfig(let m) = current {v = m} + if case .rangeTest(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .rangeTestConfig(v) + self.payloadVariant = .rangeTest(v) } }() case 6: try { @@ -398,12 +791,12 @@ extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .telemetryConfig(let m) = current {v = m} + if case .telemetry(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .telemetryConfig(v) + self.payloadVariant = .telemetry(v) } }() case 7: try { @@ -411,12 +804,12 @@ extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat var hadOneofValue = false if let current = self.payloadVariant { hadOneofValue = true - if case .cannedMessageConfig(let m) = current {v = m} + if case .cannedMessage(let m) = current {v = m} } try decoder.decodeSingularMessageField(value: &v) if let v = v { if hadOneofValue {try decoder.handleConflictingOneOf()} - self.payloadVariant = .cannedMessageConfig(v) + self.payloadVariant = .cannedMessage(v) } }() default: break @@ -430,32 +823,32 @@ extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and // https://github.com/apple/swift-protobuf/issues/1182 switch self.payloadVariant { - case .mqttConfig?: try { - guard case .mqttConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .mqtt?: try { + guard case .mqtt(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 1) }() - case .serialConfig?: try { - guard case .serialConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .serial?: try { + guard case .serial(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 2) }() - case .externalNotificationConfig?: try { - guard case .externalNotificationConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .externalNotification?: try { + guard case .externalNotification(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 3) }() - case .storeForwardConfig?: try { - guard case .storeForwardConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .storeForward?: try { + guard case .storeForward(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 4) }() - case .rangeTestConfig?: try { - guard case .rangeTestConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .rangeTest?: try { + guard case .rangeTest(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 5) }() - case .telemetryConfig?: try { - guard case .telemetryConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .telemetry?: try { + guard case .telemetry(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 6) }() - case .cannedMessageConfig?: try { - guard case .cannedMessageConfig(let v)? = self.payloadVariant else { preconditionFailure() } + case .cannedMessage?: try { + guard case .cannedMessage(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 7) }() case nil: break @@ -472,18 +865,55 @@ extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat extension ModuleConfig.MQTTConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = ModuleConfig.protoMessageName + ".MQTTConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "disabled"), + 2: .same(proto: "address"), + 3: .same(proto: "username"), + 4: .same(proto: "password"), + 5: .standard(proto: "encryption_enabled"), + ] mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { + 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.decodeSingularBoolField(value: &self.disabled) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.address) }() + case 3: try { try decoder.decodeSingularStringField(value: &self.username) }() + case 4: try { try decoder.decodeSingularStringField(value: &self.password) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self.encryptionEnabled) }() + default: break + } } } func traverse(visitor: inout V) throws { + if self.disabled != false { + try visitor.visitSingularBoolField(value: self.disabled, fieldNumber: 1) + } + if !self.address.isEmpty { + try visitor.visitSingularStringField(value: self.address, fieldNumber: 2) + } + if !self.username.isEmpty { + try visitor.visitSingularStringField(value: self.username, fieldNumber: 3) + } + if !self.password.isEmpty { + try visitor.visitSingularStringField(value: self.password, fieldNumber: 4) + } + if self.encryptionEnabled != false { + try visitor.visitSingularBoolField(value: self.encryptionEnabled, fieldNumber: 5) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: ModuleConfig.MQTTConfig, rhs: ModuleConfig.MQTTConfig) -> Bool { + if lhs.disabled != rhs.disabled {return false} + if lhs.address != rhs.address {return false} + if lhs.username != rhs.username {return false} + if lhs.password != rhs.password {return false} + if lhs.encryptionEnabled != rhs.encryptionEnabled {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -491,37 +921,158 @@ extension ModuleConfig.MQTTConfig: SwiftProtobuf.Message, SwiftProtobuf._Message extension ModuleConfig.SerialConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = ModuleConfig.protoMessageName + ".SerialConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "enabled"), + 2: .same(proto: "echo"), + 3: .same(proto: "rxd"), + 4: .same(proto: "txd"), + 5: .same(proto: "baud"), + 6: .same(proto: "timeout"), + 7: .same(proto: "mode"), + ] mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { + 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.decodeSingularBoolField(value: &self.enabled) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.echo) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self.rxd) }() + case 4: try { try decoder.decodeSingularUInt32Field(value: &self.txd) }() + case 5: try { try decoder.decodeSingularEnumField(value: &self.baud) }() + case 6: try { try decoder.decodeSingularUInt32Field(value: &self.timeout) }() + case 7: try { try decoder.decodeSingularEnumField(value: &self.mode) }() + default: break + } } } func traverse(visitor: inout V) throws { + if self.enabled != false { + try visitor.visitSingularBoolField(value: self.enabled, fieldNumber: 1) + } + if self.echo != false { + try visitor.visitSingularBoolField(value: self.echo, fieldNumber: 2) + } + if self.rxd != 0 { + try visitor.visitSingularUInt32Field(value: self.rxd, fieldNumber: 3) + } + if self.txd != 0 { + try visitor.visitSingularUInt32Field(value: self.txd, fieldNumber: 4) + } + if self.baud != .baudDefault { + try visitor.visitSingularEnumField(value: self.baud, fieldNumber: 5) + } + if self.timeout != 0 { + try visitor.visitSingularUInt32Field(value: self.timeout, fieldNumber: 6) + } + if self.mode != .modeDefault { + try visitor.visitSingularEnumField(value: self.mode, fieldNumber: 7) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: ModuleConfig.SerialConfig, rhs: ModuleConfig.SerialConfig) -> Bool { + if lhs.enabled != rhs.enabled {return false} + if lhs.echo != rhs.echo {return false} + if lhs.rxd != rhs.rxd {return false} + if lhs.txd != rhs.txd {return false} + if lhs.baud != rhs.baud {return false} + if lhs.timeout != rhs.timeout {return false} + if lhs.mode != rhs.mode {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } } +extension ModuleConfig.SerialConfig.Serial_Baud: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "BAUD_Default"), + 1: .same(proto: "BAUD_2400"), + 2: .same(proto: "BAUD_4800"), + 3: .same(proto: "BAUD_9600"), + 4: .same(proto: "BAUD_19200"), + 5: .same(proto: "BAUD_38400"), + 6: .same(proto: "BAUD_57600"), + 7: .same(proto: "BAUD_115200"), + 8: .same(proto: "BAUD_230400"), + 9: .same(proto: "BAUD_460800"), + 10: .same(proto: "BAUD_576000"), + 11: .same(proto: "BAUD_921600"), + 12: .same(proto: "BAUD_110"), + 13: .same(proto: "BAUD_300"), + 14: .same(proto: "BAUD_600"), + 15: .same(proto: "BAUD_1200"), + ] +} + +extension ModuleConfig.SerialConfig.Serial_Mode: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "MODE_Default"), + 1: .same(proto: "MODE_SIMPLE"), + 2: .same(proto: "MODE_PROTO"), + ] +} + extension ModuleConfig.ExternalNotificationConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = ModuleConfig.protoMessageName + ".ExternalNotificationConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "enabled"), + 2: .standard(proto: "output_ms"), + 3: .same(proto: "output"), + 4: .same(proto: "active"), + 5: .standard(proto: "alert_message"), + 6: .standard(proto: "alert_bell"), + ] mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { + 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.decodeSingularBoolField(value: &self.enabled) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.outputMs) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self.output) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self.active) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self.alertMessage) }() + case 6: try { try decoder.decodeSingularBoolField(value: &self.alertBell) }() + default: break + } } } func traverse(visitor: inout V) throws { + if self.enabled != false { + try visitor.visitSingularBoolField(value: self.enabled, fieldNumber: 1) + } + if self.outputMs != 0 { + try visitor.visitSingularUInt32Field(value: self.outputMs, fieldNumber: 2) + } + if self.output != 0 { + try visitor.visitSingularUInt32Field(value: self.output, fieldNumber: 3) + } + if self.active != false { + try visitor.visitSingularBoolField(value: self.active, fieldNumber: 4) + } + if self.alertMessage != false { + try visitor.visitSingularBoolField(value: self.alertMessage, fieldNumber: 5) + } + if self.alertBell != false { + try visitor.visitSingularBoolField(value: self.alertBell, fieldNumber: 6) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: ModuleConfig.ExternalNotificationConfig, rhs: ModuleConfig.ExternalNotificationConfig) -> Bool { + if lhs.enabled != rhs.enabled {return false} + if lhs.outputMs != rhs.outputMs {return false} + if lhs.output != rhs.output {return false} + if lhs.active != rhs.active {return false} + if lhs.alertMessage != rhs.alertMessage {return false} + if lhs.alertBell != rhs.alertBell {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -529,18 +1080,55 @@ extension ModuleConfig.ExternalNotificationConfig: SwiftProtobuf.Message, SwiftP extension ModuleConfig.StoreForwardConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = ModuleConfig.protoMessageName + ".StoreForwardConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "enabled"), + 2: .same(proto: "heartbeat"), + 3: .same(proto: "records"), + 4: .standard(proto: "history_return_max"), + 5: .standard(proto: "history_return_window"), + ] mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { + 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.decodeSingularBoolField(value: &self.enabled) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.heartbeat) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self.records) }() + case 4: try { try decoder.decodeSingularUInt32Field(value: &self.historyReturnMax) }() + case 5: try { try decoder.decodeSingularUInt32Field(value: &self.historyReturnWindow) }() + default: break + } } } func traverse(visitor: inout V) throws { + if self.enabled != false { + try visitor.visitSingularBoolField(value: self.enabled, fieldNumber: 1) + } + if self.heartbeat != false { + try visitor.visitSingularBoolField(value: self.heartbeat, fieldNumber: 2) + } + if self.records != 0 { + try visitor.visitSingularUInt32Field(value: self.records, fieldNumber: 3) + } + if self.historyReturnMax != 0 { + try visitor.visitSingularUInt32Field(value: self.historyReturnMax, fieldNumber: 4) + } + if self.historyReturnWindow != 0 { + try visitor.visitSingularUInt32Field(value: self.historyReturnWindow, fieldNumber: 5) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: ModuleConfig.StoreForwardConfig, rhs: ModuleConfig.StoreForwardConfig) -> Bool { + if lhs.enabled != rhs.enabled {return false} + if lhs.heartbeat != rhs.heartbeat {return false} + if lhs.records != rhs.records {return false} + if lhs.historyReturnMax != rhs.historyReturnMax {return false} + if lhs.historyReturnWindow != rhs.historyReturnWindow {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -548,18 +1136,43 @@ extension ModuleConfig.StoreForwardConfig: SwiftProtobuf.Message, SwiftProtobuf. extension ModuleConfig.RangeTestConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = ModuleConfig.protoMessageName + ".RangeTestConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "enabled"), + 2: .same(proto: "sender"), + 3: .same(proto: "save"), + ] mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { + 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.decodeSingularBoolField(value: &self.enabled) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.sender) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.save) }() + default: break + } } } func traverse(visitor: inout V) throws { + if self.enabled != false { + try visitor.visitSingularBoolField(value: self.enabled, fieldNumber: 1) + } + if self.sender != 0 { + try visitor.visitSingularUInt32Field(value: self.sender, fieldNumber: 2) + } + if self.save != false { + try visitor.visitSingularBoolField(value: self.save, fieldNumber: 3) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: ModuleConfig.RangeTestConfig, rhs: ModuleConfig.RangeTestConfig) -> Bool { + if lhs.enabled != rhs.enabled {return false} + if lhs.sender != rhs.sender {return false} + if lhs.save != rhs.save {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -647,19 +1260,105 @@ extension ModuleConfig.TelemetryConfig: SwiftProtobuf.Message, SwiftProtobuf._Me extension ModuleConfig.CannedMessageConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = ModuleConfig.protoMessageName + ".CannedMessageConfig" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "rotary1_enabled"), + 2: .standard(proto: "inputbroker_pin_a"), + 3: .standard(proto: "inputbroker_pin_b"), + 4: .standard(proto: "inputbroker_pin_press"), + 5: .standard(proto: "inputbroker_event_cw"), + 6: .standard(proto: "inputbroker_event_ccw"), + 7: .standard(proto: "inputbroker_event_press"), + 8: .standard(proto: "updown1_enabled"), + 9: .same(proto: "enabled"), + 10: .standard(proto: "allow_input_source"), + 11: .standard(proto: "send_bell"), + ] mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { + 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.decodeSingularBoolField(value: &self.rotary1Enabled) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.inputbrokerPinA) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self.inputbrokerPinB) }() + case 4: try { try decoder.decodeSingularUInt32Field(value: &self.inputbrokerPinPress) }() + case 5: try { try decoder.decodeSingularEnumField(value: &self.inputbrokerEventCw) }() + case 6: try { try decoder.decodeSingularEnumField(value: &self.inputbrokerEventCcw) }() + case 7: try { try decoder.decodeSingularEnumField(value: &self.inputbrokerEventPress) }() + case 8: try { try decoder.decodeSingularBoolField(value: &self.updown1Enabled) }() + case 9: try { try decoder.decodeSingularBoolField(value: &self.enabled) }() + case 10: try { try decoder.decodeSingularStringField(value: &self.allowInputSource) }() + case 11: try { try decoder.decodeSingularBoolField(value: &self.sendBell) }() + default: break + } } } func traverse(visitor: inout V) throws { + if self.rotary1Enabled != false { + try visitor.visitSingularBoolField(value: self.rotary1Enabled, fieldNumber: 1) + } + if self.inputbrokerPinA != 0 { + try visitor.visitSingularUInt32Field(value: self.inputbrokerPinA, fieldNumber: 2) + } + if self.inputbrokerPinB != 0 { + try visitor.visitSingularUInt32Field(value: self.inputbrokerPinB, fieldNumber: 3) + } + if self.inputbrokerPinPress != 0 { + try visitor.visitSingularUInt32Field(value: self.inputbrokerPinPress, fieldNumber: 4) + } + if self.inputbrokerEventCw != .keyNone { + try visitor.visitSingularEnumField(value: self.inputbrokerEventCw, fieldNumber: 5) + } + if self.inputbrokerEventCcw != .keyNone { + try visitor.visitSingularEnumField(value: self.inputbrokerEventCcw, fieldNumber: 6) + } + if self.inputbrokerEventPress != .keyNone { + try visitor.visitSingularEnumField(value: self.inputbrokerEventPress, fieldNumber: 7) + } + if self.updown1Enabled != false { + try visitor.visitSingularBoolField(value: self.updown1Enabled, fieldNumber: 8) + } + if self.enabled != false { + try visitor.visitSingularBoolField(value: self.enabled, fieldNumber: 9) + } + if !self.allowInputSource.isEmpty { + try visitor.visitSingularStringField(value: self.allowInputSource, fieldNumber: 10) + } + if self.sendBell != false { + try visitor.visitSingularBoolField(value: self.sendBell, fieldNumber: 11) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: ModuleConfig.CannedMessageConfig, rhs: ModuleConfig.CannedMessageConfig) -> Bool { + if lhs.rotary1Enabled != rhs.rotary1Enabled {return false} + if lhs.inputbrokerPinA != rhs.inputbrokerPinA {return false} + if lhs.inputbrokerPinB != rhs.inputbrokerPinB {return false} + if lhs.inputbrokerPinPress != rhs.inputbrokerPinPress {return false} + if lhs.inputbrokerEventCw != rhs.inputbrokerEventCw {return false} + if lhs.inputbrokerEventCcw != rhs.inputbrokerEventCcw {return false} + if lhs.inputbrokerEventPress != rhs.inputbrokerEventPress {return false} + if lhs.updown1Enabled != rhs.updown1Enabled {return false} + if lhs.enabled != rhs.enabled {return false} + if lhs.allowInputSource != rhs.allowInputSource {return false} + if lhs.sendBell != rhs.sendBell {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } } + +extension ModuleConfig.CannedMessageConfig.InputEventChar: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "KEY_NONE"), + 10: .same(proto: "KEY_SELECT"), + 17: .same(proto: "KEY_UP"), + 18: .same(proto: "KEY_DOWN"), + 19: .same(proto: "KEY_LEFT"), + 20: .same(proto: "KEY_RIGHT"), + 24: .same(proto: "KEY_CANCEL"), + 27: .same(proto: "KEY_BACK"), + ] +} From 233fb0a1e060ddb596e36daf0d1c5c557d325502 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 25 May 2022 22:30:48 -0700 Subject: [PATCH 20/21] Display time only from mesh, remove all times set in the iOS app. Add Bitrate Format assorted things. Fix battery display on node details make node list more friendly on iPad and mac --- Meshtastic Client.xcodeproj/project.pbxproj | 4 ++ MeshtasticClient/Helpers/BLEManager.swift | 8 +++- MeshtasticClient/Model/PeripheralModel.swift | 4 +- .../Views/Bluetooth/Connect.swift | 8 +++- .../Views/Helpers/LastHeardText.swift | 22 ++++++++++ MeshtasticClient/Views/Nodes/NodeDetail.swift | 33 ++++++++++----- MeshtasticClient/Views/Nodes/NodeList.swift | 42 +++++++------------ 7 files changed, 78 insertions(+), 43 deletions(-) create mode 100644 MeshtasticClient/Views/Helpers/LastHeardText.swift diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index c6e955ef..38d87e76 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -55,6 +55,7 @@ DDC2E17A26CE248F0042C5E4 /* MeshtasticClientUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E17926CE248F0042C5E4 /* MeshtasticClientUITests.swift */; }; DDC2E18F26CE25FE0042C5E4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */; }; DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */; }; + DDC3B274283F411B00AC321C /* LastHeardText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC3B273283F411B00AC321C /* LastHeardText.swift */; }; DDC4D568275499A500A4208E /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC4D567275499A500A4208E /* Persistence.swift */; }; DDCA31322826009C00207175 /* PassKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDCA31312826009C00207175 /* PassKit.framework */; }; DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF924C926FBB953009FE055 /* ConnectedDevice.swift */; }; @@ -133,6 +134,7 @@ DDC2E17B26CE248F0042C5E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationHelper.swift; sourceTree = ""; }; + DDC3B273283F411B00AC321C /* LastHeardText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastHeardText.swift; sourceTree = ""; }; DDC4D567275499A500A4208E /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; DDCA31312826009C00207175 /* PassKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PassKit.framework; path = System/Library/Frameworks/PassKit.framework; sourceTree = SDKROOT; }; DDF924C926FBB953009FE055 /* ConnectedDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectedDevice.swift; sourceTree = ""; }; @@ -356,6 +358,7 @@ DD47E3D826F3093800029299 /* MessageBubble.swift */, DD90860B26F684AF00DC5189 /* BatteryIcon.swift */, DDF924C926FBB953009FE055 /* ConnectedDevice.swift */, + DDC3B273283F411B00AC321C /* LastHeardText.swift */, ); path = Helpers; sourceTree = ""; @@ -574,6 +577,7 @@ C9483F6D2773017500998F6B /* MapView.swift in Sources */, DDAF8C5826ED07FD0058C060 /* mesh.pb.swift in Sources */, DD8169FB271F1F3A00F4AB02 /* MeshLog.swift in Sources */, + DDC3B274283F411B00AC321C /* LastHeardText.swift in Sources */, DD2E65262767A01F00E45FC5 /* NodeDetail.swift in Sources */, C9A88B57278B559900BD810A /* apponly.pb.swift in Sources */, DD4C158E2824AA7E0032668E /* config.pb.swift in Sources */, diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index fec1ea2e..0ff0cb9d 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -176,7 +176,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph peripheralName = name } - let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: String(peripheralName.suffix(3)), longName: peripheralName, firmwareVersion: "Unknown", rssi: RSSI.intValue, channelUtilization: nil, airTime: nil, lastUpdate: Date(), subscribed: false, peripheral: peripheral) + let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: String(peripheralName.suffix(3)), longName: peripheralName, firmwareVersion: "Unknown", rssi: RSSI.intValue, bitrate: nil, channelUtilization: nil, airTime: nil, lastUpdate: Date(), subscribed: false, peripheral: peripheral) let peripheralIndex = peripherals.firstIndex(where: { $0.id == newPeripheral.id }) if peripheralIndex != nil && newPeripheral.peripheral.state != CBPeripheralState.connected { @@ -407,6 +407,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph myInfo.myNodeNum = Int64(decodedInfo.myInfo.myNodeNum) myInfo.hasGps = decodedInfo.myInfo.hasGps_p myInfo.bitrate = decodedInfo.myInfo.bitrate + self.connectedPeripheral.bitrate = myInfo.bitrate // Swift does strings weird, this does work to get the version without the github hash let lastDotIndex = decodedInfo.myInfo.firmwareVersion.lastIndex(of: ".") @@ -460,6 +461,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph fetchedMyInfo[0].myNodeNum = Int64(decodedInfo.myInfo.myNodeNum) fetchedMyInfo[0].hasGps = decodedInfo.myInfo.hasGps_p + fetchedMyInfo[0].bitrate = decodedInfo.myInfo.bitrate + let lastDotIndex = decodedInfo.myInfo.firmwareVersion.lastIndex(of: ".")//.lastIndex(of: ".", offsetBy: -1) var version = decodedInfo.myInfo.firmwareVersion[...(lastDotIndex ?? String.Index(utf16Offset:6, in: decodedInfo.myInfo.firmwareVersion))] version = version.dropLast() @@ -471,6 +474,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph self.connectedPeripheral.num = fetchedMyInfo[0].myNodeNum self.connectedPeripheral.firmwareVersion = fetchedMyInfo[0].firmwareVersion ?? "Unknown" self.connectedPeripheral.name = fetchedMyInfo[0].bleName ?? "Unknown" + self.connectedPeripheral.bitrate = fetchedMyInfo[0].bitrate + } do { @@ -812,7 +817,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph // MARK: Incoming Packet from the POSITION_APP } else if decodedInfo.packet.decoded.portnum == PortNum.positionApp { - let fetchNodePositionRequest: NSFetchRequest = NSFetchRequest.init(entityName: "NodeInfoEntity") fetchNodePositionRequest.predicate = NSPredicate(format: "num == %lld", Int64(decodedInfo.packet.from)) diff --git a/MeshtasticClient/Model/PeripheralModel.swift b/MeshtasticClient/Model/PeripheralModel.swift index 1b921104..18f00d6b 100644 --- a/MeshtasticClient/Model/PeripheralModel.swift +++ b/MeshtasticClient/Model/PeripheralModel.swift @@ -9,13 +9,14 @@ struct Peripheral: Identifiable { var longName: String var firmwareVersion: String var rssi: Int + var bitrate: Float? var channelUtilization: Float? var airTime: Float? var lastUpdate: Date var subscribed: Bool var peripheral: CBPeripheral - init(id: String, num: Int64, name: String, shortName: String, longName: String, firmwareVersion: String, rssi: Int, channelUtilization: Float?, airTime: Float?, lastUpdate: Date, subscribed: Bool, peripheral: CBPeripheral) { + init(id: String, num: Int64, name: String, shortName: String, longName: String, firmwareVersion: String, rssi: Int, bitrate: Float?, channelUtilization: Float?, airTime: Float?, lastUpdate: Date, subscribed: Bool, peripheral: CBPeripheral) { self.id = id self.num = num self.name = name @@ -23,6 +24,7 @@ struct Peripheral: Identifiable { self.longName = longName self.firmwareVersion = firmwareVersion self.rssi = rssi + self.bitrate = bitrate self.channelUtilization = channelUtilization self.airTime = airTime self.lastUpdate = lastUpdate diff --git a/MeshtasticClient/Views/Bluetooth/Connect.swift b/MeshtasticClient/Views/Bluetooth/Connect.swift index 49386672..84087dbe 100644 --- a/MeshtasticClient/Views/Bluetooth/Connect.swift +++ b/MeshtasticClient/Views/Bluetooth/Connect.swift @@ -74,9 +74,13 @@ struct Connect: View { if bleManager.connectedPeripheral != nil { Text("FW Version: ").font(.caption)+Text(bleManager.connectedPeripheral.firmwareVersion) .font(.caption).foregroundColor(Color.gray) - Text("Channel Utilization: ").font(.caption)+Text(String(bleManager.connectedPeripheral.channelUtilization ?? 0.00)) + Text("Bitrate: ").font(.caption)+Text(String(format: "%.2f", bleManager.connectedPeripheral.bitrate ?? 0.00)) .font(.caption).foregroundColor(Color.gray) - Text("Air Time: ").font(.caption)+Text(String(bleManager.connectedPeripheral.airTime ?? 0.00)) + + + Text("Channel Utilization: ").font(.caption)+Text(String(format: "%.2f", bleManager.connectedPeripheral.channelUtilization ?? 0.00)) + .font(.caption).foregroundColor(Color.gray) + Text("Air Time: ").font(.caption)+Text(String(format: "%.2f", bleManager.connectedPeripheral.airTime ?? 0.00)) .font(.caption).foregroundColor(Color.gray) } if bleManager.connectedPeripheral.subscribed { diff --git a/MeshtasticClient/Views/Helpers/LastHeardText.swift b/MeshtasticClient/Views/Helpers/LastHeardText.swift new file mode 100644 index 00000000..c17a423d --- /dev/null +++ b/MeshtasticClient/Views/Helpers/LastHeardText.swift @@ -0,0 +1,22 @@ +import SwiftUI +// +// LastHeardText.swift +// Meshtastic Apple +// +// Created by Garth Vander Houwen on 5/25/22. +// +struct LastHeardText: View { + var lastHeard: Date? + let sixMonthsAgo = Calendar.current.date(byAdding: .month, value: -6, to: Date()) + + var body: some View { + if (lastHeard != nil && lastHeard! >= sixMonthsAgo!){ + + Text("Last Heard: \(lastHeard!, style: .relative) ago") + + } else { + + Text("Last Heard: Unknown Age") + } + } +} diff --git a/MeshtasticClient/Views/Nodes/NodeDetail.swift b/MeshtasticClient/Views/Nodes/NodeDetail.swift index e3bd2df1..637344a5 100644 --- a/MeshtasticClient/Views/Nodes/NodeDetail.swift +++ b/MeshtasticClient/Views/Nodes/NodeDetail.swift @@ -65,19 +65,19 @@ struct NodeDetail: View { ScrollView { - if node.lastHeard != nil { - HStack { + HStack { - Image(systemName: "clock.badge.checkmark.fill") - .font(.title) - .foregroundColor(.accentColor) - .symbolRenderingMode(.hierarchical) - Text("Last Heard: \(node.lastHeard!, style: .relative) ago").font(.title3) - } - .padding() - Divider() + Image(systemName: "clock.badge.checkmark.fill") + .font(.title) + .foregroundColor(.accentColor) + .symbolRenderingMode(.hierarchical) + + LastHeardText(lastHeard: node.lastHeard).font(.title3) + } + .padding() + Divider() HStack { @@ -133,6 +133,15 @@ struct NodeDetail: View { BatteryIcon(batteryLevel: mostRecent.batteryLevel, font: .title, color: .accentColor) .padding(.bottom) + Text(String(mostRecent.batteryLevel) + "%") + .font(.title3) + .foregroundColor(.gray) + .fixedSize() + Text(String(format: "%.2f", mostRecent.voltage) + " V") + .font(.title3) + .foregroundColor(.gray) + .fixedSize() + } .padding(5) @@ -194,6 +203,10 @@ struct NodeDetail: View { Divider() ForEach(node.positions!.array as! [PositionEntity], id: \.self) { (mappin: PositionEntity) in + if mappin.coordinate != nil { + + + } } // ForEach(node.positions!.array as! [PositionEntity], id: \.self) { (mappin: PositionEntity) in diff --git a/MeshtasticClient/Views/Nodes/NodeList.swift b/MeshtasticClient/Views/Nodes/NodeList.swift index 3c043ea8..b608a3f3 100644 --- a/MeshtasticClient/Views/Nodes/NodeList.swift +++ b/MeshtasticClient/Views/Nodes/NodeList.swift @@ -65,11 +65,18 @@ struct NodeList: View { .padding(.bottom, 10) if connected { + HStack(alignment: .bottom) { Image(systemName: "repeat.circle.fill").font(.title3) .foregroundColor(.accentColor).symbolRenderingMode(.hierarchical) - Text("Currently Connected").font(.title3).foregroundColor(Color.accentColor) + if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { + + Text("Currently Connected").font(.headline).foregroundColor(Color.accentColor) + } else { + + Text("Currently Connected").font(.title3).foregroundColor(Color.accentColor) + } } Spacer() } @@ -77,44 +84,23 @@ struct NodeList: View { HStack(alignment: .bottom) { Image(systemName: "clock.badge.checkmark.fill").font(.title3).foregroundColor(.accentColor).symbolRenderingMode(.hierarchical) - - if node.lastHeard != nil { - Text("Last Heard: \(node.lastHeard!, style: .relative) ago").font(.subheadline).foregroundColor(.gray) + if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { + + LastHeardText(lastHeard: node.lastHeard).font(.subheadline).foregroundColor(.gray) } else { - Text("Last Heard: Unknown").font(.subheadline).foregroundColor(.gray) + + LastHeardText(lastHeard: node.lastHeard).font(.title3).foregroundColor(.gray) } } } .padding([.leading, .top, .bottom]) } -// .swipeActions { -// -// Button { -// -// context.delete(node) -// -// do { -// -// try context.save() -// print("Successfully Deleted NodeInfoEntiy: \(node.num)") -// -// } catch { -// -// print("Failed to save context after deleting NodeInfoEntity Num: \(node.num)") -// } -// -// } label: { -// -// Label("Delete from app", systemImage: "trash") -// } -// .tint(.red) -// } } } } .navigationTitle("All Nodes") .onAppear { - // self.nodes.returnsObjectsAsFaults = false + self.bleManager.context = context self.bleManager.userSettings = userSettings From bd5623758fb61e17b51e5ca1718fd4c1938d8c38 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 25 May 2022 22:31:16 -0700 Subject: [PATCH 21/21] Bump build number --- Meshtastic Client.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 38d87e76..d2feb92c 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -751,7 +751,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; @@ -783,7 +783,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES;