From ea7ca345c1374518345c5c62b564dc3c29ab6eeb Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 4 Feb 2022 02:26:58 -0800 Subject: [PATCH 1/2] Context menu for messages --- Meshtastic Client.xcodeproj/project.pbxproj | 4 + MeshtasticClient/Helpers/BLEManager.swift | 35 +- MeshtasticClient/Protobufs/admin.pb.swift | 510 ++++++++++++++++++ .../Protobufs/deviceonly.pb.swift | 75 +++ .../environmental_measurement.pb.swift | 24 + MeshtasticClient/Protobufs/mesh.pb.swift | 94 ++-- .../Protobufs/radioconfig.pb.swift | 346 +++++++++++- .../Views/Messages/UserMessageList.swift | 38 +- gen_protos.sh | 2 +- 9 files changed, 1071 insertions(+), 57 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 6bfed725..38dd6e48 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ DD47E3DB26F3901B00029299 /* Channels.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3DA26F3901A00029299 /* Channels.swift */; }; DD47E3DD26F390A000029299 /* Messages.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3DC26F390A000029299 /* Messages.swift */; }; DD4A911E2708C65400501B7E /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4A911D2708C65400501B7E /* AppSettings.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 */; }; DD539502276DAA6A00AD86B1 /* MapLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD539501276DAA6A00AD86B1 /* MapLocation.swift */; }; @@ -90,6 +91,7 @@ DD47E3DA26F3901A00029299 /* Channels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Channels.swift; sourceTree = ""; }; DD47E3DC26F390A000029299 /* Messages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Messages.swift; sourceTree = ""; }; DD4A911D2708C65400501B7E /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.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 = ""; }; DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLogger.swift; sourceTree = ""; }; @@ -214,6 +216,7 @@ DDAF8C5626ED07740058C060 /* Protobufs */ = { isa = PBXGroup; children = ( + DD4DED8F27AD2975004BA27E /* cannedmessages.pb.swift */, DDAF8C6126ED0A230058C060 /* admin.pb.swift */, C9A88B56278B559900BD810A /* apponly.pb.swift */, DDAF8C6426ED0A490058C060 /* channel.pb.swift */, @@ -528,6 +531,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DD4DED9027AD2975004BA27E /* cannedmessages.pb.swift in Sources */, DD836AE726F6B38600ABCC23 /* Connect.swift in Sources */, DDAF8C6E26ED19040058C060 /* Extensions.swift in Sources */, DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */, diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 2545f807..21ce011e 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -682,11 +682,11 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } newMessage.receivedACK = false newMessage.direction = "IN" - newMessage.isTapback = decodedInfo.packet.isTapback + newMessage.isTapback = decodedInfo.packet.decoded.isTapback - if decodedInfo.packet.replyID > 0 { + if decodedInfo.packet.decoded.replyID > 0 { - newMessage.replyID = Int64(decodedInfo.packet.replyID) + newMessage.replyID = Int64(decodedInfo.packet.decoded.replyID) } if decodedInfo.packet.to == broadcastNodeNum && fetchedUsers.count == 1 { @@ -823,8 +823,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet mutablePositions.add(position) - print("💾 Recieved a Position Packet") - if position.coordinate == nil { var newPostions = [PositionEntity]() newPostions.append(position) @@ -845,42 +843,45 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph try context!.save() if meshLoggingEnabled { - MeshLogger.log("💾 Updated NodeInfo SNR and Time from Node Info App Packet For: \(fetchedNode[0].num)") + MeshLogger.log("💾 Updated NodeInfo Position Coordinates, SNR and Time from Position App Packet For: \(fetchedNode[0].num)") } - print("💾 Updated NodeInfo SNR and Time from Position Packet For: \(fetchedNode[0].num)") + print("💾 Updated NodeInfo Position Coordinates, SNR and Time from Position App Packet For:: \(fetchedNode[0].num)") } catch { context!.rollback() let nsError = error as NSError - print("💥 Error Saving NodeInfoEntity from NODEINFO_APP \(nsError)") + print("💥 Error Saving NodeInfoEntity from POSITION_APP \(nsError)") } } catch { - print("💥 Error Fetching NodeInfoEntity for NODEINFO_APP") + print("💥 Error Fetching NodeInfoEntity for POSITION_APP") } - - // + } else if decodedInfo.packet.decoded.portnum == PortNum.environmentalMeasurementApp { + + 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())") + } else if decodedInfo.packet.decoded.portnum == PortNum.storeForwardApp { - if meshLoggingEnabled { MeshLogger.log("🚨 MESH PACKET received for Store Forward App UNHANDLED \(try decodedInfo.packet.jsonString())") } + if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Store Forward App UNHANDLED \(try decodedInfo.packet.jsonString())") } print("ℹ️ MESH PACKET received for Admin App UNHANDLED \(try decodedInfo.packet.jsonString())") } else if decodedInfo.packet.decoded.portnum == PortNum.adminApp { - if meshLoggingEnabled { MeshLogger.log("🚨 MESH PACKET received for Admin App UNHANDLED \(try decodedInfo.packet.jsonString())") } + if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Admin App UNHANDLED \(try decodedInfo.packet.jsonString())") } print("ℹ️ MESH PACKET received for Admin App UNHANDLED \(try decodedInfo.packet.jsonString())") } else if decodedInfo.packet.decoded.portnum == PortNum.routingApp { - if meshLoggingEnabled { MeshLogger.log("🚨 MESH PACKET received for Routing App UNHANDLED \(try decodedInfo.packet.jsonString())") } + if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Routing App UNHANDLED \(try decodedInfo.packet.jsonString())") } print("ℹ️ MESH PACKET received for Routing App UNHANDLED \(try decodedInfo.packet.jsonString())") } else { - if meshLoggingEnabled { MeshLogger.log("🚨 MESH PACKET received for Other App UNHANDLED \(try decodedInfo.packet.jsonString())") } + if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Other App UNHANDLED \(try decodedInfo.packet.jsonString())") } print("ℹ️ MESH PACKET received for Other App UNHANDLED \(try decodedInfo.packet.jsonString())") } @@ -986,9 +987,9 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph var meshPacket = MeshPacket() meshPacket.to = UInt32(toUserNum) meshPacket.from = UInt32(fromUserNum) - meshPacket.isTapback = isTapback + meshPacket.decoded.isTapback = isTapback if replyID > 0 { - meshPacket.replyID = UInt32(replyID) + meshPacket.decoded.replyID = UInt32(replyID) } meshPacket.decoded = dataMessage meshPacket.wantAck = true diff --git a/MeshtasticClient/Protobufs/admin.pb.swift b/MeshtasticClient/Protobufs/admin.pb.swift index fe280abf..62641e41 100644 --- a/MeshtasticClient/Protobufs/admin.pb.swift +++ b/MeshtasticClient/Protobufs/admin.pb.swift @@ -162,6 +162,156 @@ struct AdminMessage { set {variant = .rebootSeconds(newValue)} } + /// + /// Get the Canned Message Plugin message part1 in the response to this message. + var getCannedMessagePluginPart1Request: Bool { + get { + if case .getCannedMessagePluginPart1Request(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)} + } + + /// + /// Get the Canned Message Plugin message part2 in the response to this message. + var getCannedMessagePluginPart2Request: Bool { + get { + if case .getCannedMessagePluginPart2Request(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)} + } + + /// + /// Get the Canned Message Plugin message part3 in the response to this message. + var getCannedMessagePluginPart3Request: Bool { + get { + if case .getCannedMessagePluginPart3Request(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)} + } + + /// + /// Get the Canned Message Plugin message part4 in the response to this message. + var getCannedMessagePluginPart4Request: Bool { + get { + if case .getCannedMessagePluginPart4Request(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)} + } + + /// + /// Get the Canned Message Plugin message part5 in the response to this message. + var getCannedMessagePluginPart5Request: Bool { + get { + if case .getCannedMessagePluginPart5Request(let v)? = variant {return v} + return false + } + set {variant = .getCannedMessagePluginPart5Request(newValue)} + } + + var getCannedMessagePluginPart5Response: CannedMessagePluginMessagePart5 { + get { + if case .getCannedMessagePluginPart5Response(let v)? = variant {return v} + return CannedMessagePluginMessagePart5() + } + set {variant = .getCannedMessagePluginPart5Response(newValue)} + } + + /// + /// Set the canned message plugin part 1 text. + var setCannedMessagePluginPart1: CannedMessagePluginMessagePart1 { + get { + if case .setCannedMessagePluginPart1(let v)? = variant {return v} + return CannedMessagePluginMessagePart1() + } + set {variant = .setCannedMessagePluginPart1(newValue)} + } + + /// + /// Set the canned message plugin part 2 text. + var setCannedMessagePluginPart2: CannedMessagePluginMessagePart2 { + get { + if case .setCannedMessagePluginPart2(let v)? = variant {return v} + return CannedMessagePluginMessagePart2() + } + set {variant = .setCannedMessagePluginPart2(newValue)} + } + + /// + /// Set the canned message plugin part 3 text. + var setCannedMessagePluginPart3: CannedMessagePluginMessagePart3 { + get { + if case .setCannedMessagePluginPart3(let v)? = variant {return v} + return CannedMessagePluginMessagePart3() + } + set {variant = .setCannedMessagePluginPart3(newValue)} + } + + /// + /// Set the canned message plugin part 4 text. + var setCannedMessagePluginPart4: CannedMessagePluginMessagePart4 { + get { + if case .setCannedMessagePluginPart4(let v)? = variant {return v} + return CannedMessagePluginMessagePart4() + } + 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)} + } + + /// + /// Tell the node to shutdown in this many seconds (or <0 to cancel shutdown) + var shutdownSeconds: Int32 { + get { + if case .shutdownSeconds(let v)? = variant {return v} + return 0 + } + set {variant = .shutdownSeconds(newValue)} + } + var unknownFields = SwiftProtobuf.UnknownStorage() enum OneOf_Variant: Equatable { @@ -205,6 +355,44 @@ 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 Plugin message part2 in the response to this message. + case getCannedMessagePluginPart2Request(Bool) + case getCannedMessagePluginPart2Response(CannedMessagePluginMessagePart2) + /// + /// Get the Canned Message Plugin message part3 in the response to this message. + case getCannedMessagePluginPart3Request(Bool) + case getCannedMessagePluginPart3Response(CannedMessagePluginMessagePart3) + /// + /// Get the Canned Message Plugin message part4 in the response to this message. + case getCannedMessagePluginPart4Request(Bool) + case getCannedMessagePluginPart4Response(CannedMessagePluginMessagePart4) + /// + /// Get the Canned Message Plugin message part5 in the response to this message. + case getCannedMessagePluginPart5Request(Bool) + case getCannedMessagePluginPart5Response(CannedMessagePluginMessagePart5) + /// + /// Set the canned message plugin part 1 text. + case setCannedMessagePluginPart1(CannedMessagePluginMessagePart1) + /// + /// Set the canned message plugin part 2 text. + case setCannedMessagePluginPart2(CannedMessagePluginMessagePart2) + /// + /// Set the canned message plugin part 3 text. + case setCannedMessagePluginPart3(CannedMessagePluginMessagePart3) + /// + /// Set the canned message plugin part 4 text. + case setCannedMessagePluginPart4(CannedMessagePluginMessagePart4) + /// + /// Set the canned message plugin part 5 text. + case setCannedMessagePluginPart5(CannedMessagePluginMessagePart5) + /// + /// Tell the node to shutdown in this many seconds (or <0 to cancel shutdown) + case shutdownSeconds(Int32) #if !swift(>=4.1) static func ==(lhs: AdminMessage.OneOf_Variant, rhs: AdminMessage.OneOf_Variant) -> Bool { @@ -264,6 +452,70 @@ 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() } + return l == r + }() + case (.getCannedMessagePluginPart1Response, .getCannedMessagePluginPart1Response): return { + guard case .getCannedMessagePluginPart1Response(let l) = lhs, case .getCannedMessagePluginPart1Response(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() } + return l == r + }() + case (.getCannedMessagePluginPart2Response, .getCannedMessagePluginPart2Response): return { + guard case .getCannedMessagePluginPart2Response(let l) = lhs, case .getCannedMessagePluginPart2Response(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() } + return l == r + }() + case (.getCannedMessagePluginPart3Response, .getCannedMessagePluginPart3Response): return { + guard case .getCannedMessagePluginPart3Response(let l) = lhs, case .getCannedMessagePluginPart3Response(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() } + return l == r + }() + case (.getCannedMessagePluginPart4Response, .getCannedMessagePluginPart4Response): return { + guard case .getCannedMessagePluginPart4Response(let l) = lhs, case .getCannedMessagePluginPart4Response(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() } + return l == r + }() + case (.getCannedMessagePluginPart5Response, .getCannedMessagePluginPart5Response): return { + guard case .getCannedMessagePluginPart5Response(let l) = lhs, case .getCannedMessagePluginPart5Response(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() } + 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() } + return l == r + }() + case (.shutdownSeconds, .shutdownSeconds): return { + guard case .shutdownSeconds(let l) = lhs, case .shutdownSeconds(let r) = rhs else { preconditionFailure() } + return l == r + }() default: return false } } @@ -291,6 +543,22 @@ 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"), + 51: .standard(proto: "shutdown_seconds"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -433,6 +701,184 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat self.variant = .rebootSeconds(v) } }() + case 36: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessagePluginPart1Request(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) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessagePluginPart1Response(v) + } + }() + case 38: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessagePluginPart2Request(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) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessagePluginPart2Response(v) + } + }() + case 40: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessagePluginPart3Request(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) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessagePluginPart3Response(v) + } + }() + case 42: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessagePluginPart4Request(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) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessagePluginPart4Response(v) + } + }() + case 44: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessagePluginPart5Request(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) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .getCannedMessagePluginPart5Response(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) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.variant = .setCannedMessagePluginPart1(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) + 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) + } + }() + case 51: try { + var v: Int32? + try decoder.decodeSingularInt32Field(value: &v) + if let v = v { + if self.variant != nil {try decoder.handleConflictingOneOf()} + self.variant = .shutdownSeconds(v) + } + }() default: break } } @@ -495,6 +941,70 @@ 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() } + 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 .getCannedMessagePluginPart2Request?: try { + guard case .getCannedMessagePluginPart2Request(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 .getCannedMessagePluginPart3Request?: try { + guard case .getCannedMessagePluginPart3Request(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 .getCannedMessagePluginPart4Request?: try { + guard case .getCannedMessagePluginPart4Request(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 .getCannedMessagePluginPart5Request?: try { + guard case .getCannedMessagePluginPart5Request(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularBoolField(value: v, fieldNumber: 44) + }() + case .getCannedMessagePluginPart5Response?: try { + guard case .getCannedMessagePluginPart5Response(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 45) + }() + case .setCannedMessagePluginPart1?: try { + guard case .setCannedMessagePluginPart1(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularMessageField(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 .shutdownSeconds?: try { + guard case .shutdownSeconds(let v)? = self.variant else { preconditionFailure() } + try visitor.visitSingularInt32Field(value: v, fieldNumber: 51) + }() case nil: break } try unknownFields.traverse(visitor: &visitor) diff --git a/MeshtasticClient/Protobufs/deviceonly.pb.swift b/MeshtasticClient/Protobufs/deviceonly.pb.swift index b44ea5c8..db92de38 100644 --- a/MeshtasticClient/Protobufs/deviceonly.pb.swift +++ b/MeshtasticClient/Protobufs/deviceonly.pb.swift @@ -152,6 +152,41 @@ 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() {} @@ -253,6 +288,11 @@ 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 { @@ -265,6 +305,11 @@ 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() @@ -280,6 +325,11 @@ 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 } } @@ -307,6 +357,11 @@ 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 } } @@ -342,6 +397,21 @@ 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) } @@ -360,6 +430,11 @@ 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 index 73e7ef02..76533a31 100644 --- a/MeshtasticClient/Protobufs/environmental_measurement.pb.swift +++ b/MeshtasticClient/Protobufs/environmental_measurement.pb.swift @@ -31,6 +31,12 @@ struct EnvironmentalMeasurement { var barometricPressure: Float = 0 + var gasResistance: Float = 0 + + var voltage: Float = 0 + + var current: Float = 0 + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -44,6 +50,9 @@ extension EnvironmentalMeasurement: SwiftProtobuf.Message, SwiftProtobuf._Messag 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 { @@ -55,6 +64,9 @@ extension EnvironmentalMeasurement: SwiftProtobuf.Message, SwiftProtobuf._Messag 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 } } @@ -70,6 +82,15 @@ extension EnvironmentalMeasurement: SwiftProtobuf.Message, SwiftProtobuf._Messag 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) } @@ -77,6 +98,9 @@ extension EnvironmentalMeasurement: SwiftProtobuf.Message, SwiftProtobuf._Messag 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 512ab45a..9f6370a3 100644 --- a/MeshtasticClient/Protobufs/mesh.pb.swift +++ b/MeshtasticClient/Protobufs/mesh.pb.swift @@ -62,6 +62,9 @@ enum HardwareModel: SwiftProtobuf.Enum { /// 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 + case heltecV1 // = 11 + /// /// Less common/prototype boards listed here (needs one more byte over the air) case loraRelayV1 // = 32 @@ -78,6 +81,14 @@ enum HardwareModel: SwiftProtobuf.Enum { /// /// Custom DIY device based on @NanoVHF schematics: https://github.com/NanoVHF/Meshtastic-DIY/tree/main/Schematics case diyV1 // = 39 + + /// + /// RAK WisBlock ESP32 core: https://docs.rakwireless.com/Product-Categories/WisBlock/RAK11200/Overview/ + case rak11200 // = 40 + + /// + /// 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 case UNRECOGNIZED(Int) init() { @@ -97,6 +108,7 @@ enum HardwareModel: SwiftProtobuf.Enum { case 8: self = .tloraV11P3 case 9: self = .rak4631 case 10: self = .heltecV21 + case 11: self = .heltecV1 case 32: self = .loraRelayV1 case 33: self = .nrf52840Dk case 34: self = .ppr @@ -105,6 +117,8 @@ enum HardwareModel: SwiftProtobuf.Enum { case 37: self = .portduino case 38: self = .androidSim case 39: self = .diyV1 + case 40: self = .rak11200 + case 255: self = .privateHw default: self = .UNRECOGNIZED(rawValue) } } @@ -122,6 +136,7 @@ enum HardwareModel: SwiftProtobuf.Enum { case .tloraV11P3: return 8 case .rak4631: return 9 case .heltecV21: return 10 + case .heltecV1: return 11 case .loraRelayV1: return 32 case .nrf52840Dk: return 33 case .ppr: return 34 @@ -130,6 +145,8 @@ enum HardwareModel: SwiftProtobuf.Enum { case .portduino: return 37 case .androidSim: return 38 case .diyV1: return 39 + case .rak11200: return 40 + case .privateHw: return 255 case .UNRECOGNIZED(let i): return i } } @@ -152,6 +169,7 @@ extension HardwareModel: CaseIterable { .tloraV11P3, .rak4631, .heltecV21, + .heltecV1, .loraRelayV1, .nrf52840Dk, .ppr, @@ -160,6 +178,8 @@ extension HardwareModel: CaseIterable { .portduino, .androidSim, .diyV1, + .rak11200, + .privateHw, ] } @@ -1064,6 +1084,15 @@ struct DataMessage { /// Indicates the original message ID that this message is reporting failure on. (formerly called original_id) var requestID: UInt32 = 0 + /// + /// If set, this message is intened to be a reply to a previously sent message with the defined id. + var replyID: UInt32 = 0 + + /// + /// 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 unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -1212,21 +1241,6 @@ struct MeshPacket { set {_uniqueStorage()._delayed = newValue} } - /// - /// If set, this message is intened to be a reply to a previously sent message with the defined id. - var replyID: UInt32 { - get {return _storage._replyID} - set {_uniqueStorage()._replyID = newValue} - } - - /// - /// Defaults to false. If true, then what is in the payload should be treated as an emoji like giving - /// a message a heart or poop emoji. - var isTapback: Bool { - get {return _storage._isTapback} - set {_uniqueStorage()._isTapback = newValue} - } - var unknownFields = SwiftProtobuf.UnknownStorage() enum OneOf_PayloadVariant: Equatable { @@ -1613,14 +1627,14 @@ struct MyNodeInfo { } /// - /// 48 time windows of 1hr each with the airtime transmitted out of the device per hour. + /// 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} } /// - /// 48 time windows of 1hr each with the airtime of valid packets for your mesh. + /// 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} @@ -1640,6 +1654,13 @@ struct MyNodeInfo { set {_uniqueStorage()._channelUtilization = newValue} } + /// + /// Percent of airtime for transmission used within the last hour. + var airUtilTx: Float { + get {return _storage._airUtilTx} + set {_uniqueStorage()._airUtilTx = newValue} + } + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -2046,6 +2067,7 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { 8: .same(proto: "TLORA_V1_1p3"), 9: .same(proto: "RAK4631"), 10: .same(proto: "HELTEC_V2_1"), + 11: .same(proto: "HELTEC_V1"), 32: .same(proto: "LORA_RELAY_V1"), 33: .same(proto: "NRF52840DK"), 34: .same(proto: "PPR"), @@ -2054,6 +2076,8 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { 37: .same(proto: "PORTDUINO"), 38: .same(proto: "ANDROID_SIM"), 39: .same(proto: "DIY_V1"), + 40: .same(proto: "RAK11200"), + 255: .same(proto: "PRIVATE_HW"), ] } @@ -2585,6 +2609,8 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati 4: .same(proto: "dest"), 5: .same(proto: "source"), 6: .standard(proto: "request_id"), + 7: .standard(proto: "reply_id"), + 8: .standard(proto: "is_tapback"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2599,6 +2625,8 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati case 4: try { try decoder.decodeSingularFixed32Field(value: &self.dest) }() 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) }() default: break } } @@ -2623,6 +2651,12 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati if self.requestID != 0 { try visitor.visitSingularFixed32Field(value: self.requestID, fieldNumber: 6) } + if self.replyID != 0 { + try visitor.visitSingularFixed32Field(value: self.replyID, fieldNumber: 7) + } + if self.isTapback != false { + try visitor.visitSingularBoolField(value: self.isTapback, fieldNumber: 8) + } try unknownFields.traverse(visitor: &visitor) } @@ -2633,6 +2667,8 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati if lhs.dest != rhs.dest {return false} 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.unknownFields != rhs.unknownFields {return false} return true } @@ -2654,8 +2690,6 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 12: .same(proto: "priority"), 13: .standard(proto: "rx_rssi"), 15: .same(proto: "delayed"), - 16: .standard(proto: "reply_id"), - 17: .standard(proto: "is_tapback"), ] fileprivate class _StorageClass { @@ -2671,8 +2705,6 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio var _priority: MeshPacket.Priority = .unset var _rxRssi: Int32 = 0 var _delayed: MeshPacket.Delayed = .noDelay - var _replyID: UInt32 = 0 - var _isTapback: Bool = false static let defaultInstance = _StorageClass() @@ -2691,8 +2723,6 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio _priority = source._priority _rxRssi = source._rxRssi _delayed = source._delayed - _replyID = source._replyID - _isTapback = source._isTapback } } @@ -2743,8 +2773,6 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio case 12: try { try decoder.decodeSingularEnumField(value: &_storage._priority) }() case 13: try { try decoder.decodeSingularInt32Field(value: &_storage._rxRssi) }() case 15: try { try decoder.decodeSingularEnumField(value: &_storage._delayed) }() - case 16: try { try decoder.decodeSingularFixed32Field(value: &_storage._replyID) }() - case 17: try { try decoder.decodeSingularBoolField(value: &_storage._isTapback) }() default: break } } @@ -2800,12 +2828,6 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if _storage._delayed != .noDelay { try visitor.visitSingularEnumField(value: _storage._delayed, fieldNumber: 15) } - if _storage._replyID != 0 { - try visitor.visitSingularFixed32Field(value: _storage._replyID, fieldNumber: 16) - } - if _storage._isTapback != false { - try visitor.visitSingularBoolField(value: _storage._isTapback, fieldNumber: 17) - } } try unknownFields.traverse(visitor: &visitor) } @@ -2827,8 +2849,6 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if _storage._priority != rhs_storage._priority {return false} if _storage._rxRssi != rhs_storage._rxRssi {return false} if _storage._delayed != rhs_storage._delayed {return false} - if _storage._replyID != rhs_storage._replyID {return false} - if _storage._isTapback != rhs_storage._isTapback {return false} return true } if !storagesAreEqual {return false} @@ -2935,6 +2955,7 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 17: .standard(proto: "air_period_rx"), 18: .standard(proto: "has_wifi"), 19: .standard(proto: "channel_utilization"), + 20: .standard(proto: "air_util_tx"), ] fileprivate class _StorageClass { @@ -2956,6 +2977,7 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio var _airPeriodRx: [UInt32] = [] var _hasWifi_p: Bool = false var _channelUtilization: Float = 0 + var _airUtilTx: Float = 0 static let defaultInstance = _StorageClass() @@ -2980,6 +3002,7 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio _airPeriodRx = source._airPeriodRx _hasWifi_p = source._hasWifi_p _channelUtilization = source._channelUtilization + _airUtilTx = source._airUtilTx } } @@ -3016,6 +3039,7 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 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 } } @@ -3078,6 +3102,9 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if _storage._channelUtilization != 0 { try visitor.visitSingularFloatField(value: _storage._channelUtilization, fieldNumber: 19) } + if _storage._airUtilTx != 0 { + try visitor.visitSingularFloatField(value: _storage._airUtilTx, fieldNumber: 20) + } } try unknownFields.traverse(visitor: &visitor) } @@ -3105,6 +3132,7 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 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} diff --git a/MeshtasticClient/Protobufs/radioconfig.pb.swift b/MeshtasticClient/Protobufs/radioconfig.pb.swift index 77770d3d..5ea36075 100644 --- a/MeshtasticClient/Protobufs/radioconfig.pb.swift +++ b/MeshtasticClient/Protobufs/radioconfig.pb.swift @@ -535,6 +535,72 @@ extension PositionFlags: CaseIterable { #endif // swift(>=4.2) +enum InputEventChar: SwiftProtobuf.Enum { + typealias RawValue = Int + case keyNone // = 0 + case keyUp // = 17 + case keyDown // = 18 + case keyLeft // = 19 + case keyRight // = 20 + + /// '\n' + case keySelect // = 10 + case keyBack // = 27 + 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 + } + } + +} + +#if swift(>=4.2) + +extension InputEventChar: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static var allCases: [InputEventChar] = [ + .keyNone, + .keyUp, + .keyDown, + .keyLeft, + .keyRight, + .keySelect, + .keyBack, + .keyCancel, + ] +} + +#endif // swift(>=4.2) + /// /// The entire set of user settable/readable settings for our radio device. /// Includes both the current channel settings and any preferences the user has @@ -779,7 +845,6 @@ struct RadioConfig { /// 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 { @@ -1082,12 +1147,134 @@ struct RadioConfig { set {_uniqueStorage()._mqttPassword = newValue} } + /// + /// Disable TX from the LoRa radio. Useful for hot-swapping antennas and other tests. + /// Defaults to false + var isLoraTxDisabled: Bool { + get {return _storage._isLoraTxDisabled} + set {_uniqueStorage()._isLoraTxDisabled = newValue} + } + + /// + /// If set to true, enable power saving features of the esp32 + var isPowerSaving: Bool { + get {return _storage._isPowerSaving} + set {_uniqueStorage()._isPowerSaving = newValue} + } + + /// + /// Enable the rotary encoder #1 + var rotary1Enabled: Bool { + get {return _storage._rotary1Enabled} + set {_uniqueStorage()._rotary1Enabled = newValue} + } + + /// + /// GPIO pin for rotary encoder A port. + var rotary1PinA: UInt32 { + get {return _storage._rotary1PinA} + set {_uniqueStorage()._rotary1PinA = newValue} + } + + /// + /// GPIO pin for rotary encoder B port. + var rotary1PinB: UInt32 { + get {return _storage._rotary1PinB} + set {_uniqueStorage()._rotary1PinB = newValue} + } + + /// + /// GPIO pin for rotary encoder Press port. + var rotary1PinPress: UInt32 { + get {return _storage._rotary1PinPress} + set {_uniqueStorage()._rotary1PinPress = newValue} + } + + /// + /// Generate input event on CW of this kind. + var rotary1EventCw: InputEventChar { + get {return _storage._rotary1EventCw} + set {_uniqueStorage()._rotary1EventCw = newValue} + } + + /// + /// Generate input event on CCW of this kind. + var rotary1EventCcw: InputEventChar { + get {return _storage._rotary1EventCcw} + set {_uniqueStorage()._rotary1EventCcw = newValue} + } + + /// + /// Generate input event on Press of this kind. + var rotary1EventPress: InputEventChar { + get {return _storage._rotary1EventPress} + set {_uniqueStorage()._rotary1EventPress = newValue} + } + + /// + /// Enable/disable CannedMessagePlugin. + var cannedMessagePluginEnabled: Bool { + get {return _storage._cannedMessagePluginEnabled} + set {_uniqueStorage()._cannedMessagePluginEnabled = 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} + } + + /// + /// 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} + } + + /// + /// 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} + } + + /// + /// 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} + set {_uniqueStorage()._mqttEncryptionEnabled = newValue} + } + + /// + /// 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 { + get {return _storage._adcMultiplierOverride} + set {_uniqueStorage()._adcMultiplierOverride = newValue} + } + var unknownFields = SwiftProtobuf.UnknownStorage() enum EnvironmentalMeasurementSensorType: 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 UNRECOGNIZED(Int) init() { @@ -1098,6 +1285,12 @@ struct RadioConfig { 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 default: self = .UNRECOGNIZED(rawValue) } } @@ -1106,6 +1299,12 @@ struct RadioConfig { 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 .UNRECOGNIZED(let i): return i } } @@ -1129,6 +1328,12 @@ extension RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType: CaseIt static var allCases: [RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType] = [ .dht11, .ds18B20, + .dht12, + .dht21, + .dht22, + .bme280, + .bme680, + .mcp9808, ] } @@ -1217,6 +1422,19 @@ extension PositionFlags: SwiftProtobuf._ProtoNameProviding { ] } +extension 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"), + ] +} + extension RadioConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = "RadioConfig" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ @@ -1320,6 +1538,21 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes 154: .standard(proto: "hop_limit"), 155: .standard(proto: "mqtt_username"), 156: .standard(proto: "mqtt_password"), + 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"), + 174: .standard(proto: "mqtt_encryption_enabled"), + 175: .standard(proto: "adc_multiplier_override"), ] fileprivate class _StorageClass { @@ -1391,6 +1624,21 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes var _hopLimit: UInt32 = 0 var _mqttUsername: String = String() var _mqttPassword: String = String() + 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 _mqttEncryptionEnabled: Bool = false + var _adcMultiplierOverride: Float = 0 static let defaultInstance = _StorageClass() @@ -1465,6 +1713,21 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes _hopLimit = source._hopLimit _mqttUsername = source._mqttUsername _mqttPassword = source._mqttPassword + _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 + _mqttEncryptionEnabled = source._mqttEncryptionEnabled + _adcMultiplierOverride = source._adcMultiplierOverride } } @@ -1551,6 +1814,21 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes case 154: try { try decoder.decodeSingularUInt32Field(value: &_storage._hopLimit) }() case 155: try { try decoder.decodeSingularStringField(value: &_storage._mqttUsername) }() case 156: try { try decoder.decodeSingularStringField(value: &_storage._mqttPassword) }() + 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 174: try { try decoder.decodeSingularBoolField(value: &_storage._mqttEncryptionEnabled) }() + case 175: try { try decoder.decodeSingularFloatField(value: &_storage._adcMultiplierOverride) }() default: break } } @@ -1763,6 +2041,51 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if !_storage._mqttPassword.isEmpty { try visitor.visitSingularStringField(value: _storage._mqttPassword, fieldNumber: 156) } + if _storage._isLoraTxDisabled != false { + try visitor.visitSingularBoolField(value: _storage._isLoraTxDisabled, fieldNumber: 157) + } + if _storage._isPowerSaving != false { + try visitor.visitSingularBoolField(value: _storage._isPowerSaving, fieldNumber: 158) + } + 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._rotary1PinB != 0 { + try visitor.visitSingularUInt32Field(value: _storage._rotary1PinB, fieldNumber: 162) + } + if _storage._rotary1PinPress != 0 { + try visitor.visitSingularUInt32Field(value: _storage._rotary1PinPress, fieldNumber: 163) + } + if _storage._rotary1EventCw != .keyNone { + try visitor.visitSingularEnumField(value: _storage._rotary1EventCw, fieldNumber: 164) + } + if _storage._rotary1EventCcw != .keyNone { + try visitor.visitSingularEnumField(value: _storage._rotary1EventCcw, fieldNumber: 165) + } + if _storage._rotary1EventPress != .keyNone { + try visitor.visitSingularEnumField(value: _storage._rotary1EventPress, fieldNumber: 166) + } + if _storage._cannedMessagePluginEnabled != false { + try visitor.visitSingularBoolField(value: _storage._cannedMessagePluginEnabled, fieldNumber: 170) + } + if !_storage._cannedMessagePluginAllowInputSource.isEmpty { + try visitor.visitSingularStringField(value: _storage._cannedMessagePluginAllowInputSource, fieldNumber: 171) + } + if !_storage._cannedMessagePluginMessages.isEmpty { + try visitor.visitSingularStringField(value: _storage._cannedMessagePluginMessages, fieldNumber: 172) + } + if _storage._cannedMessagePluginSendBell != false { + try visitor.visitSingularBoolField(value: _storage._cannedMessagePluginSendBell, fieldNumber: 173) + } + if _storage._mqttEncryptionEnabled != false { + try visitor.visitSingularBoolField(value: _storage._mqttEncryptionEnabled, fieldNumber: 174) + } + if _storage._adcMultiplierOverride != 0 { + try visitor.visitSingularFloatField(value: _storage._adcMultiplierOverride, fieldNumber: 175) + } } try unknownFields.traverse(visitor: &visitor) } @@ -1840,6 +2163,21 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes if _storage._hopLimit != rhs_storage._hopLimit {return false} if _storage._mqttUsername != rhs_storage._mqttUsername {return false} if _storage._mqttPassword != rhs_storage._mqttPassword {return false} + 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._mqttEncryptionEnabled != rhs_storage._mqttEncryptionEnabled {return false} + if _storage._adcMultiplierOverride != rhs_storage._adcMultiplierOverride {return false} return true } if !storagesAreEqual {return false} @@ -1853,5 +2191,11 @@ extension RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType: SwiftP 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"), ] } diff --git a/MeshtasticClient/Views/Messages/UserMessageList.swift b/MeshtasticClient/Views/Messages/UserMessageList.swift index 66d6e842..8b407652 100644 --- a/MeshtasticClient/Views/Messages/UserMessageList.swift +++ b/MeshtasticClient/Views/Messages/UserMessageList.swift @@ -62,7 +62,7 @@ struct UserMessageList: View { let messageReply = allMessages.first(where: { $0.messageId == message.replyID }) HStack { - + Text(String(message.messageId)) Text(messageReply?.messagePayload ?? "EMPTY MESSAGE").foregroundColor(.blue).font(.caption2) .padding(10) .overlay( @@ -212,6 +212,27 @@ struct UserMessageList: View { Text("Copy") Image(systemName: "doc.on.doc") } + Menu("Message Details") { + + VStack { + + let time = Int32(message.messageTimestamp) + let messageDate = Date(timeIntervalSince1970: TimeInterval(time)) + + if time != 0 { + Text("Sent \(messageDate, style: .date) \(messageDate, style: .time)").font(.caption2).foregroundColor(.gray) + } else { + Text("Unknown").font(.caption2).foregroundColor(.gray) + } + + } + + VStack { + + Text("Received ACK: \(message.receivedACK ? "✔️" : "")") + + } + } Divider() Button(role: .destructive, action: { self.showDeleteMessageAlert = true @@ -261,16 +282,23 @@ struct UserMessageList: View { let time = Int32(message.messageTimestamp) let messageDate = Date(timeIntervalSince1970: TimeInterval(time)) + let showUntil = Date().addingTimeInterval(3600) if time != 0 { - Text(messageDate, style: .date).font(.caption2).foregroundColor(.gray) - Text(messageDate, style: .time).font(.caption2).foregroundColor(.gray) + // Text(messageDate, style: .date).font(.caption2).foregroundColor(.gray) + // Text(messageDate, style: .time).font(.caption2).foregroundColor(.gray) } else { - Text("Unknown").font(.caption2).foregroundColor(.gray) + // Text("Unknown").font(.caption2).foregroundColor(.gray) + } + + if messageDate <= showUntil && message.receivedACK { + + Text("Delivered").font(.caption2).foregroundColor(.gray) } } - .padding(4) + } + .padding(.bottom) .id(allMessages.firstIndex(of: message)) if !currentUser { diff --git a/gen_protos.sh b/gen_protos.sh index abdb0cdf..852c9d8d 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="radioconfig.proto channel.proto deviceonly.proto portnums.proto remote_hardware.proto environmental_measurement.proto admin.proto mqtt.proto mesh.proto storeforward.proto" +pfiles="radioconfig.proto channel.proto cannedmessages.proto deviceonly.proto portnums.proto remote_hardware.proto environmental_measurement.proto admin.proto mqtt.proto mesh.proto storeforward.proto" for pf in $pfiles do echo "Generating $pf..." From b1fb4c0bbf75a19fa86a7f3e2d570c31712bc94c Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 4 Feb 2022 17:09:30 -0800 Subject: [PATCH 2/2] Update protobufs --- .../Protobufs/cannedmessages.pb.swift | 287 ++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 MeshtasticClient/Protobufs/cannedmessages.pb.swift diff --git a/MeshtasticClient/Protobufs/cannedmessages.pb.swift b/MeshtasticClient/Protobufs/cannedmessages.pb.swift new file mode 100644 index 00000000..9b6068b8 --- /dev/null +++ b/MeshtasticClient/Protobufs/cannedmessages.pb.swift @@ -0,0 +1,287 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: cannedmessages.proto +// +// 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 + +// 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 +} + +/// +/// Canned message plugin part 1 +struct CannedMessagePluginMessagePart1 { + // 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() + + 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() {} +} + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +extension CannedMessagePluginMessagePart1: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = "CannedMessagePluginMessagePart1" + 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: 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} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +}