From 5a1818d5032dd671ecac4773c06b9d8c5b094361 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 17 Sep 2024 14:15:33 -0700 Subject: [PATCH 1/8] Set message size to 200 bytes, add extra pki check before setting key --- Localizable.xcstrings | 2 +- Meshtastic/AppIntents/MessageChannelIntent.swift | 4 ++-- Meshtastic/Helpers/MeshPackets.swift | 6 ++++-- .../Views/Messages/TextMessageField/TextMessageField.swift | 2 +- .../Views/Messages/TextMessageField/TextMessageSize.swift | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Localizable.xcstrings b/Localizable.xcstrings index a61ea1cf..d91dded2 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -14559,7 +14559,7 @@ "Message" : { }, - "Message content exceeds 228 bytes." : { + "Message content exceeds 200 bytes." : { }, "Message Status Options" : { diff --git a/Meshtastic/AppIntents/MessageChannelIntent.swift b/Meshtastic/AppIntents/MessageChannelIntent.swift index 29d0a6c2..6001d957 100644 --- a/Meshtastic/AppIntents/MessageChannelIntent.swift +++ b/Meshtastic/AppIntents/MessageChannelIntent.swift @@ -38,8 +38,8 @@ struct MessageChannelIntent: AppIntent { throw AppIntentErrors.AppIntentError.message("Failed to encode message content") } - if messageData.count > 228 { - throw $messageContent.needsValueError("Message content exceeds 228 bytes.") + if messageData.count > 200 { + throw $messageContent.needsValueError("Message content exceeds 200 bytes.") } if(!BLEManager.shared.sendMessage(message: messageContent, toUserNum: 0, channel: Int32(channelNumber), isEmoji: false, replyID: 0)){ diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index 09683c0e..a75a4c04 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -891,9 +891,11 @@ func textMessageAppPacket( if newMessage.fromUser?.publicKey != newMessage.publicKey { newMessage.fromUser?.keyMatch = false newMessage.fromUser?.newPublicKey = newMessage.publicKey - Logger.data.error("🔑 Key Mismatch origninal key: \(newMessage.fromUser?.publicKey?.base64EncodedString() ?? "No Key") new key: \(newMessage.fromUser?.newPublicKey?.base64EncodedString() ?? "No Key") ") + let nodeKey = String(newMessage.fromUser?.publicKey?.base64EncodedString() ?? "No Key").prefix(8) + let messageKey = String(newMessage.fromUser?.newPublicKey?.base64EncodedString() ?? "No Key").prefix(8) + Logger.data.error("🔑 Key Mismatch origninal key: \(nodeKey, privacy: .public) . . . new key: \(messageKey, privacy: .public) . . .") } - } else { + } else if packet.pkiEncrypted { /// We have no key, set it if it is not empty if !packet.publicKey.isEmpty { newMessage.fromUser?.pkiEncrypted = true diff --git a/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift b/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift index 469e57a4..12b72ae9 100644 --- a/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift +++ b/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift @@ -2,7 +2,7 @@ import SwiftUI import OSLog struct TextMessageField: View { - static let maxbytes = 228 + static let maxbytes = 200 @EnvironmentObject var bleManager: BLEManager let destination: MessageDestination diff --git a/Meshtastic/Views/Messages/TextMessageField/TextMessageSize.swift b/Meshtastic/Views/Messages/TextMessageField/TextMessageSize.swift index 2b7b1e5e..c939b825 100644 --- a/Meshtastic/Views/Messages/TextMessageField/TextMessageSize.swift +++ b/Meshtastic/Views/Messages/TextMessageField/TextMessageSize.swift @@ -15,6 +15,6 @@ struct TextMessageSize: View { struct TextMessageSizePreview: PreviewProvider { static var previews: some View { - TextMessageSize(maxbytes: 228, totalBytes: 100) + TextMessageSize(maxbytes: 200, totalBytes: 100) } } From c5f847a5488e0513c4dd8218109a189863fc15a0 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 17 Sep 2024 14:33:30 -0700 Subject: [PATCH 2/8] Bump bersion --- Meshtastic.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 7d9209f1..353226be 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -1687,7 +1687,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.5.5; + MARKETING_VERSION = 2.5.6; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1722,7 +1722,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.5.5; + MARKETING_VERSION = 2.5.6; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1754,7 +1754,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.5.5; + MARKETING_VERSION = 2.5.6; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1787,7 +1787,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.5.5; + MARKETING_VERSION = 2.5.6; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; From aaa6bbbfd29ed5012373af94f18c5399c0b790d8 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 18 Sep 2024 16:36:06 -0700 Subject: [PATCH 3/8] Log right public key field --- Localizable.xcstrings | 18 +++++++++++++++--- Meshtastic/Helpers/MeshPackets.swift | 9 +-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Localizable.xcstrings b/Localizable.xcstrings index d91dded2..0ea54454 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -21,6 +21,21 @@ }, ": %d" : { + }, + ".dot" : { + + }, + ".gauge" : { + + }, + ".gradient" : { + + }, + ".pill" : { + + }, + ".text" : { + }, "(Re)define PIN_GPS_EN for your board." : { @@ -19154,9 +19169,6 @@ }, "Send" : { - }, - "Send ${messageContent} to ${channelNumber}" : { - }, "Send a Group Message" : { diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index a75a4c04..badac8ec 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -872,27 +872,23 @@ func textMessageAppPacket( newMessage.read = true } } - if packet.decoded.replyID > 0 { newMessage.replyID = Int64(packet.decoded.replyID) } - if fetchedUsers.first(where: { $0.num == packet.to }) != nil && packet.to != Constants.maximumNodeNum { if !storeForwardBroadcast { newMessage.toUser = fetchedUsers.first(where: { $0.num == packet.to }) } } - if fetchedUsers.first(where: { $0.num == packet.from }) != nil { newMessage.fromUser = fetchedUsers.first(where: { $0.num == packet.from }) - if !(newMessage.fromUser?.publicKey?.isEmpty ?? true) && newMessage.toUser != nil && packet.pkiEncrypted { // We have a key and it is a PKC encrypted DM, check if it matches if newMessage.fromUser?.publicKey != newMessage.publicKey { newMessage.fromUser?.keyMatch = false newMessage.fromUser?.newPublicKey = newMessage.publicKey let nodeKey = String(newMessage.fromUser?.publicKey?.base64EncodedString() ?? "No Key").prefix(8) - let messageKey = String(newMessage.fromUser?.newPublicKey?.base64EncodedString() ?? "No Key").prefix(8) + let messageKey = String(newMessage.publicKey?.base64EncodedString() ?? "No Key").prefix(8) Logger.data.error("🔑 Key Mismatch origninal key: \(nodeKey, privacy: .public) . . . new key: \(messageKey, privacy: .public) . . .") } } else if packet.pkiEncrypted { @@ -902,17 +898,14 @@ func textMessageAppPacket( newMessage.fromUser?.publicKey = packet.publicKey } } - if packet.rxTime > 0 { newMessage.fromUser?.userNode?.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime))) } else { newMessage.fromUser?.userNode?.lastHeard = Date() } } - newMessage.messagePayload = messageText newMessage.messagePayloadMarkdown = generateMessageMarkdown(message: messageText!) - if packet.to != Constants.maximumNodeNum && newMessage.fromUser != nil { newMessage.fromUser?.lastMessage = Date() } From 94708e76cba86c1109bc4c5937444fc927b5019b Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 18 Sep 2024 18:25:20 -0700 Subject: [PATCH 4/8] fix logging typo, update lock icon on messages to only show for real acks --- Meshtastic/Helpers/MeshPackets.swift | 6 ++---- Meshtastic/Views/Messages/MessageText.swift | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index badac8ec..96b14cb0 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -883,13 +883,13 @@ func textMessageAppPacket( if fetchedUsers.first(where: { $0.num == packet.from }) != nil { newMessage.fromUser = fetchedUsers.first(where: { $0.num == packet.from }) if !(newMessage.fromUser?.publicKey?.isEmpty ?? true) && newMessage.toUser != nil && packet.pkiEncrypted { - // We have a key and it is a PKC encrypted DM, check if it matches + /// We have a key and it is a PKC encrypted DM, check if it matches if newMessage.fromUser?.publicKey != newMessage.publicKey { newMessage.fromUser?.keyMatch = false newMessage.fromUser?.newPublicKey = newMessage.publicKey let nodeKey = String(newMessage.fromUser?.publicKey?.base64EncodedString() ?? "No Key").prefix(8) let messageKey = String(newMessage.publicKey?.base64EncodedString() ?? "No Key").prefix(8) - Logger.data.error("🔑 Key Mismatch origninal key: \(nodeKey, privacy: .public) . . . new key: \(messageKey, privacy: .public) . . .") + Logger.data.error("🔑 Key mismatch original key: \(nodeKey, privacy: .public) . . . new key: \(messageKey, privacy: .public) . . .") } } else if packet.pkiEncrypted { /// We have no key, set it if it is not empty @@ -909,9 +909,7 @@ func textMessageAppPacket( if packet.to != Constants.maximumNodeNum && newMessage.fromUser != nil { newMessage.fromUser?.lastMessage = Date() } - var messageSaved = false - do { try context.save() Logger.data.info("💾 Saved a new message for \(newMessage.messageId)") diff --git a/Meshtastic/Views/Messages/MessageText.swift b/Meshtastic/Views/Messages/MessageText.swift index 93f8cf25..1f2cc017 100644 --- a/Meshtastic/Views/Messages/MessageText.swift +++ b/Meshtastic/Views/Messages/MessageText.swift @@ -30,7 +30,7 @@ struct MessageText: View { .background(isCurrentUser ? .accentColor : Color(.gray)) .cornerRadius(15) .overlay { - if message.pkiEncrypted { + if message.pkiEncrypted && message.ackError == 0 && message.realACK { VStack(alignment: .trailing) { Spacer() HStack { From 470f3432da4386c18ac61cee2270e92d1ff5962f Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 18 Sep 2024 18:50:46 -0700 Subject: [PATCH 5/8] Clean up key mis match logic --- Meshtastic/Helpers/MeshPackets.swift | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index 96b14cb0..27c41aeb 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -827,7 +827,7 @@ func textMessageAppPacket( } } let rangeTest = messageText?.contains(rangeTestRegex) ?? false && messageText?.starts(with: "seq ") ?? false - + if !wantRangeTestPackets && rangeTest { return } @@ -840,16 +840,13 @@ func textMessageAppPacket( } } } - + if messageText?.count ?? 0 > 0 { MeshLogger.log("💬 \("mesh.log.textmessage.received".localized)") - let messageUsers = UserEntity.fetchRequest() messageUsers.predicate = NSPredicate(format: "num IN %@", [packet.to, packet.from]) - do { let fetchedUsers = try context.fetch(messageUsers) - let newMessage = MessageEntity(context: context) newMessage.messageId = Int64(packet.id) if packet.rxTime > 0 { @@ -863,10 +860,6 @@ func textMessageAppPacket( newMessage.isEmoji = packet.decoded.emoji == 1 newMessage.channel = Int32(packet.channel) newMessage.portNum = Int32(packet.decoded.portnum.rawValue) - if newMessage.toUser?.pkiEncrypted ?? false { - newMessage.pkiEncrypted = true - newMessage.publicKey = packet.publicKey - } if packet.decoded.portnum == PortNum.detectionSensorApp { if !UserDefaults.enableDetectionNotifications { newMessage.read = true @@ -882,14 +875,21 @@ func textMessageAppPacket( } if fetchedUsers.first(where: { $0.num == packet.from }) != nil { newMessage.fromUser = fetchedUsers.first(where: { $0.num == packet.from }) - if !(newMessage.fromUser?.publicKey?.isEmpty ?? true) && newMessage.toUser != nil && packet.pkiEncrypted { - /// We have a key and it is a PKC encrypted DM, check if it matches - if newMessage.fromUser?.publicKey != newMessage.publicKey { - newMessage.fromUser?.keyMatch = false - newMessage.fromUser?.newPublicKey = newMessage.publicKey - let nodeKey = String(newMessage.fromUser?.publicKey?.base64EncodedString() ?? "No Key").prefix(8) - let messageKey = String(newMessage.publicKey?.base64EncodedString() ?? "No Key").prefix(8) - Logger.data.error("🔑 Key mismatch original key: \(nodeKey, privacy: .public) . . . new key: \(messageKey, privacy: .public) . . .") + /// Set the public key for the message + if newMessage.fromUser?.pkiEncrypted ?? false { + newMessage.pkiEncrypted = true + newMessage.publicKey = packet.publicKey + } + /// Check for key mismatch + if let nodeKey = newMessage.fromUser?.publicKey { + if newMessage.toUser != nil && packet.pkiEncrypted && !packet.publicKey.isEmpty { + if nodeKey != newMessage.publicKey { + newMessage.fromUser?.keyMatch = false + newMessage.fromUser?.newPublicKey = newMessage.publicKey + let nodeKey = String(nodeKey.base64EncodedString()).prefix(8) + let messageKey = String(newMessage.publicKey?.base64EncodedString() ?? "No Key").prefix(8) + Logger.data.error("🔑 Key mismatch original key: \(nodeKey, privacy: .public) . . . new key: \(messageKey, privacy: .public) . . .") + } } } else if packet.pkiEncrypted { /// We have no key, set it if it is not empty From 82e75ac6b5303faf965b1a0f4d27989d449f6e3d Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 19 Sep 2024 11:20:09 -0700 Subject: [PATCH 6/8] retry on unknown pub key --- Meshtastic/Enums/RoutingError.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meshtastic/Enums/RoutingError.swift b/Meshtastic/Enums/RoutingError.swift index 8b50de89..aa2a0c10 100644 --- a/Meshtastic/Enums/RoutingError.swift +++ b/Meshtastic/Enums/RoutingError.swift @@ -97,7 +97,7 @@ enum RoutingError: Int, CaseIterable, Identifiable { case .pkiFailed: return true case .pkiUnknownPubkey: - return false + return true } } func protoEnumValue() -> Routing.Error { From 799f5873148230f32a729b89bbbdd2bbeb71b429 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 19 Sep 2024 11:23:02 -0700 Subject: [PATCH 7/8] Update protos --- .../Sources/meshtastic/atak.pb.swift | 32 +++++++++++ .../Sources/meshtastic/clientonly.pb.swift | 54 +++++++++++++++++++ .../Sources/meshtastic/deviceonly.pb.swift | 14 +++-- .../Sources/meshtastic/mesh.pb.swift | 40 ++++++++++++-- protobufs | 2 +- 5 files changed, 131 insertions(+), 11 deletions(-) diff --git a/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift index 4406deb3..c756d94d 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift @@ -322,6 +322,17 @@ public struct TAKPacket { set {payloadVariant = .chat(newValue)} } + /// + /// Generic CoT detail XML + /// May be compressed / truncated by the sender + public var detail: Data { + get { + if case .detail(let v)? = payloadVariant {return v} + return Data() + } + set {payloadVariant = .detail(newValue)} + } + public var unknownFields = SwiftProtobuf.UnknownStorage() /// @@ -333,6 +344,10 @@ public struct TAKPacket { /// /// ATAK GeoChat message case chat(GeoChat) + /// + /// Generic CoT detail XML + /// May be compressed / truncated by the sender + case detail(Data) #if !swift(>=4.1) public static func ==(lhs: TAKPacket.OneOf_PayloadVariant, rhs: TAKPacket.OneOf_PayloadVariant) -> Bool { @@ -348,6 +363,10 @@ public struct TAKPacket { guard case .chat(let l) = lhs, case .chat(let r) = rhs else { preconditionFailure() } return l == r }() + case (.detail, .detail): return { + guard case .detail(let l) = lhs, case .detail(let r) = rhs else { preconditionFailure() } + return l == r + }() default: return false } } @@ -555,6 +574,7 @@ extension TAKPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation 4: .same(proto: "status"), 5: .same(proto: "pli"), 6: .same(proto: "chat"), + 7: .same(proto: "detail"), ] public mutating func decodeMessage(decoder: inout D) throws { @@ -593,6 +613,14 @@ extension TAKPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation self.payloadVariant = .chat(v) } }() + case 7: try { + var v: Data? + try decoder.decodeSingularBytesField(value: &v) + if let v = v { + if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} + self.payloadVariant = .detail(v) + } + }() default: break } } @@ -624,6 +652,10 @@ extension TAKPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation guard case .chat(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 6) }() + case .detail?: try { + guard case .detail(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularBytesField(value: v, fieldNumber: 7) + }() case nil: break } try unknownFields.traverse(visitor: &visitor) diff --git a/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift index c3d93bf7..f89a8e3c 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift @@ -83,6 +83,39 @@ public struct DeviceProfile { /// Clears the value of `moduleConfig`. Subsequent reads from it will return its default value. public mutating func clearModuleConfig() {self._moduleConfig = nil} + /// + /// Fixed position data + public var fixedPosition: Position { + get {return _fixedPosition ?? Position()} + set {_fixedPosition = newValue} + } + /// Returns true if `fixedPosition` has been explicitly set. + public var hasFixedPosition: Bool {return self._fixedPosition != nil} + /// Clears the value of `fixedPosition`. Subsequent reads from it will return its default value. + public mutating func clearFixedPosition() {self._fixedPosition = nil} + + /// + /// Ringtone for ExternalNotification + public var ringtone: String { + get {return _ringtone ?? String()} + set {_ringtone = newValue} + } + /// Returns true if `ringtone` has been explicitly set. + public var hasRingtone: Bool {return self._ringtone != nil} + /// Clears the value of `ringtone`. Subsequent reads from it will return its default value. + public mutating func clearRingtone() {self._ringtone = nil} + + /// + /// Predefined messages for CannedMessage + public var cannedMessages: String { + get {return _cannedMessages ?? String()} + set {_cannedMessages = newValue} + } + /// Returns true if `cannedMessages` has been explicitly set. + public var hasCannedMessages: Bool {return self._cannedMessages != nil} + /// Clears the value of `cannedMessages`. Subsequent reads from it will return its default value. + public mutating func clearCannedMessages() {self._cannedMessages = nil} + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -92,6 +125,9 @@ public struct DeviceProfile { fileprivate var _channelURL: String? = nil fileprivate var _config: LocalConfig? = nil fileprivate var _moduleConfig: LocalModuleConfig? = nil + fileprivate var _fixedPosition: Position? = nil + fileprivate var _ringtone: String? = nil + fileprivate var _cannedMessages: String? = nil } #if swift(>=5.5) && canImport(_Concurrency) @@ -110,6 +146,9 @@ extension DeviceProfile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa 3: .standard(proto: "channel_url"), 4: .same(proto: "config"), 5: .standard(proto: "module_config"), + 6: .standard(proto: "fixed_position"), + 7: .same(proto: "ringtone"), + 8: .standard(proto: "canned_messages"), ] public mutating func decodeMessage(decoder: inout D) throws { @@ -123,6 +162,9 @@ extension DeviceProfile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa case 3: try { try decoder.decodeSingularStringField(value: &self._channelURL) }() case 4: try { try decoder.decodeSingularMessageField(value: &self._config) }() case 5: try { try decoder.decodeSingularMessageField(value: &self._moduleConfig) }() + case 6: try { try decoder.decodeSingularMessageField(value: &self._fixedPosition) }() + case 7: try { try decoder.decodeSingularStringField(value: &self._ringtone) }() + case 8: try { try decoder.decodeSingularStringField(value: &self._cannedMessages) }() default: break } } @@ -148,6 +190,15 @@ extension DeviceProfile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa try { if let v = self._moduleConfig { try visitor.visitSingularMessageField(value: v, fieldNumber: 5) } }() + try { if let v = self._fixedPosition { + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + } }() + try { if let v = self._ringtone { + try visitor.visitSingularStringField(value: v, fieldNumber: 7) + } }() + try { if let v = self._cannedMessages { + try visitor.visitSingularStringField(value: v, fieldNumber: 8) + } }() try unknownFields.traverse(visitor: &visitor) } @@ -157,6 +208,9 @@ extension DeviceProfile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa if lhs._channelURL != rhs._channelURL {return false} if lhs._config != rhs._config {return false} if lhs._moduleConfig != rhs._moduleConfig {return false} + if lhs._fixedPosition != rhs._fixedPosition {return false} + if lhs._ringtone != rhs._ringtone {return false} + if lhs._cannedMessages != rhs._cannedMessages {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift index 43506399..3dd965f2 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift @@ -235,9 +235,13 @@ public struct NodeInfoLite { /// /// Number of hops away from us this node is (0 if adjacent) public var hopsAway: UInt32 { - get {return _storage._hopsAway} + get {return _storage._hopsAway ?? 0} set {_uniqueStorage()._hopsAway = newValue} } + /// Returns true if `hopsAway` has been explicitly set. + public var hasHopsAway: Bool {return _storage._hopsAway != nil} + /// Clears the value of `hopsAway`. Subsequent reads from it will return its default value. + public mutating func clearHopsAway() {_uniqueStorage()._hopsAway = nil} /// /// True if node is in our favorites list @@ -620,7 +624,7 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat var _deviceMetrics: DeviceMetrics? = nil var _channel: UInt32 = 0 var _viaMqtt: Bool = false - var _hopsAway: UInt32 = 0 + var _hopsAway: UInt32? = nil var _isFavorite: Bool = false #if swift(>=5.10) @@ -710,9 +714,9 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat if _storage._viaMqtt != false { try visitor.visitSingularBoolField(value: _storage._viaMqtt, fieldNumber: 8) } - if _storage._hopsAway != 0 { - try visitor.visitSingularUInt32Field(value: _storage._hopsAway, fieldNumber: 9) - } + try { if let v = _storage._hopsAway { + try visitor.visitSingularUInt32Field(value: v, fieldNumber: 9) + } }() if _storage._isFavorite != false { try visitor.visitSingularBoolField(value: _storage._isFavorite, fieldNumber: 10) } diff --git a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift index c7e8dc07..6bddec60 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift @@ -1416,6 +1416,14 @@ public struct Routing { /// /// The receiving node does not have a Public Key to decode with case pkiUnknownPubkey // = 35 + + /// + /// Admin packet otherwise checks out, but uses a bogus or expired session key + case adminBadSessionKey // = 36 + + /// + /// Admin packet sent using PKC, but not from a public key on the admin key list + case adminPublicKeyUnauthorized // = 37 case UNRECOGNIZED(Int) public init() { @@ -1438,6 +1446,8 @@ public struct Routing { case 33: self = .notAuthorized case 34: self = .pkiFailed case 35: self = .pkiUnknownPubkey + case 36: self = .adminBadSessionKey + case 37: self = .adminPublicKeyUnauthorized default: self = .UNRECOGNIZED(rawValue) } } @@ -1458,6 +1468,8 @@ public struct Routing { case .notAuthorized: return 33 case .pkiFailed: return 34 case .pkiUnknownPubkey: return 35 + case .adminBadSessionKey: return 36 + case .adminPublicKeyUnauthorized: return 37 case .UNRECOGNIZED(let i): return i } } @@ -1486,6 +1498,8 @@ extension Routing.Error: CaseIterable { .notAuthorized, .pkiFailed, .pkiUnknownPubkey, + .adminBadSessionKey, + .adminPublicKeyUnauthorized, ] } @@ -2167,9 +2181,13 @@ public struct NodeInfo { /// /// Number of hops away from us this node is (0 if adjacent) public var hopsAway: UInt32 { - get {return _storage._hopsAway} + get {return _storage._hopsAway ?? 0} set {_uniqueStorage()._hopsAway = newValue} } + /// Returns true if `hopsAway` has been explicitly set. + public var hasHopsAway: Bool {return _storage._hopsAway != nil} + /// Clears the value of `hopsAway`. Subsequent reads from it will return its default value. + public mutating func clearHopsAway() {_uniqueStorage()._hopsAway = nil} /// /// True if node is in our favorites list @@ -2997,6 +3015,10 @@ public struct DeviceMetadata { /// Has Remote Hardware enabled public var hasRemoteHardware_p: Bool = false + /// + /// Has PKC capabilities + public var hasPkc_p: Bool = false + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -3818,6 +3840,8 @@ extension Routing.Error: SwiftProtobuf._ProtoNameProviding { 33: .same(proto: "NOT_AUTHORIZED"), 34: .same(proto: "PKI_FAILED"), 35: .same(proto: "PKI_UNKNOWN_PUBKEY"), + 36: .same(proto: "ADMIN_BAD_SESSION_KEY"), + 37: .same(proto: "ADMIN_PUBLIC_KEY_UNAUTHORIZED"), ] } @@ -4326,7 +4350,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB var _deviceMetrics: DeviceMetrics? = nil var _channel: UInt32 = 0 var _viaMqtt: Bool = false - var _hopsAway: UInt32 = 0 + var _hopsAway: UInt32? = nil var _isFavorite: Bool = false #if swift(>=5.10) @@ -4416,9 +4440,9 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB if _storage._viaMqtt != false { try visitor.visitSingularBoolField(value: _storage._viaMqtt, fieldNumber: 8) } - if _storage._hopsAway != 0 { - try visitor.visitSingularUInt32Field(value: _storage._hopsAway, fieldNumber: 9) - } + try { if let v = _storage._hopsAway { + try visitor.visitSingularUInt32Field(value: v, fieldNumber: 9) + } }() if _storage._isFavorite != false { try visitor.visitSingularBoolField(value: _storage._isFavorite, fieldNumber: 10) } @@ -5281,6 +5305,7 @@ extension DeviceMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement 8: .standard(proto: "position_flags"), 9: .standard(proto: "hw_model"), 10: .same(proto: "hasRemoteHardware"), + 11: .same(proto: "hasPKC"), ] public mutating func decodeMessage(decoder: inout D) throws { @@ -5299,6 +5324,7 @@ extension DeviceMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement case 8: try { try decoder.decodeSingularUInt32Field(value: &self.positionFlags) }() case 9: try { try decoder.decodeSingularEnumField(value: &self.hwModel) }() case 10: try { try decoder.decodeSingularBoolField(value: &self.hasRemoteHardware_p) }() + case 11: try { try decoder.decodeSingularBoolField(value: &self.hasPkc_p) }() default: break } } @@ -5335,6 +5361,9 @@ extension DeviceMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement if self.hasRemoteHardware_p != false { try visitor.visitSingularBoolField(value: self.hasRemoteHardware_p, fieldNumber: 10) } + if self.hasPkc_p != false { + try visitor.visitSingularBoolField(value: self.hasPkc_p, fieldNumber: 11) + } try unknownFields.traverse(visitor: &visitor) } @@ -5349,6 +5378,7 @@ extension DeviceMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement if lhs.positionFlags != rhs.positionFlags {return false} if lhs.hwModel != rhs.hwModel {return false} if lhs.hasRemoteHardware_p != rhs.hasRemoteHardware_p {return false} + if lhs.hasPkc_p != rhs.hasPkc_p {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/protobufs b/protobufs index 0acaec6e..5709c0a0 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 0acaec6eff00e748beeae89148093221f131cd9c +Subproject commit 5709c0a05eaefccbc9cb8ed3917adbf5fd134197 From 39a456954bd550ab446d37dfc50eba093abcb362 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 19 Sep 2024 11:51:13 -0700 Subject: [PATCH 8/8] add new routing error messages --- Meshtastic/Enums/RoutingError.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Meshtastic/Enums/RoutingError.swift b/Meshtastic/Enums/RoutingError.swift index aa2a0c10..b3962a09 100644 --- a/Meshtastic/Enums/RoutingError.swift +++ b/Meshtastic/Enums/RoutingError.swift @@ -24,6 +24,8 @@ enum RoutingError: Int, CaseIterable, Identifiable { case notAuthorized = 33 case pkiFailed = 34 case pkiUnknownPubkey = 35 + case adminBadSessionKey = 36 + case adminPublicKeyUnauthorized = 37 var id: Int { self.rawValue } var display: String { @@ -57,6 +59,10 @@ enum RoutingError: Int, CaseIterable, Identifiable { return "routing.pkifailed".localized case .pkiUnknownPubkey: return "routing.pkiunknownpubkey".localized + case .adminBadSessionKey: + return "routing.adminbadsessionkey".localized + case .adminPublicKeyUnauthorized: + return "routing.adminpublickeyunauthorized".localized } } var color: Color { @@ -98,6 +104,10 @@ enum RoutingError: Int, CaseIterable, Identifiable { return true case .pkiUnknownPubkey: return true + case .adminBadSessionKey: + return true + case .adminPublicKeyUnauthorized: + return true } } func protoEnumValue() -> Routing.Error { @@ -132,6 +142,10 @@ enum RoutingError: Int, CaseIterable, Identifiable { return Routing.Error.pkiFailed case .pkiUnknownPubkey: return Routing.Error.pkiUnknownPubkey + case .adminBadSessionKey: + return Routing.Error.adminBadSessionKey + case .adminPublicKeyUnauthorized: + return Routing.Error.adminPublicKeyUnauthorized } } }