diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 6ea81c15..35592c2d 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -1704,7 +1704,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.5.10; + MARKETING_VERSION = 2.5.11; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1738,7 +1738,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.5.10; + MARKETING_VERSION = 2.5.11; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1770,7 +1770,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.5.10; + MARKETING_VERSION = 2.5.11; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1803,7 +1803,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.5.10; + MARKETING_VERSION = 2.5.11; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Meshtastic/Extensions/String.swift b/Meshtastic/Extensions/String.swift index 4e840a98..b001f2eb 100644 --- a/Meshtastic/Extensions/String.swift +++ b/Meshtastic/Extensions/String.swift @@ -61,11 +61,11 @@ extension String { } func camelCaseToWords() -> String { - return unicodeScalars.dropFirst().reduce(String(prefix(1))) { - return CharacterSet.uppercaseLetters.contains($1) - ? $0 + " " + String($1) - : $0 + String($1) - } + return self + .replacingOccurrences(of: "([a-z])([A-Z](?=[A-Z])[a-z]*)", with: "$1 $2", options: .regularExpression) + .replacingOccurrences(of: "([A-Z])([A-Z][a-z])", with: "$1 $2", options: .regularExpression) + .replacingOccurrences(of: "([a-z])([A-Z][a-z])", with: "$1 $2", options: .regularExpression) + .replacingOccurrences(of: "([a-z])([A-Z][a-z])", with: "$1 $2", options: .regularExpression) } var length: Int { diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index bb707885..90d9f978 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -27,7 +27,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate @Published var automaticallyReconnect: Bool = true @Published var mqttProxyConnected: Bool = false @Published var mqttError: String = "" - public var minimumVersion = "2.0.0" + public var minimumVersion = "2.3.2" public var connectedVersion: String public var isConnecting: Bool = false public var isConnected: Bool = false diff --git a/Meshtastic/Resources/DeviceHardware.json b/Meshtastic/Resources/DeviceHardware.json index 5e0135b9..94c74660 100644 --- a/Meshtastic/Resources/DeviceHardware.json +++ b/Meshtastic/Resources/DeviceHardware.json @@ -86,7 +86,8 @@ ], "images": [ "t-echo.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 8, @@ -113,7 +114,8 @@ "images": [ "rak4631.svg", "rak4631_case.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 10, @@ -150,7 +152,8 @@ ], "images": [ "tbeam-s3-core.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 13, @@ -204,7 +207,8 @@ ], "images": [ "tlora-t3s3-v1.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 16, @@ -219,7 +223,8 @@ ], "images": [ "tlora-t3s3-epaper.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 17, @@ -243,6 +248,10 @@ "displayName": "Nano G2 Ultra", "tags": [ "B&Q" + ], + "requiresDfu": true, + "images": [ + "nano-g2-ultra.svg" ] }, { @@ -258,7 +267,8 @@ ], "images": [ "wio-tracker-wm1110.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 25, @@ -282,7 +292,11 @@ "displayName": "RAK WisBlock 11310", "tags": [ "RAK" - ] + ], + "images": [ + "rak4631.svg" + ], + "requiresDfu": true }, { "hwModel": 29, @@ -294,7 +308,8 @@ "displayName": "Canary One", "tags": [ "Canary" - ] + ], + "requiresDfu": true }, { "hwModel": 30, @@ -306,7 +321,8 @@ "displayName": "RP2040 LoRa", "tags": [ "Waveshare" - ] + ], + "requiresDfu": true }, { "hwModel": 31, @@ -318,6 +334,10 @@ "displayName": "Station G2", "tags": [ "B&Q" + ], + "requiresDfu": true, + "images": [ + "station-g2.svg" ] }, { @@ -409,7 +429,8 @@ "tags": [ "Raspberry Pi", "DIY" - ] + ], + "requiresDfu": true }, { "hwModel": 47, @@ -422,7 +443,8 @@ "tags": [ "Raspberry Pi", "DIY" - ] + ], + "requiresDfu": true }, { "hwModel": 48, @@ -437,19 +459,21 @@ ], "images": [ "heltec-wireless-tracker.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 58, "hwModelSlug": "HELTEC_WIRELESS_TRACKER_V1_0", "platformioTarget": "heltec-wireless-tracker-V1-0", "architecture": "esp32-s3", - "activelySupported": true, + "activelySupported": false, "supportLevel": 3, "displayName": "Heltec Wireless Tracker V1.0", "images": [ "heltec-wireless-tracker.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 49, @@ -479,7 +503,8 @@ ], "images": [ "t-deck.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 51, @@ -525,7 +550,7 @@ "hwModelSlug": "HELTEC_WIRELESS_PAPER_V1_0", "platformioTarget": "heltec-wireless-paper-v1_0", "architecture": "esp32-s3", - "activelySupported": true, + "activelySupported": false, "supportLevel": 3, "tags": [ "Heltec" @@ -542,7 +567,8 @@ "architecture": "esp32-s3", "activelySupported": true, "supportLevel": 3, - "displayName": "unPhone" + "displayName": "unPhone", + "requiresDfu": true }, { "hwModel": 48, @@ -551,7 +577,8 @@ "architecture": "esp32-s3", "activelySupported": true, "supportLevel": 3, - "displayName": "TrackSenger (small TFT)" + "displayName": "TrackSenger (small TFT)", + "requiresDfu": true }, { "hwModel": 48, @@ -560,7 +587,8 @@ "architecture": "esp32-s3", "activelySupported": true, "supportLevel": 3, - "displayName": "TrackSenger (big TFT)" + "displayName": "TrackSenger (big TFT)", + "requiresDfu": true }, { "hwModel": 48, @@ -581,7 +609,8 @@ "displayName": "EBYTE EoRa-S3", "tags": [ "EByte" - ] + ], + "requiresDfu": true }, { "hwModel": 64, @@ -608,7 +637,8 @@ ], "images": [ "heltec-vision-master-t190.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 67, @@ -623,7 +653,8 @@ ], "images": [ "heltec-vision-master-e213.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 68, @@ -638,7 +669,8 @@ ], "images": [ "heltec-vision-master-e290.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 69, @@ -654,7 +686,8 @@ "images": [ "heltec-mesh-node-t114.svg", "heltec-mesh-node-t114-case.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 70, @@ -684,7 +717,8 @@ ], "images": [ "tracker-t1000-e.svg" - ] + ], + "requiresDfu": true }, { "hwModel": 72, @@ -699,6 +733,23 @@ ], "images": [ "seeed-xiao-s3.svg" - ] + ], + "requiresDfu": true + }, + { + "hwModel": 84, + "hwModelSlug": "WISMESH_TAP", + "platformioTarget": "rak_wismeshtap", + "architecture": "nrf52840", + "activelySupported": false, + "supportLevel": 1, + "displayName": "RAK WisMesh Tap", + "tags": [ + "RAK" + ], + "images": [ + "rak-wismeshtap.svg" + ], + "requiresDfu": true } ] diff --git a/Meshtastic/Views/Bluetooth/InvalidVersion.swift b/Meshtastic/Views/Bluetooth/InvalidVersion.swift index 9c0cca78..291722f4 100644 --- a/Meshtastic/Views/Bluetooth/InvalidVersion.swift +++ b/Meshtastic/Views/Bluetooth/InvalidVersion.swift @@ -44,8 +44,6 @@ struct InvalidVersion: View { Text("Version \(minimumVersion) includes breaking changes to devices and the client apps. Only nodes version \(minimumVersion) and above are supported.") .font(.callout) .padding([.leading, .trailing, .bottom]) - Link("Version 1.2 End of life (EOL) Info", destination: URL(string: "https://meshtastic.org/docs/1.2-End-of-life/")!) - .font(.callout) #if targetEnvironment(macCatalyst) Button { diff --git a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift index 37f989a5..d57dacba 100644 --- a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift +++ b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift @@ -103,7 +103,7 @@ struct BluetoothConfig: View { .onFirstAppear { // Need to request a BluetoothConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty bluetooth config") + let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -111,10 +111,12 @@ struct BluetoothConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.bluetoothConfig == nil { + Logger.mesh.info("⚙️ Empty or expired bluetooth config requesting via PKI admin") _ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty bluetooth config") _ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/DeviceConfig.swift b/Meshtastic/Views/Settings/Config/DeviceConfig.swift index f5fca283..da2978cf 100644 --- a/Meshtastic/Views/Settings/Config/DeviceConfig.swift +++ b/Meshtastic/Views/Settings/Config/DeviceConfig.swift @@ -78,7 +78,7 @@ struct DeviceConfig: View { .toggleStyle(SwitchToggleStyle(tint: .accentColor)) Toggle(isOn: $tripleClickAsAdHocPing) { - Label("Triple Click Ad Hoc Ping", systemImage: "map.pin") + Label("Triple Click Ad Hoc Ping", systemImage: "mappin") Text("Send a position on the primary channel when the user button is triple clicked.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) @@ -229,7 +229,6 @@ struct DeviceConfig: View { .onFirstAppear { // Need to request a DeviceConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty device config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -237,11 +236,13 @@ struct DeviceConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.deviceConfig == nil { + Logger.mesh.info("⚙️ Empty or expired device config requesting via PKI admin") _ = bleManager.requestDeviceConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { if node.deviceConfig == nil { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty device config") _ = bleManager.requestDeviceConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/DisplayConfig.swift b/Meshtastic/Views/Settings/Config/DisplayConfig.swift index 07975419..88839956 100644 --- a/Meshtastic/Views/Settings/Config/DisplayConfig.swift +++ b/Meshtastic/Views/Settings/Config/DisplayConfig.swift @@ -166,7 +166,6 @@ struct DisplayConfig: View { .onFirstAppear { // Need to request a DisplayConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty display config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -174,10 +173,12 @@ struct DisplayConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.displayConfig == nil { + Logger.mesh.info("⚙️ Empty or expired display config requesting via PKI admin") _ = bleManager.requestDisplayConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty display config") _ = bleManager.requestDisplayConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/LoRaConfig.swift b/Meshtastic/Views/Settings/Config/LoRaConfig.swift index 4c12c598..51461cf0 100644 --- a/Meshtastic/Views/Settings/Config/LoRaConfig.swift +++ b/Meshtastic/Views/Settings/Config/LoRaConfig.swift @@ -241,7 +241,6 @@ struct LoRaConfig: View { .onFirstAppear { // Need to request a LoRaConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty lora config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -249,10 +248,13 @@ struct LoRaConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.loRaConfig == nil { + Logger.mesh.info("⚙️ Empty or expired lora config requesting via PKI admin") + _ = bleManager.requestLoRaConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty lora config") _ = bleManager.requestLoRaConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift b/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift index fc82a4ca..62340da8 100644 --- a/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift @@ -88,7 +88,6 @@ struct AmbientLightingConfig: View { .onFirstAppear { // Need to request a Ambient Lighting Config from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty ambient lighting config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -96,10 +95,12 @@ struct AmbientLightingConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.ambientLightingConfig == nil { + Logger.mesh.info("⚙️ Empty or expired ambient lighting module config requesting via PKI admin") _ = bleManager.requestAmbientLightingConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty ambient lighting module config") _ = bleManager.requestAmbientLightingConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index 4f580b2a..b5dfee63 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -236,7 +236,6 @@ struct CannedMessagesConfig: View { .onFirstAppear { // Need to request a CannedMessagesModuleConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty canned message config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -244,10 +243,12 @@ struct CannedMessagesConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.cannedMessageConfig == nil { + Logger.mesh.info("⚙️ Empty or expired canned messages module config requesting via PKI admin") _ = bleManager.requestCannedMessagesModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty canned messages module config") _ = bleManager.requestCannedMessagesModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift index aff3dfea..59ee4f3f 100644 --- a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift @@ -194,7 +194,6 @@ struct DetectionSensorConfig: View { .onFirstAppear { // Need to request a DetectionSensorModuleConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty detection sensor config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -202,10 +201,12 @@ struct DetectionSensorConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.detectionSensorConfig == nil { + Logger.mesh.info("⚙️ Empty or expired detection sensor module config requesting via PKI admin") _ = bleManager.requestDetectionSensorModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty detection sensor module config") _ = bleManager.requestDetectionSensorModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift index a0f14c7f..9602c44b 100644 --- a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift @@ -202,7 +202,6 @@ struct ExternalNotificationConfig: View { .onFirstAppear { // Need to request a ExternalNotificationModuleConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty external notificaiton module config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -210,10 +209,12 @@ struct ExternalNotificationConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.externalNotificationConfig == nil { + Logger.mesh.info("⚙️ Empty or expired external notificaiton module config requesting via PKI admin") _ = bleManager.requestExternalNotificationModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty external notificaiton module config") _ = bleManager.requestExternalNotificationModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift index 224fd43c..6694097f 100644 --- a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift @@ -322,7 +322,6 @@ struct MQTTConfig: View { .onFirstAppear { // Need to request a MqttModuleConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty mqtt module config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -330,10 +329,12 @@ struct MQTTConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.mqttConfig == nil { + Logger.mesh.info("⚙️ Empty or expired mqtt module config requesting via PKI admin") _ = bleManager.requestMqttModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty mqtt module config") _ = bleManager.requestMqttModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift index 2fd97646..24af3504 100644 --- a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift @@ -61,7 +61,6 @@ struct PaxCounterConfig: View { .onFirstAppear { // Need to request a PaxCounterModuleConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty pax counter module config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -69,10 +68,12 @@ struct PaxCounterConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.paxCounterConfig == nil { + Logger.mesh.info("⚙️ Empty or expired pax counter module config requesting via PKI admin") _ = bleManager.requestPaxCounterModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty pax counter module config") _ = bleManager.requestPaxCounterModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift index ae4797fc..979eb736 100644 --- a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift @@ -84,7 +84,6 @@ struct RangeTestConfig: View { .onFirstAppear { // Need to request a RangeTestModuleConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty range test module config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -92,10 +91,12 @@ struct RangeTestConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.rangeTestConfig == nil { + Logger.mesh.info("⚙️ Empty or expired range test module config requesting via PKI admin") _ = bleManager.requestRangeTestModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty range test module config") _ = bleManager.requestRangeTestModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift b/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift index 2e0931a7..b81e2348 100644 --- a/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift @@ -75,7 +75,6 @@ struct RtttlConfig: View { .onFirstAppear { // Need to request a RtttlConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty range test module config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -83,10 +82,12 @@ struct RtttlConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.rtttlConfig == nil { + Logger.mesh.info("⚙️ Empty or expired ringtone module config requesting via PKI admin") _ = bleManager.requestRtttlConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty ringtone module config") _ = bleManager.requestRtttlConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift index a7fd5bdb..fd2c0c99 100644 --- a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift @@ -139,7 +139,6 @@ struct SerialConfig: View { .onFirstAppear { // Need to request a SerialModuleConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty serial module config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -147,10 +146,12 @@ struct SerialConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.serialConfig == nil { + Logger.mesh.info("⚙️ Empty or expired serial module config requesting via PKI admin") _ = bleManager.requestSerialModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty serial module config") _ = bleManager.requestSerialModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift index d90ea3fb..9c247acf 100644 --- a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift @@ -149,7 +149,6 @@ struct StoreForwardConfig: View { .onFirstAppear { // Need to request a StoreForwardModuleConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty store & forward module config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -157,10 +156,12 @@ struct StoreForwardConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.storeForwardConfig == nil { + Logger.mesh.info("⚙️ Empty or expired store & forward module config requesting via PKI admin") _ = bleManager.requestStoreAndForwardModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty store & forward module config") _ = bleManager.requestStoreAndForwardModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift index 4ba39834..ad173dae 100644 --- a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift @@ -137,7 +137,6 @@ struct TelemetryConfig: View { .onFirstAppear { // Need to request a TelemetryModuleConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty telemetry module config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -145,10 +144,12 @@ struct TelemetryConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.telemetryConfig == nil { + Logger.mesh.info("⚙️ Empty or expired telemetry module config requesting via PKI admin") _ = bleManager.requestTelemetryModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty telemetry module config") _ = bleManager.requestTelemetryModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/NetworkConfig.swift b/Meshtastic/Views/Settings/Config/NetworkConfig.swift index 8cebde85..84f48c41 100644 --- a/Meshtastic/Views/Settings/Config/NetworkConfig.swift +++ b/Meshtastic/Views/Settings/Config/NetworkConfig.swift @@ -133,7 +133,6 @@ struct NetworkConfig: View { .onFirstAppear { // Need to request a NetworkConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty network config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -141,10 +140,12 @@ struct NetworkConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.networkConfig == nil { + Logger.mesh.info("⚙️ Empty or expired network config requesting via PKI admin") _ = bleManager.requestNetworkConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty network config") _ = bleManager.requestNetworkConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/PositionConfig.swift b/Meshtastic/Views/Settings/Config/PositionConfig.swift index 451ac02d..f963b02b 100644 --- a/Meshtastic/Views/Settings/Config/PositionConfig.swift +++ b/Meshtastic/Views/Settings/Config/PositionConfig.swift @@ -410,7 +410,6 @@ struct PositionConfig: View { supportedVersion = bleManager.connectedVersion == "0.0.0" || self.minimumVersion.compare(bleManager.connectedVersion, options: .numeric) == .orderedAscending || minimumVersion.compare(bleManager.connectedVersion, options: .numeric) == .orderedSame // Need to request a NetworkConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty position config") let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -418,10 +417,12 @@ struct PositionConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.positionConfig == nil { + Logger.mesh.info("⚙️ Empty or expired position config requesting via PKI admin") _ = bleManager.requestPositionConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty position config") _ = bleManager.requestPositionConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/PowerConfig.swift b/Meshtastic/Views/Settings/Config/PowerConfig.swift index 822fd1e0..e9f7c0e5 100644 --- a/Meshtastic/Views/Settings/Config/PowerConfig.swift +++ b/Meshtastic/Views/Settings/Config/PowerConfig.swift @@ -130,7 +130,7 @@ struct PowerConfig: View { } // Need to request a NetworkConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty power config") + let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -138,10 +138,12 @@ struct PowerConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.powerConfig == nil { + Logger.mesh.info("⚙️ Empty or expired power config requesting via PKI admin") _ = bleManager.requestPowerConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty power config") _ = bleManager.requestPowerConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/Meshtastic/Views/Settings/Config/SecurityConfig.swift b/Meshtastic/Views/Settings/Config/SecurityConfig.swift index 5fb391b3..e62251c8 100644 --- a/Meshtastic/Views/Settings/Config/SecurityConfig.swift +++ b/Meshtastic/Views/Settings/Config/SecurityConfig.swift @@ -198,7 +198,8 @@ struct SecurityConfig: View { .onFirstAppear { // Need to request a DeviceConfig from the remote node before allowing changes if let connectedPeripheral = bleManager.connectedPeripheral, let node { - Logger.mesh.info("empty security config") + + let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) if let connectedNode { if node.num != connectedNode.num { @@ -206,11 +207,13 @@ struct SecurityConfig: View { /// 2.5 Administration with session passkey let expiration = node.sessionExpiration ?? Date() if expiration < Date() || node.securityConfig == nil { + Logger.mesh.info("⚙️ Empty or expired security config requesting via PKI admin") _ = bleManager.requestSecurityConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } else { if node.deviceConfig == nil { /// Legacy Administration + Logger.mesh.info("☠️ Using insecure legacy admin, empty security config") _ = bleManager.requestSecurityConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } diff --git a/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift index 9e7fe0c5..1f51447d 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift @@ -416,6 +416,26 @@ public struct AdminMessage { set {payloadVariant = .storeUiConfig(newValue)} } + /// + /// Set specified node-num to be ignored on the NodeDB on the device + public var setIgnoredNode: UInt32 { + get { + if case .setIgnoredNode(let v)? = payloadVariant {return v} + return 0 + } + set {payloadVariant = .setIgnoredNode(newValue)} + } + + /// + /// Set specified node-num to be un-ignored on the NodeDB on the device + public var removeIgnoredNode: UInt32 { + get { + if case .removeIgnoredNode(let v)? = payloadVariant {return v} + return 0 + } + set {payloadVariant = .removeIgnoredNode(newValue)} + } + /// /// Begins an edit transaction for config, module config, owner, and channel settings changes /// This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) @@ -633,6 +653,12 @@ public struct AdminMessage { /// Tell the node to store UI data persistently. case storeUiConfig(DeviceUIConfig) /// + /// Set specified node-num to be ignored on the NodeDB on the device + case setIgnoredNode(UInt32) + /// + /// Set specified node-num to be un-ignored on the NodeDB on the device + case removeIgnoredNode(UInt32) + /// /// Begins an edit transaction for config, module config, owner, and channel settings changes /// This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) case beginEditSettings(Bool) @@ -817,6 +843,14 @@ public struct AdminMessage { guard case .storeUiConfig(let l) = lhs, case .storeUiConfig(let r) = rhs else { preconditionFailure() } return l == r }() + case (.setIgnoredNode, .setIgnoredNode): return { + guard case .setIgnoredNode(let l) = lhs, case .setIgnoredNode(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.removeIgnoredNode, .removeIgnoredNode): return { + guard case .removeIgnoredNode(let l) = lhs, case .removeIgnoredNode(let r) = rhs else { preconditionFailure() } + return l == r + }() case (.beginEditSettings, .beginEditSettings): return { guard case .beginEditSettings(let l) = lhs, case .beginEditSettings(let r) = rhs else { preconditionFailure() } return l == r @@ -1184,6 +1218,8 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat 44: .standard(proto: "get_ui_config_request"), 45: .standard(proto: "get_ui_config_response"), 46: .standard(proto: "store_ui_config"), + 47: .standard(proto: "set_ignored_node"), + 48: .standard(proto: "remove_ignored_node"), 64: .standard(proto: "begin_edit_settings"), 65: .standard(proto: "commit_edit_settings"), 94: .standard(proto: "factory_reset_device"), @@ -1572,6 +1608,22 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat self.payloadVariant = .storeUiConfig(v) } }() + case 47: try { + var v: UInt32? + try decoder.decodeSingularUInt32Field(value: &v) + if let v = v { + if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} + self.payloadVariant = .setIgnoredNode(v) + } + }() + case 48: try { + var v: UInt32? + try decoder.decodeSingularUInt32Field(value: &v) + if let v = v { + if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} + self.payloadVariant = .removeIgnoredNode(v) + } + }() case 64: try { var v: Bool? try decoder.decodeSingularBoolField(value: &v) @@ -1804,6 +1856,14 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat guard case .storeUiConfig(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 46) }() + case .setIgnoredNode?: try { + guard case .setIgnoredNode(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularUInt32Field(value: v, fieldNumber: 47) + }() + case .removeIgnoredNode?: try { + guard case .removeIgnoredNode(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularUInt32Field(value: v, fieldNumber: 48) + }() case .beginEditSettings?: try { guard case .beginEditSettings(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularBoolField(value: v, fieldNumber: 64) diff --git a/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift index f677d644..6c4dbe93 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift @@ -134,6 +134,10 @@ public enum Language: SwiftProtobuf.Enum { /// Greek case greek // = 13 + /// + /// Norwegian + case norwegian // = 14 + /// /// Simplified Chinese (experimental) case simplifiedChinese // = 30 @@ -163,6 +167,7 @@ public enum Language: SwiftProtobuf.Enum { case 11: self = .russian case 12: self = .dutch case 13: self = .greek + case 14: self = .norwegian case 30: self = .simplifiedChinese case 31: self = .traditionalChinese default: self = .UNRECOGNIZED(rawValue) @@ -185,6 +190,7 @@ public enum Language: SwiftProtobuf.Enum { case .russian: return 11 case .dutch: return 12 case .greek: return 13 + case .norwegian: return 14 case .simplifiedChinese: return 30 case .traditionalChinese: return 31 case .UNRECOGNIZED(let i): return i @@ -212,6 +218,7 @@ extension Language: CaseIterable { .russian, .dutch, .greek, + .norwegian, .simplifiedChinese, .traditionalChinese, ] @@ -315,6 +322,13 @@ public struct DeviceUIConfig { /// Clears the value of `nodeHighlight`. Subsequent reads from it will return its default value. public mutating func clearNodeHighlight() {_uniqueStorage()._nodeHighlight = nil} + /// + /// 8 integers for screen calibration data + public var calibrationData: Data { + get {return _storage._calibrationData} + set {_uniqueStorage()._calibrationData = newValue} + } + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -422,6 +436,7 @@ extension Language: SwiftProtobuf._ProtoNameProviding { 11: .same(proto: "RUSSIAN"), 12: .same(proto: "DUTCH"), 13: .same(proto: "GREEK"), + 14: .same(proto: "NORWEGIAN"), 30: .same(proto: "SIMPLIFIED_CHINESE"), 31: .same(proto: "TRADITIONAL_CHINESE"), ] @@ -443,6 +458,7 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement 11: .same(proto: "language"), 12: .standard(proto: "node_filter"), 13: .standard(proto: "node_highlight"), + 14: .standard(proto: "calibration_data"), ] fileprivate class _StorageClass { @@ -459,6 +475,7 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement var _language: Language = .english var _nodeFilter: NodeFilter? = nil var _nodeHighlight: NodeHighlight? = nil + var _calibrationData: Data = Data() #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. @@ -486,6 +503,7 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement _language = source._language _nodeFilter = source._nodeFilter _nodeHighlight = source._nodeHighlight + _calibrationData = source._calibrationData } } @@ -517,6 +535,7 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement case 11: try { try decoder.decodeSingularEnumField(value: &_storage._language) }() case 12: try { try decoder.decodeSingularMessageField(value: &_storage._nodeFilter) }() case 13: try { try decoder.decodeSingularMessageField(value: &_storage._nodeHighlight) }() + case 14: try { try decoder.decodeSingularBytesField(value: &_storage._calibrationData) }() default: break } } @@ -568,6 +587,9 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement try { if let v = _storage._nodeHighlight { try visitor.visitSingularMessageField(value: v, fieldNumber: 13) } }() + if !_storage._calibrationData.isEmpty { + try visitor.visitSingularBytesField(value: _storage._calibrationData, fieldNumber: 14) + } } try unknownFields.traverse(visitor: &visitor) } @@ -590,6 +612,7 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement if _storage._language != rhs_storage._language {return false} if _storage._nodeFilter != rhs_storage._nodeFilter {return false} if _storage._nodeHighlight != rhs_storage._nodeHighlight {return false} + if _storage._calibrationData != rhs_storage._calibrationData {return false} return true } if !storagesAreEqual {return false} diff --git a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift index 3349c2c9..34a33373 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift @@ -196,6 +196,21 @@ public struct NodeInfoLite { set {_uniqueStorage()._isFavorite = newValue} } + /// + /// True if node is in our ignored list + /// Persists between NodeDB internal clean ups + public var isIgnored: Bool { + get {return _storage._isIgnored} + set {_uniqueStorage()._isIgnored = newValue} + } + + /// + /// Last byte of the node number of the node that should be used as the next hop to reach this node. + public var nextHop: UInt32 { + get {return _storage._nextHop} + set {_uniqueStorage()._nextHop = newValue} + } + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -486,6 +501,8 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat 8: .standard(proto: "via_mqtt"), 9: .standard(proto: "hops_away"), 10: .standard(proto: "is_favorite"), + 11: .standard(proto: "is_ignored"), + 12: .standard(proto: "next_hop"), ] fileprivate class _StorageClass { @@ -499,6 +516,8 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat var _viaMqtt: Bool = false var _hopsAway: UInt32? = nil var _isFavorite: Bool = false + var _isIgnored: Bool = false + var _nextHop: UInt32 = 0 #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. @@ -523,6 +542,8 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat _viaMqtt = source._viaMqtt _hopsAway = source._hopsAway _isFavorite = source._isFavorite + _isIgnored = source._isIgnored + _nextHop = source._nextHop } } @@ -551,6 +572,8 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat case 8: try { try decoder.decodeSingularBoolField(value: &_storage._viaMqtt) }() case 9: try { try decoder.decodeSingularUInt32Field(value: &_storage._hopsAway) }() case 10: try { try decoder.decodeSingularBoolField(value: &_storage._isFavorite) }() + case 11: try { try decoder.decodeSingularBoolField(value: &_storage._isIgnored) }() + case 12: try { try decoder.decodeSingularUInt32Field(value: &_storage._nextHop) }() default: break } } @@ -593,6 +616,12 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat if _storage._isFavorite != false { try visitor.visitSingularBoolField(value: _storage._isFavorite, fieldNumber: 10) } + if _storage._isIgnored != false { + try visitor.visitSingularBoolField(value: _storage._isIgnored, fieldNumber: 11) + } + if _storage._nextHop != 0 { + try visitor.visitSingularUInt32Field(value: _storage._nextHop, fieldNumber: 12) + } } try unknownFields.traverse(visitor: &visitor) } @@ -612,6 +641,8 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat if _storage._viaMqtt != rhs_storage._viaMqtt {return false} if _storage._hopsAway != rhs_storage._hopsAway {return false} if _storage._isFavorite != rhs_storage._isFavorite {return false} + if _storage._isIgnored != rhs_storage._isIgnored {return false} + if _storage._nextHop != rhs_storage._nextHop {return false} return true } if !storagesAreEqual {return false} diff --git a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift index 154d8a6b..434d1ec9 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift @@ -380,6 +380,11 @@ public enum HardwareModel: SwiftProtobuf.Enum { /// Lilygo TLora-C6 with the new ESP32-C6 MCU case tloraC6 // = 83 + /// + /// WisMesh Tap + /// RAK-4631 w/ TFT in injection modled case + case wismeshTap // = 84 + /// /// ------------------------------------------------------------------------------------------------------------------------------------------ /// 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. @@ -477,6 +482,7 @@ public enum HardwareModel: SwiftProtobuf.Enum { case 81: self = .seeedXiaoS3 case 82: self = .ms24Sf1 case 83: self = .tloraC6 + case 84: self = .wismeshTap case 255: self = .privateHw default: self = .UNRECOGNIZED(rawValue) } @@ -568,6 +574,7 @@ public enum HardwareModel: SwiftProtobuf.Enum { case .seeedXiaoS3: return 81 case .ms24Sf1: return 82 case .tloraC6: return 83 + case .wismeshTap: return 84 case .privateHw: return 255 case .UNRECOGNIZED(let i): return i } @@ -664,6 +671,7 @@ extension HardwareModel: CaseIterable { .seeedXiaoS3, .ms24Sf1, .tloraC6, + .wismeshTap, .privateHw, ] } @@ -684,7 +692,7 @@ public enum Constants: SwiftProtobuf.Enum { /// From mesh.options /// note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is /// outside of this envelope - case dataPayloadLen // = 237 + case dataPayloadLen // = 233 case UNRECOGNIZED(Int) public init() { @@ -694,7 +702,7 @@ public enum Constants: SwiftProtobuf.Enum { public init?(rawValue: Int) { switch rawValue { case 0: self = .zero - case 237: self = .dataPayloadLen + case 233: self = .dataPayloadLen default: self = .UNRECOGNIZED(rawValue) } } @@ -702,7 +710,7 @@ public enum Constants: SwiftProtobuf.Enum { public var rawValue: Int { switch self { case .zero: return 0 - case .dataPayloadLen: return 237 + case .dataPayloadLen: return 233 case .UNRECOGNIZED(let i): return i } } @@ -2055,6 +2063,22 @@ public struct MeshPacket { set {_uniqueStorage()._pkiEncrypted = newValue} } + /// + /// Last byte of the node number of the node that should be used as the next hop in routing. + /// Set by the firmware internally, clients are not supposed to set this. + public var nextHop: UInt32 { + get {return _storage._nextHop} + set {_uniqueStorage()._nextHop = newValue} + } + + /// + /// Last byte of the node number of the node that will relay/relayed this packet. + /// Set by the firmware internally, clients are not supposed to set this. + public var relayNode: UInt32 { + get {return _storage._relayNode} + set {_uniqueStorage()._relayNode = newValue} + } + public var unknownFields = SwiftProtobuf.UnknownStorage() public enum OneOf_PayloadVariant: Equatable { @@ -2370,6 +2394,14 @@ public struct NodeInfo { set {_uniqueStorage()._isFavorite = newValue} } + /// + /// True if node is in our ignored list + /// Persists between NodeDB internal clean ups + public var isIgnored: Bool { + get {return _storage._isIgnored} + set {_uniqueStorage()._isIgnored = newValue} + } + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -3526,6 +3558,7 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { 81: .same(proto: "SEEED_XIAO_S3"), 82: .same(proto: "MS24SF1"), 83: .same(proto: "TLORA_C6"), + 84: .same(proto: "WISMESH_TAP"), 255: .same(proto: "PRIVATE_HW"), ] } @@ -3533,7 +3566,7 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { extension Constants: SwiftProtobuf._ProtoNameProviding { public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 0: .same(proto: "ZERO"), - 237: .same(proto: "DATA_PAYLOAD_LEN"), + 233: .same(proto: "DATA_PAYLOAD_LEN"), ] } @@ -4328,6 +4361,8 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio 15: .standard(proto: "hop_start"), 16: .standard(proto: "public_key"), 17: .standard(proto: "pki_encrypted"), + 18: .standard(proto: "next_hop"), + 19: .standard(proto: "relay_node"), ] fileprivate class _StorageClass { @@ -4347,6 +4382,8 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio var _hopStart: UInt32 = 0 var _publicKey: Data = Data() var _pkiEncrypted: Bool = false + var _nextHop: UInt32 = 0 + var _relayNode: UInt32 = 0 #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. @@ -4377,6 +4414,8 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio _hopStart = source._hopStart _publicKey = source._publicKey _pkiEncrypted = source._pkiEncrypted + _nextHop = source._nextHop + _relayNode = source._relayNode } } @@ -4431,6 +4470,8 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio case 15: try { try decoder.decodeSingularUInt32Field(value: &_storage._hopStart) }() case 16: try { try decoder.decodeSingularBytesField(value: &_storage._publicKey) }() case 17: try { try decoder.decodeSingularBoolField(value: &_storage._pkiEncrypted) }() + case 18: try { try decoder.decodeSingularUInt32Field(value: &_storage._nextHop) }() + case 19: try { try decoder.decodeSingularUInt32Field(value: &_storage._relayNode) }() default: break } } @@ -4499,6 +4540,12 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if _storage._pkiEncrypted != false { try visitor.visitSingularBoolField(value: _storage._pkiEncrypted, fieldNumber: 17) } + if _storage._nextHop != 0 { + try visitor.visitSingularUInt32Field(value: _storage._nextHop, fieldNumber: 18) + } + if _storage._relayNode != 0 { + try visitor.visitSingularUInt32Field(value: _storage._relayNode, fieldNumber: 19) + } } try unknownFields.traverse(visitor: &visitor) } @@ -4524,6 +4571,8 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if _storage._hopStart != rhs_storage._hopStart {return false} if _storage._publicKey != rhs_storage._publicKey {return false} if _storage._pkiEncrypted != rhs_storage._pkiEncrypted {return false} + if _storage._nextHop != rhs_storage._nextHop {return false} + if _storage._relayNode != rhs_storage._relayNode {return false} return true } if !storagesAreEqual {return false} @@ -4568,6 +4617,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB 8: .standard(proto: "via_mqtt"), 9: .standard(proto: "hops_away"), 10: .standard(proto: "is_favorite"), + 11: .standard(proto: "is_ignored"), ] fileprivate class _StorageClass { @@ -4581,6 +4631,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB var _viaMqtt: Bool = false var _hopsAway: UInt32? = nil var _isFavorite: Bool = false + var _isIgnored: Bool = false #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. @@ -4605,6 +4656,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB _viaMqtt = source._viaMqtt _hopsAway = source._hopsAway _isFavorite = source._isFavorite + _isIgnored = source._isIgnored } } @@ -4633,6 +4685,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB case 8: try { try decoder.decodeSingularBoolField(value: &_storage._viaMqtt) }() case 9: try { try decoder.decodeSingularUInt32Field(value: &_storage._hopsAway) }() case 10: try { try decoder.decodeSingularBoolField(value: &_storage._isFavorite) }() + case 11: try { try decoder.decodeSingularBoolField(value: &_storage._isIgnored) }() default: break } } @@ -4675,6 +4728,9 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB if _storage._isFavorite != false { try visitor.visitSingularBoolField(value: _storage._isFavorite, fieldNumber: 10) } + if _storage._isIgnored != false { + try visitor.visitSingularBoolField(value: _storage._isIgnored, fieldNumber: 11) + } } try unknownFields.traverse(visitor: &visitor) } @@ -4694,6 +4750,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB if _storage._viaMqtt != rhs_storage._viaMqtt {return false} if _storage._hopsAway != rhs_storage._hopsAway {return false} if _storage._isFavorite != rhs_storage._isFavorite {return false} + if _storage._isIgnored != rhs_storage._isIgnored {return false} return true } if !storagesAreEqual {return false} diff --git a/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift index e67b5272..1ce50e07 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift @@ -156,6 +156,10 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum { /// /// SCD40/SCD41 CO2, humidity, temperature sensor case scd4X // = 32 + + /// + /// ClimateGuard RadSens, radiation, Geiger-Muller Tube + case radsens // = 33 case UNRECOGNIZED(Int) public init() { @@ -197,6 +201,7 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum { case 30: self = .max30102 case 31: self = .mlx90614 case 32: self = .scd4X + case 33: self = .radsens default: self = .UNRECOGNIZED(rawValue) } } @@ -236,6 +241,7 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum { case .max30102: return 30 case .mlx90614: return 31 case .scd4X: return 32 + case .radsens: return 33 case .UNRECOGNIZED(let i): return i } } @@ -280,6 +286,7 @@ extension TelemetrySensorType: CaseIterable { .max30102, .mlx90614, .scd4X, + .radsens, ] } @@ -554,6 +561,17 @@ public struct EnvironmentMetrics { /// Clears the value of `windLull`. Subsequent reads from it will return its default value. public mutating func clearWindLull() {_uniqueStorage()._windLull = nil} + /// + /// Radiation in µR/h + public var radiation: Float { + get {return _storage._radiation ?? 0} + set {_uniqueStorage()._radiation = newValue} + } + /// Returns true if `radiation` has been explicitly set. + public var hasRadiation: Bool {return _storage._radiation != nil} + /// Clears the value of `radiation`. Subsequent reads from it will return its default value. + public mutating func clearRadiation() {_uniqueStorage()._radiation = nil} + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -1128,6 +1146,7 @@ extension TelemetrySensorType: SwiftProtobuf._ProtoNameProviding { 30: .same(proto: "MAX30102"), 31: .same(proto: "MLX90614"), 32: .same(proto: "SCD4X"), + 33: .same(proto: "RADSENS"), ] } @@ -1211,6 +1230,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple 15: .same(proto: "weight"), 16: .standard(proto: "wind_gust"), 17: .standard(proto: "wind_lull"), + 18: .same(proto: "radiation"), ] fileprivate class _StorageClass { @@ -1231,6 +1251,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple var _weight: Float? = nil var _windGust: Float? = nil var _windLull: Float? = nil + var _radiation: Float? = nil #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. @@ -1262,6 +1283,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple _weight = source._weight _windGust = source._windGust _windLull = source._windLull + _radiation = source._radiation } } @@ -1297,6 +1319,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple case 15: try { try decoder.decodeSingularFloatField(value: &_storage._weight) }() case 16: try { try decoder.decodeSingularFloatField(value: &_storage._windGust) }() case 17: try { try decoder.decodeSingularFloatField(value: &_storage._windLull) }() + case 18: try { try decoder.decodeSingularFloatField(value: &_storage._radiation) }() default: break } } @@ -1360,6 +1383,9 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple try { if let v = _storage._windLull { try visitor.visitSingularFloatField(value: v, fieldNumber: 17) } }() + try { if let v = _storage._radiation { + try visitor.visitSingularFloatField(value: v, fieldNumber: 18) + } }() } try unknownFields.traverse(visitor: &visitor) } @@ -1386,6 +1412,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if _storage._weight != rhs_storage._weight {return false} if _storage._windGust != rhs_storage._windGust {return false} if _storage._windLull != rhs_storage._windLull {return false} + if _storage._radiation != rhs_storage._radiation {return false} return true } if !storagesAreEqual {return false} diff --git a/protobufs b/protobufs index 04f21f5c..02e6576e 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 04f21f5c7238b8e02f794d9282c4786752634b3c +Subproject commit 02e6576efaa2f691be9504b8c1c6261703f7a277