diff --git a/Localizable.xcstrings b/Localizable.xcstrings index 9bbbd0bd..33be032d 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -1486,8 +1486,8 @@ } } }, - "⚠️ The configured value: (%@ seconds) is not one of the optimized options." : { - "comment" : "A text warning that the configured update interval is not one of the optimized options.", + "⚠️ The configured value: (%@) is not one of the optimized options." : { + "comment" : "A warning label below the picker, indicating that the selected update interval is not one of the optimized options.", "isCommentAutoGenerated" : true }, "🦕 End of life Version 🦖 ☄️" : { @@ -3854,7 +3854,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Ambient Lighting module config received: %@" + "value" : "收到环境照明模块配置: %@" } }, "zh-Hant-TW" : { @@ -3905,10 +3905,6 @@ } } }, - "Anonymous Usage and Crash data" : { - "comment" : "A description of how the app collects and uses data about its usage and crashes. It emphasizes that this data is anonymous and non-personally identifiable.", - "isCommentAutoGenerated" : true - }, "Any missed messages will be delivered again." : { "localizations" : { "it" : { @@ -5139,6 +5135,12 @@ } } } + }, + "Bearing: %@" : { + + }, + "Bearing: N/A" : { + }, "Biking" : { "localizations" : { @@ -5459,7 +5461,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Bluetooth config received: %@" + "value" : "收到蓝牙配置: %@" } }, "zh-Hant-TW" : { @@ -6127,7 +6129,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Canned Message module config received: %@" + "value" : "收到预设消息模块配置: %@" } }, "zh-Hant-TW" : { @@ -6313,7 +6315,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Canned Messages Messages Received For: %@" + "value" : "收到预设消息: %@" } }, "zh-Hant-TW" : { @@ -7666,6 +7668,10 @@ } } }, + "Client Base should only favorite other nodes you control. Improper use will hurt your local mesh." : { + "comment" : "A message displayed in a confirmation dialog when trying to favorite a node as a CLIENT_BASE.", + "isCommentAutoGenerated" : true + }, "Client Hidden" : { "localizations" : { "de" : { @@ -8085,6 +8091,9 @@ } } } + }, + "Compass" : { + }, "Config" : { "localizations" : { @@ -10412,7 +10421,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Detection Sensor module config received: %@" + "value" : "收到检测传感器模块配置: %@" } }, "zh-Hant-TW" : { @@ -10638,7 +10647,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Device config received: %@" + "value" : "收到设备配置: %@" } }, "zh-Hant-TW" : { @@ -10822,7 +10831,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Device Metadata admin message received from: %@" + "value" : "已收到来自设备元数据管理员的消息, 来自: %@" } }, "zh-Hant-TW" : { @@ -11795,7 +11804,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Display config received: %@" + "value" : "收到显示屏配置: %@" } }, "zh-Hant-TW" : { @@ -11829,7 +11838,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "展示华氏度" + "value" : "显示华氏度" } }, "zh-Hant-TW" : { @@ -11995,6 +12004,9 @@ } } } + }, + "Distance: %@" : { + }, "Documentation" : { "localizations" : { @@ -12081,7 +12093,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "双击作为按钮" + "value" : "双击代替按钮" } }, "zh-Hant-TW" : { @@ -12417,7 +12429,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "回声" + "value" : "回显" } }, "zh-Hant-TW" : { @@ -13399,7 +13411,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "擦除所有 App 数据?" + "value" : "删除所有 App 数据?" } }, "zh-Hant-TW" : { @@ -13439,7 +13451,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "擦除所有设备和 App 数据?" + "value" : "删除所有设备和 App 数据?" } }, "zh-Hant-TW" : { @@ -14083,7 +14095,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "External Notification module config received: %@" + "value" : "收到外部通知模块配置: %@" } }, "zh-Hant-TW" : { @@ -14700,7 +14712,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Finish" + "value" : "完成" } }, "zh-Hant-TW" : { @@ -14791,7 +14803,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "固件升级文档" + "value" : "固件升级文件" } }, "zh-Hant-TW" : { @@ -16433,7 +16445,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "GPS Receive GPIO" + "value" : "GPS 接收 GPIO" } }, "zh-Hant-TW" : { @@ -16467,7 +16479,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "GPS Transmit GPIO" + "value" : "GPS 发送 GPIO" } }, "zh-Hant-TW" : { @@ -17989,7 +18001,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "如果难以访问设备的重置按钮,请在此进入 DFU 模式。" + "value" : "如果难以触及设备的重置按钮,请在此进入 DFU 模式。" } }, "zh-Hant-TW" : { @@ -18023,7 +18035,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "如果设置了,您发送的任何数据包都会回传到设备。" + "value" : "如果设置,您发送的任何数据包都会回传到设备。" } }, "zh-Hant-TW" : { @@ -18611,7 +18623,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "倒置顶栏,用于双色显示" + "value" : "倒置顶栏,用于双色显示屏" } }, "zh-Hant-TW" : { @@ -18925,6 +18937,13 @@ } } } + }, + "Last seen device:" : { + "comment" : "A label displayed next to the last seen device text in the `DeviceConnectRow`.", + "isCommentAutoGenerated" : true + }, + "Last seen device: %@" : { + }, "Latitude" : { "localizations" : { @@ -20015,7 +20034,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "LoRa config received: %@" + "value" : "收到 LoRa 配置: %@" } }, "zh-Hant-TW" : { @@ -20445,6 +20464,9 @@ } } } + }, + "Manual Connections" : { + }, "Map Data" : { "localizations" : { @@ -20929,6 +20951,9 @@ } } } + }, + "Meshtastic does not collect any personal information. We do anonymously collect usage and crash data to improve the app. You can opt out under app settings." : { + }, "Meshtastic Node %@ has shared channels with you" : { "localizations" : { @@ -21193,7 +21218,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Message received from the text message app." + "value" : "收到来自短信应用的消息。" } }, "zh-Hant-TW" : { @@ -22196,7 +22221,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "MyInfo received: %@" + "value" : "收到我的消息: %@" } }, "zh-Hant-TW" : { @@ -22556,7 +22581,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Network config received: %@" + "value" : "收到网络配置: %@" } }, "zh-Hant-TW" : { @@ -24754,6 +24779,9 @@ } } } + }, + "Open Compass" : { + }, "Open Settings" : { "localizations" : { @@ -25742,7 +25770,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "PAX Counter message received for: %@" + "value" : "收到 PAX 计数信息: %@" } }, "zh-Hant-TW" : { @@ -27464,7 +27492,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Process" + "value" : "处理" } }, "zh-Hant-TW" : { @@ -28470,6 +28498,7 @@ } }, "Received Ack" : { + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -28532,8 +28561,12 @@ } } } + }, + "Received Ack: %@" : { + }, "Recipient Ack" : { + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -28596,6 +28629,9 @@ } } } + }, + "Recipient Ack: %@" : { + }, "Recording route" : { "localizations" : { @@ -28779,6 +28815,16 @@ } } }, + "Relayed by %d %@" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Relayed by %1$d %2$@" + } + } + } + }, "Release Notes" : { "localizations" : { "it" : { @@ -29228,7 +29274,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Requested Canned Messages Module Messages for node: %@" + "value" : "请求的节点预设消息模块消息: %@" } }, "zh-Hant-TW" : { @@ -30356,7 +30402,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Routing received for RequestID: %@ Ack Status: %@" + "value" : "收到请求ID为 %@ 的路由, Ack 状态: %@" } }, "zh-Hant-TW" : { @@ -30504,7 +30550,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "RTTTL Ringtone config received: %@" + "value" : "收到 RTTTL 铃声配置: %@" } }, "zh-Hant-TW" : { @@ -32306,7 +32352,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Sent a Channel for: %@ Channel Index %d" + "value" : "已发送频道: %@ 频道索引 %d" } }, "zh-Hant-TW" : { @@ -32370,7 +32416,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Sent a LoRa.Config for: %@" + "value" : "发送 LoRa.Config 给: %@" } }, "zh-Hant-TW" : { @@ -32435,7 +32481,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Sent a Position Packet from the Apple device GPS to node: %@" + "value" : "从苹果设备 GPS 发送定位数据包给节点: %@" } }, "zh-Hant-TW" : { @@ -32499,7 +32545,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Sent a Trace Route Request to node: %@" + "value" : "发送跟踪路由请求到节点: %@" } }, "zh-Hant-TW" : { @@ -32563,7 +32609,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Sent a Waypoint Packet from: %@" + "value" : "发送来自的航点数据包: %@" } }, "zh-Hant-TW" : { @@ -32627,7 +32673,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Sent message %@ from %@ to %@" + "value" : "发送消息 %@ 来自 %@ 给 %@" } }, "zh-Hant-TW" : { @@ -32949,7 +32995,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Serial module config received: %@" + "value" : "收到串口模块配置: %@" } }, "zh-Hant-TW" : { @@ -35131,7 +35177,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Store & Forward module config received: %@" + "value" : "收到存储和转发模块配置: %@" } }, "zh-Hant-TW" : { @@ -35750,7 +35796,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Telemetry module config received: %@" + "value" : "收到遥测模块配置: %@" } }, "zh-Hant-TW" : { @@ -36743,7 +36789,12 @@ } } }, + "These settings will %@" : { + "comment" : "A paragraph below the title that explains what the user is about to do.", + "isCommentAutoGenerated" : true + }, "These settings will %@ channels. The current LoRa Config will be replaced, if there are substantial changes to the LoRa config the device will reboot" : { + "extractionState" : "stale", "localizations" : { "it" : { "stringUnit" : { @@ -38000,7 +38051,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Trace Route request returned: %@" + "value" : "跟踪路由请求回复: %@" } }, "zh-Hant-TW" : { @@ -40176,6 +40227,9 @@ } } } + }, + "User Privacy" : { + }, "User Uploaded" : { "comment" : "Data source label for user uploaded files", @@ -41027,7 +41081,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Waypoint Packet received from node: %@" + "value" : "收到航点数据包, 来自节点: %@" } }, "zh-Hant-TW" : { @@ -41040,10 +41094,6 @@ }, "Waypoints" : { - }, - "We anonymously collect usage and crash data to improve the app. This helps us understand how the app is being used and where we can make improvements. The data we collect is non-personally identifiable and cannot be linked to you as an individual. You can opt out of this under app settings." : { - "comment" : "A description of how the app collects and uses user data. Includes a link to the app settings.", - "isCommentAutoGenerated" : true }, "Weather Conditions" : { "localizations" : { @@ -41220,7 +41270,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "锁意味着什么?" + "value" : "锁头图标含义" } }, "zh-Hant-TW" : { @@ -41260,7 +41310,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "什么是 Meshtastic?" + "value" : "Meshtastic 是什么?" } }, "zh-Hant-TW" : { @@ -41854,6 +41904,10 @@ } } }, + "Yes, I control this node" : { + "comment" : "A button label that appears in a confirmation sheet when favoriting a node as a CLIENT_BASE.", + "isCommentAutoGenerated" : true + }, "Yesterday" : { "localizations" : { "de" : { @@ -42267,4 +42321,4 @@ } }, "version" : "1.1" -} \ No newline at end of file +} diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 63f334e5..b87ce5f2 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ 2344A2B12D68DFF800170A77 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25C49D8F2C471AEA0024FBD1 /* Constants.swift */; }; 2346A7192E2FB9A300CB9239 /* SerialConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2346A7182E2FB9A300CB9239 /* SerialConnection.swift */; }; 2346A71D2E2FB9C500CB9239 /* SerialTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2346A71C2E2FB9C500CB9239 /* SerialTransport.swift */; }; + 2349A04A2EAE4DA30060A581 /* ManualConnectionList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2349A0492EAE4DA30060A581 /* ManualConnectionList.swift */; }; 2373AE132D0A216C0086C749 /* MetricsChartSeries.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2373AE122D0A216C0086C749 /* MetricsChartSeries.swift */; }; 2373AE152D0A24930086C749 /* MetricsSeriesList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2373AE142D0A24930086C749 /* MetricsSeriesList.swift */; }; 2373AE172D0A26620086C749 /* EnvironmentDefaultSeries.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2373AE162D0A26620086C749 /* EnvironmentDefaultSeries.swift */; }; @@ -97,6 +98,7 @@ B3E905B12B71F7F300654D07 /* TextMessageField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3E905B02B71F7F300654D07 /* TextMessageField.swift */; }; BC10380F2DD4334400B00BFA /* AddContactIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC10380E2DD4333C00B00BFA /* AddContactIntent.swift */; }; BC6B45FF2CB2F98900723CEB /* SaveChannelSettingsIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC6B45FE2CB2F98900723CEB /* SaveChannelSettingsIntent.swift */; }; + BCA9A82C2EC802CF00166292 /* CompassView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCA9A82B2EC802CF00166292 /* CompassView.swift */; }; BCB35B4F2E5FC42500B04F60 /* MessageNodeIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB35B4E2E5FC41E00B04F60 /* MessageNodeIntent.swift */; }; BCB613812C67290800485544 /* SendWaypointIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613802C67290800485544 /* SendWaypointIntent.swift */; }; BCB613832C672A2600485544 /* MessageChannelIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613822C672A2600485544 /* MessageChannelIntent.swift */; }; @@ -357,6 +359,7 @@ 2344A2AE2D6697A700170A77 /* TelemetryEntity+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TelemetryEntity+CoreDataProperties.swift"; sourceTree = ""; }; 2346A7182E2FB9A300CB9239 /* SerialConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerialConnection.swift; sourceTree = ""; }; 2346A71C2E2FB9C500CB9239 /* SerialTransport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerialTransport.swift; sourceTree = ""; }; + 2349A0492EAE4DA30060A581 /* ManualConnectionList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualConnectionList.swift; sourceTree = ""; }; 2373AE122D0A216C0086C749 /* MetricsChartSeries.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetricsChartSeries.swift; sourceTree = ""; }; 2373AE142D0A24930086C749 /* MetricsSeriesList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetricsSeriesList.swift; sourceTree = ""; }; 2373AE162D0A26620086C749 /* EnvironmentDefaultSeries.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentDefaultSeries.swift; sourceTree = ""; }; @@ -407,6 +410,7 @@ B3E905B02B71F7F300654D07 /* TextMessageField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextMessageField.swift; sourceTree = ""; }; BC10380E2DD4333C00B00BFA /* AddContactIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactIntent.swift; sourceTree = ""; }; BC6B45FE2CB2F98900723CEB /* SaveChannelSettingsIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveChannelSettingsIntent.swift; sourceTree = ""; }; + BCA9A82B2EC802CF00166292 /* CompassView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompassView.swift; sourceTree = ""; }; BCB35B4E2E5FC41E00B04F60 /* MessageNodeIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageNodeIntent.swift; sourceTree = ""; }; BCB613802C67290800485544 /* SendWaypointIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendWaypointIntent.swift; sourceTree = ""; }; BCB613822C672A2600485544 /* MessageChannelIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageChannelIntent.swift; sourceTree = ""; }; @@ -832,6 +836,7 @@ 23D316922E5618D2002FA4FB /* AsyncGate.swift */, 23E23F912E392C2B00919073 /* LogRecord+StringRepresentation.swift */, 23D9D9382E50DA97005D1C18 /* ResettableTimer.swift */, + 2349A0492EAE4DA30060A581 /* ManualConnectionList.swift */, ); path = Helpers; sourceTree = ""; @@ -1271,6 +1276,7 @@ 8D3F8A3E2D44BB02009EAAA4 /* PowerMetrics.swift */, 237B46952DC8F1C100B22D99 /* RateLimitedButton.swift */, 23A1AFB62E42BD2500E46C96 /* RXTXIndicatorView.swift */, + BCA9A82B2EC802CF00166292 /* CompassView.swift */, ); path = Helpers; sourceTree = ""; @@ -1811,6 +1817,7 @@ 233E99BE2D849D3200CC3A77 /* RadiationCompactWidget.swift in Sources */, DDD94A502845C8F5004A87A0 /* DateTimeText.swift in Sources */, DDB6ABE228B13FB500384BA1 /* PositionConfigEnums.swift in Sources */, + BCA9A82C2EC802CF00166292 /* CompassView.swift in Sources */, DD994B69295F88B60013760A /* IntervalEnums.swift in Sources */, 23D316932E5618D2002FA4FB /* AsyncGate.swift in Sources */, 23FF00B62E323C75001DF095 /* AccessoryManager+Connect.swift in Sources */, @@ -1841,6 +1848,7 @@ BCDDFA9A2DBB180D0065189C /* ScrollToBottomButton.swift in Sources */, DDC4C9FF2A8D982900CE201C /* DetectionSensorConfig.swift in Sources */, 2344A2AF2D6697A700170A77 /* TelemetryEntity+CoreDataClass.swift in Sources */, + 2349A04A2EAE4DA30060A581 /* ManualConnectionList.swift in Sources */, 2344A2B02D6697A700170A77 /* TelemetryEntity+CoreDataProperties.swift in Sources */, D9C983A22B79D1A600BDBE6A /* RequestPositionButton.swift in Sources */, 237AEB8F2E1FE457003B7CE3 /* Transport.swift in Sources */, @@ -2094,7 +2102,7 @@ "@executable_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 14.6; - MARKETING_VERSION = 2.7.5; + MARKETING_VERSION = 2.7.6; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -2129,7 +2137,7 @@ "@executable_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 14.6; - MARKETING_VERSION = 2.7.5; + MARKETING_VERSION = 2.7.6; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -2161,7 +2169,7 @@ "@executable_path/../../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 14.6; - MARKETING_VERSION = 2.7.5; + MARKETING_VERSION = 2.7.6; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -2194,7 +2202,7 @@ "@executable_path/../../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 14.6; - MARKETING_VERSION = 2.7.5; + MARKETING_VERSION = 2.7.6; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -2261,7 +2269,7 @@ requirement = { kind = versionRange; maximumVersion = 4.0.0; - minimumVersion = 3.1.0; + minimumVersion = 3.3.0; }; }; 259792242C2F10B600AD1659 /* XCRemoteSwiftPackageReference "swift-protobuf" */ = { diff --git a/Meshtastic.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Meshtastic.xcworkspace/xcshareddata/swiftpm/Package.resolved index 84f5fd5e..ba8776f7 100644 --- a/Meshtastic.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Meshtastic.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "fd71b247ba909b0eb360db5530e1068363839c5e169dea6f6a9974b2d98276f4", + "originHash" : "25240dd07109fa832be10093f5d97529f872f18e8d9df6468e5e4212bc0b487e", "pins" : [ { "identity" : "cocoamqtt", @@ -15,8 +15,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/DataDog/dd-sdk-ios.git", "state" : { - "revision" : "a193cab2786b704ebc98c290a7cc8a3165f636bb", - "version" : "3.1.0" + "revision" : "8d67e973ff4a958cb536263cb816646ee904c508", + "version" : "3.3.0" } }, { @@ -60,8 +60,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-protobuf.git", "state" : { - "revision" : "d72aed98f8253ec1aa9ea1141e28150f408cf17f", - "version" : "1.29.0" + "revision" : "c169a5744230951031770e27e475ff6eefe51f9d", + "version" : "1.33.3" } } ], diff --git a/Meshtastic/Accessory/Accessory Manager/AccessoryManager+Connect.swift b/Meshtastic/Accessory/Accessory Manager/AccessoryManager+Connect.swift index df627fbe..d5ca0929 100644 --- a/Meshtastic/Accessory/Accessory Manager/AccessoryManager+Connect.swift +++ b/Meshtastic/Accessory/Accessory Manager/AccessoryManager+Connect.swift @@ -66,10 +66,6 @@ extension AccessoryManager { Logger.transport.info("[Accessory] Event stream closed") } self.activeConnection = (device: device, connection: connection) - - if UserDefaults.preferredPeripheralId.count < 1 { - UserDefaults.preferredPeripheralId = device.id.uuidString - } } catch let error as CBError where error.code == .peerRemovedPairingInformation { await self.connectionStepper?.cancelCurrentlyExecutingStep(withError: AccessoryError.coreBluetoothError(error), cancelFullProcess: true) } @@ -114,6 +110,10 @@ extension AccessoryManager { Logger.transport.info("🔗👟 [Connect] Step 5: Send wantConfig (database)") self.updateState(.retrievingDatabase(nodeCount: 0)) self.allowDisconnect = true + + Logger.transport.info("🔗 Saving preferredPeripheralId: \(device.id.uuidString)") + UserDefaults.preferredPeripheralId = device.id.uuidString + try await self.sendWantDatabase() } @@ -168,6 +168,15 @@ extension AccessoryManager { // We have an active connection self.updateDevice(deviceId: device.id, key: \.connectionState, value: .connected) self.updateState(.subscribed) + + // If we successfully connected to a manual connection, then save it to the list + // Remember, Device is a value type (struct) so don't use use `device` here, thats + // The value at the instantiation of the connect process. We want the currently + // updated device object in `activeConnection` with its additonal metadata from + // NodeInfo packets. + if let activeDevice = self.activeConnection?.device, activeDevice.isManualConnection { + ManualConnectionList.shared.insert(device: activeDevice) + } } // Step 8: Update UI and status to connected @@ -258,7 +267,7 @@ actor SequentialSteps { var isRunning: Bool = false var externalError: Error? - init(maxRetries: Int = 1, retryDelay: Duration = .seconds(3), @StepsBuilder _ builder: () -> [Step]) { + init(maxRetries: Int = 3, retryDelay: Duration = .seconds(3), @StepsBuilder _ builder: () -> [Step]) { self.maxRetries = maxRetries self.retryDelay = retryDelay self.steps = builder() @@ -343,6 +352,7 @@ actor SequentialSteps { return } isRunning = false + return throw AccessoryError.tooManyRetries } diff --git a/Meshtastic/Accessory/Accessory Manager/AccessoryManager+FromRadio.swift b/Meshtastic/Accessory/Accessory Manager/AccessoryManager+FromRadio.swift index 01cdac79..5bcead9b 100644 --- a/Meshtastic/Accessory/Accessory Manager/AccessoryManager+FromRadio.swift +++ b/Meshtastic/Accessory/Accessory Manager/AccessoryManager+FromRadio.swift @@ -106,13 +106,25 @@ extension AccessoryManager { return } + // Check if we're in database retrieval mode to defer saves for performance + let isRetrievingDatabase = if case .retrievingDatabase = self.state { true } else { false } + // TODO: nodeInfoPacket's channel: parameter is not used - if let nodeInfo = nodeInfoPacket(nodeInfo: nodeInfo, channel: 0, context: context) { + if let nodeInfo = nodeInfoPacket(nodeInfo: nodeInfo, channel: 0, context: context, deferSave: isRetrievingDatabase) { if let activeDevice = activeConnection?.device, activeDevice.num == nodeInfo.num { if let user = nodeInfo.user { updateDevice(deviceId: activeDevice.id, key: \.shortName, value: user.shortName ?? "?") updateDevice(deviceId: activeDevice.id, key: \.longName, value: user.longName ?? "Unknown".localized) updateDevice(deviceId: activeDevice.id, key: \.hardwareModel, value: user.hwModel) + + if activeDevice.isManualConnection { + // We just received a NodeInfo for the currently connected node and this is a + // manual connection. Update the metadata for the device entry in UserDefaults + // with this information for better display later + ManualConnectionList.shared.updateDevice(deviceId: activeDevice.id, key: \.shortName, value: user.shortName) + ManualConnectionList.shared.updateDevice(deviceId: activeDevice.id, key: \.longName, value: user.longName) + ManualConnectionList.shared.updateDevice(deviceId: activeDevice.id, key: \.hardwareModel, value: user.hwModel) + } } } } diff --git a/Meshtastic/Accessory/Accessory Manager/AccessoryManager+MQTT.swift b/Meshtastic/Accessory/Accessory Manager/AccessoryManager+MQTT.swift index 7c286336..4da8c739 100644 --- a/Meshtastic/Accessory/Accessory Manager/AccessoryManager+MQTT.swift +++ b/Meshtastic/Accessory/Accessory Manager/AccessoryManager+MQTT.swift @@ -32,14 +32,12 @@ extension AccessoryManager { } } // Set initial unread message badge states - appState.unreadChannelMessages = fetchedNodeInfo[0].myInfo?.unreadMessages ?? 0 - appState.unreadDirectMessages = fetchedNodeInfo[0].user?.unreadMessages ?? 0 - } - if fetchedNodeInfo.count == 1 && fetchedNodeInfo[0].rangeTestConfig?.enabled == true { - wantRangeTestPackets = true - } - if fetchedNodeInfo.count == 1 && fetchedNodeInfo[0].storeForwardConfig?.enabled == true { - wantStoreAndForwardPackets = true + appState.unreadChannelMessages = fetchedNodeInfo[0].myInfo?.unreadMessages(context: context) ?? 0 + appState.unreadDirectMessages = fetchedNodeInfo[0].user?.unreadMessages(context: context, skipLastMessageCheck: true) ?? 0 // skipLastMessageCheck=true because we don't update lastMessage on our own connected node + + // Set wantRangeTestPackets and wantStoreAndForwardPackets + wantRangeTestPackets = fetchedNodeInfo[0].rangeTestConfig?.enabled ?? false + wantStoreAndForwardPackets = fetchedNodeInfo[0].storeForwardConfig?.enabled ?? false } } catch { Logger.data.error("Failed to find a node info for the connected node \(error.localizedDescription, privacy: .public)") @@ -51,8 +49,12 @@ extension AccessoryManager { func onMqttConnected() { mqttProxyConnected = true mqttError = "" - Logger.services.info("📲 [MQTT Client Proxy] onMqttConnected now subscribing to \(self.mqttManager.topic, privacy: .public).") - mqttManager.mqttClientProxy?.subscribe(mqttManager.topic) + if mqttManager.shouldSubscribe { + Logger.services.info("📲 [MQTT Client Proxy] onMqttConnected now subscribing to \(self.mqttManager.topic, privacy: .public).") + mqttManager.mqttClientProxy?.subscribe(mqttManager.topic) + } else { + Logger.services.info("📲 [MQTT Client Proxy] onMqttConnected not subscribing since downlink is not on") + } } func onMqttDisconnected() { @@ -83,3 +85,4 @@ extension AccessoryManager { Logger.services.info("📲 [MQTT Client Proxy] onMqttError: \(message, privacy: .public)") } } + diff --git a/Meshtastic/Accessory/Accessory Manager/AccessoryManager+ToRadio.swift b/Meshtastic/Accessory/Accessory Manager/AccessoryManager+ToRadio.swift index e0478902..4fe2ffaf 100644 --- a/Meshtastic/Accessory/Accessory Manager/AccessoryManager+ToRadio.swift +++ b/Meshtastic/Accessory/Accessory Manager/AccessoryManager+ToRadio.swift @@ -165,6 +165,7 @@ extension AccessoryManager { nodeMeshPacket.decoded = dataNodeMessage // Update local database with the new node info + // FUTURE: after https://github.com/meshtastic/firmware/pull/8495 is merged, `favorite: true` becomes `favorite: (connectedDeviceRole != DeviceRoles.clientBase)` upsertNodeInfoPacket(packet: nodeMeshPacket, favorite: true, context: context) } } catch { @@ -333,7 +334,7 @@ extension AccessoryManager { var contact = SharedContact() contact.manuallyVerified = false contact.nodeNum = UInt32(truncatingIfNeeded: user.num) - user.userNode?.favorite = true + user.userNode?.favorite = user.userNode?.deviceConfig?.role ?? 0 != DeviceRoles.clientBase.rawValue contact.user = user.toProto() do { let contactString = try contact.serializedData().base64EncodedString() @@ -350,7 +351,7 @@ extension AccessoryManager { if toUserNum > 0 { meshPacket.to = UInt32(toUserNum) let hopsAway = newMessage.toUser?.userNode?.hopsAway ?? 0 - if hopsAway > Int32(truncatingIfNeeded: newMessage.toUser?.userNode?.loRaConfig?.hopLimit ?? 0) { + if hopsAway > Int32(truncatingIfNeeded: newMessage.fromUser?.userNode?.loRaConfig?.hopLimit ?? 0) { meshPacket.hopLimit = UInt32(truncatingIfNeeded: hopsAway) } } else { @@ -509,32 +510,32 @@ extension AccessoryManager { let logString = String.localizedStringWithFormat("Sent a Channel for: %@ Channel Index %d".localized, String(deviceNum), chan.index) try await send(toRadio, debugDescription: logString) } - - // Save the LoRa Config and the device will reboot - var adminPacket = AdminMessage() - adminPacket.setConfig.lora = channelSet.loraConfig - adminPacket.setConfig.lora.configOkToMqtt = okToMQTT // Preserve users okToMQTT choice - var meshPacket: MeshPacket = MeshPacket() - meshPacket.to = UInt32(deviceNum) - meshPacket.from = UInt32(deviceNum) - meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. with nil deviceId") return } - - // Update the active device - if let activeConnection { + + // Update the active device if the UUID's match + if let activeConnection, activeConnection.device.id == deviceId { var device = activeConnection.device if device[keyPath: key] != value { // Update the @Published stuff for the UI @@ -493,6 +493,14 @@ class AccessoryManager: ObservableObject, MqttClientProxyManagerDelegate { handleMyInfo(myNodeInfo) case .packet(let packet): + // All received packets get passed through updateAnyPacketFrom to update lastHeard, rxSnr, etc. (like firmware's NodeDB::updateFrom). + if let connectedNodeNum = self.activeDeviceNum { + updateAnyPacketFrom(packet: packet, activeDeviceNum: connectedNodeNum, context: context) + } else { + Logger.mesh.error("🕸️ Unable to determine connectedNodeNum for updateAnyPacketFrom. Skipping.") + } + + // Dispatch based on packet contents. if case let .decoded(data) = packet.payloadVariant { switch data.portnum { case .textMessageApp, .detectionSensorApp, .alertApp: @@ -570,6 +578,8 @@ class AccessoryManager: ObservableObject, MqttClientProxyManagerDelegate { Logger.mesh.info("🕸️ MESH PACKET received for ATAK Forwarder App UNHANDLED UNHANDLED") case .simulatorApp: Logger.mesh.info("🕸️ MESH PACKET received for Simulator App UNHANDLED UNHANDLED") + case .storeForwardPlusplusApp: + Logger.mesh.info("🕸️ MESH PACKET received for SFPP App UNHANDLED UNHANDLED") case .audioApp: Logger.mesh.info("🕸️ MESH PACKET received for Audio App UNHANDLED UNHANDLED") case .tracerouteApp: @@ -665,6 +675,17 @@ class AccessoryManager: ObservableObject, MqttClientProxyManagerDelegate { self.firstDatabaseNodeInfoContinuation = nil } + // Perform a single batch save after database retrieval completes + // This significantly improves performance on reconnect + do { + try context.save() + Logger.data.info("💾 [Database] Batch saved all node info after database retrieval") + } catch { + context.rollback() + let nsError = error as NSError + Logger.data.error("💥 [Database] Error saving batch node info: \(nsError, privacy: .public)") + } + default: Logger.transport.error("[Accessory] Unknown nonce completed: \(configCompleteID)") } @@ -687,6 +708,13 @@ extension AccessoryManager { return activeConnection?.device.firmwareVersion } + var connectedDeviceRole: DeviceRoles? { + guard let connectedNodeNum = activeDeviceNum else { return nil } + guard let connectedNode = getNodeInfo(id: connectedNodeNum, context: context) else { return nil } + guard let connectedNodeUser = connectedNode.user else { return nil } + return DeviceRoles(rawValue: Int(connectedNodeUser.role)) + } + func checkIsVersionSupported(forVersion: String) -> Bool { let myVersion = connectedVersion ?? "0.0.0" let supportedVersion = UserDefaults.firmwareVersion == "0.0.0" || @@ -703,7 +731,8 @@ extension AccessoryManager { await self.heartbeatTimer?.cancel(withReason: "Duplicate setup, cancelling previous timer") self.heartbeatTimer = nil } - self.heartbeatTimer = ResettableTimer(isRepeating: true, debugName: "Send Heartbeat") { + + self.heartbeatTimer = ResettableTimer(isRepeating: true, debugName: Bundle.main.isDebug ? "Send Heartbeat" : nil) { Logger.transport.debug("💓 [Heartbeat] Sending periodic heartbeat") try? await self.sendHeartbeat() } @@ -711,7 +740,7 @@ extension AccessoryManager { // We can send heartbeats for older versions just fine, but only 2.7.4 and up will respond with // a definite queueStatus packet. if self.checkIsVersionSupported(forVersion: "2.7.4") { - self.heartbeatResponseTimer = ResettableTimer(isRepeating: false, debugName: "Heartbeat Timeout") { @MainActor in + self.heartbeatResponseTimer = ResettableTimer(isRepeating: false, debugName: Bundle.main.isDebug ? "Heartbeat Timeout" : nil) { @MainActor in Logger.transport.error("💓 [Heartbeat] Connection Timeout: Did not receive a packet after heartbeat.") // If we're in the middle of a connection cancel it. await self.connectionStepper?.cancel() diff --git a/Meshtastic/Accessory/Helpers/ManualConnectionList.swift b/Meshtastic/Accessory/Helpers/ManualConnectionList.swift new file mode 100644 index 00000000..665573a9 --- /dev/null +++ b/Meshtastic/Accessory/Helpers/ManualConnectionList.swift @@ -0,0 +1,61 @@ +// +// ManualConnectionList.swift +// Meshtastic +// +// Created by jake on 10/26/25. +// + +import Foundation + +// Maintains an observable list of devices that's backed by UserDefaults +public class ManualConnectionList: ObservableObject { + static let shared = ManualConnectionList() + + @Published private var _list: [Device] + + private init() { + _list = UserDefaults.manualConnections + } + + var connectionsList: [Device] { + get { + return _list + } + } + + func insert(device: Device) { + // Don't insert if already there + guard !_list.contains(where: {$0.id == device.id}) else { + return + } + + // Add the new entry + var list = _list + list.append(device) + _list = list + UserDefaults.manualConnections = list + } + + func updateDevice(deviceId: UUID, key: WritableKeyPath, value: T) where T: Equatable { + var list = _list + if let deviceIndex = list.firstIndex(where: {$0.id == deviceId}) { + list[deviceIndex][keyPath: key] = value + _list = list + UserDefaults.manualConnections = list + } + } + + func remove(device: Device) { + var list = _list + list.removeAll(where: {$0.id == device.id}) + _list = list + UserDefaults.manualConnections = list + } + + func remove(atOffsets: IndexSet) { + var list = _list + list.remove(atOffsets: atOffsets) + _list = list + UserDefaults.manualConnections = list + } +} diff --git a/Meshtastic/Accessory/Protocols/Connection.swift b/Meshtastic/Accessory/Protocols/Connection.swift index afc087c5..27758b84 100644 --- a/Meshtastic/Accessory/Protocols/Connection.swift +++ b/Meshtastic/Accessory/Protocols/Connection.swift @@ -31,7 +31,7 @@ enum ConnectionEvent { case disconnected(shouldReconnect: Bool) } -enum ConnectionState: Equatable { +enum ConnectionState: Equatable, Codable { case disconnected case connecting case connected diff --git a/Meshtastic/Accessory/Protocols/Device.swift b/Meshtastic/Accessory/Protocols/Device.swift index 03ae1d1d..d14b349e 100644 --- a/Meshtastic/Accessory/Protocols/Device.swift +++ b/Meshtastic/Accessory/Protocols/Device.swift @@ -7,7 +7,8 @@ import Foundation -struct Device: Identifiable, Hashable { +struct Device: Identifiable, Hashable, Codable, CustomStringConvertible { + let id: UUID var name: String var transportType: TransportType @@ -23,7 +24,9 @@ struct Device: Identifiable, Hashable { var connectionState: ConnectionState var wasRestored: Bool = false - init(id: UUID, name: String, transportType: TransportType, identifier: String, connectionState: ConnectionState = .disconnected, rssi: Int? = nil, num: Int64? = nil, wasRestored: Bool = false) { + var isManualConnection: Bool = false + + init(id: UUID, name: String, transportType: TransportType, identifier: String, connectionState: ConnectionState = .disconnected, rssi: Int? = nil, num: Int64? = nil, wasRestored: Bool = false, isManualConnection: Bool = false) { self.id = id self.name = name self.transportType = transportType @@ -32,6 +35,7 @@ struct Device: Identifiable, Hashable { self.rssi = rssi self.num = num self.wasRestored = wasRestored + self.isManualConnection = isManualConnection } var rssiString: String { @@ -53,4 +57,16 @@ struct Device: Identifiable, Hashable { } } + var description: String { + switch (shortName, longName) { + case (let shortName?, let longName?): // Both shortName and longName are non-nil + return "\(longName) (\(shortName))" + case (let shortName?, nil): // shortName is non-nil, longName is nil + return "\(shortName)" + case (nil, let longName?): // shortName is nil, longName is non-nil + return "\(longName)" + default: // Both are nil + return "Device(id: \(id))" + } + } } diff --git a/Meshtastic/Accessory/Protocols/Transport.swift b/Meshtastic/Accessory/Protocols/Transport.swift index 0c5cce08..55fa8545 100644 --- a/Meshtastic/Accessory/Protocols/Transport.swift +++ b/Meshtastic/Accessory/Protocols/Transport.swift @@ -9,7 +9,7 @@ import Foundation import CommonCrypto import SwiftUI -enum TransportType: String, CaseIterable { +enum TransportType: String, CaseIterable, Codable { case ble = "BLE" case tcp = "TCP" case serial = "Serial" @@ -53,14 +53,15 @@ protocol Transport { var requiresPeriodicHeartbeat: Bool { get } var supportsManualConnection: Bool { get } - func manuallyConnect(withConnectionString: String) async throws + func device(forManualConnection: String) -> Device? + func manuallyConnect(toDevice: Device) async throws } // Used to make stable-ish ID's for accessories that don't have a UUID extension String { - func toUUIDFormatHash() -> UUID? { + func toUUIDFormatHash() -> UUID { // Convert string to data - guard let data = self.data(using: .utf8) else { return nil } + let data = self.data(using: .utf8) ?? Data() // Create buffer for SHA-256 hash (32 bytes) var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH)) diff --git a/Meshtastic/Accessory/Transports/Bluetooth Low Energy/BLETransport.swift b/Meshtastic/Accessory/Transports/Bluetooth Low Energy/BLETransport.swift index ea4a22b8..aa1a32d4 100644 --- a/Meshtastic/Accessory/Transports/Bluetooth Low Energy/BLETransport.swift +++ b/Meshtastic/Accessory/Transports/Bluetooth Low Energy/BLETransport.swift @@ -403,7 +403,11 @@ class BLETransport: Transport { } - func manuallyConnect(withConnectionString: String) async throws { + func device(forManualConnection: String) -> Device? { + return nil + } + + func manuallyConnect(toDevice: Device) async throws { Logger.transport.error("🛜 [BLE] This transport does not support manual connections") } diff --git a/Meshtastic/Accessory/Transports/Serial/SerialTransport.swift b/Meshtastic/Accessory/Transports/Serial/SerialTransport.swift index 920dd538..b34b1884 100644 --- a/Meshtastic/Accessory/Transports/Serial/SerialTransport.swift +++ b/Meshtastic/Accessory/Transports/Serial/SerialTransport.swift @@ -31,7 +31,7 @@ class SerialTransport: Transport { while !Task.isCancelled { let ports = self.getSerialPorts() for port in ports { - let id = port.toUUIDFormatHash() ?? UUID() + let id = port.toUUIDFormatHash() if !portsAlreadyNotified.contains(port) { Logger.transport.info("🔱 [Serial] Port \(port, privacy: .public) found.") let newDevice = Device(id: id, @@ -45,9 +45,8 @@ class SerialTransport: Transport { for knownPort in portsAlreadyNotified where !ports.contains(knownPort) { // Previosuly seen port is no longer available Logger.transport.info("🔱 [Serial] Port \(knownPort, privacy: .public) is no longer connected.") - if let uuid = knownPort.toUUIDFormatHash() { - cont.yield(.deviceLost(uuid)) - } + let uuid = knownPort.toUUIDFormatHash() + cont.yield(.deviceLost(uuid)) portsAlreadyNotified.removeAll(where: {$0 == knownPort}) } try? await Task.sleep(for: .seconds(5)) @@ -118,7 +117,11 @@ class SerialTransport: Transport { return SerialConnection(path: device.identifier) } - func manuallyConnect(withConnectionString: String) async throws { + func device(forManualConnection: String) -> Device? { + return nil + } + + func manuallyConnect(toDevice: Device) async throws { Logger.transport.error("🔱 [USB] This transport does not support manual connections") } } diff --git a/Meshtastic/Accessory/Transports/TCP/TCPTransport.swift b/Meshtastic/Accessory/Transports/TCP/TCPTransport.swift index d753fc76..1acc988c 100644 --- a/Meshtastic/Accessory/Transports/TCP/TCPTransport.swift +++ b/Meshtastic/Accessory/Transports/TCP/TCPTransport.swift @@ -73,13 +73,29 @@ class TCPTransport: NSObject, Transport, NetServiceBrowserDelegate, NetServiceDe let ip = service.ipv4Address ?? "Unknown IP" // Use a mishmash of things and hash for stable? ID. - let idString = "\(service.name):\(host):\(ip):\(port)".toUUIDFormatHash() ?? UUID() + let idString = "\(service.name):\(host):\(ip):\(port)".toUUIDFormatHash() // Save the resolved service locally for later services[service.name] = ResolvedService(id: idString, service: service, host: host, port: port) + let name: String + if let txtRecords = service.txtRecordData().map({NetService.dictionary(fromTXTRecord: $0)}) { + var nodeNameString = "" + if let shortNameData = txtRecords["shortname"] { + nodeNameString += String(decoding: shortNameData, as: UTF8.self) + } + if let nodeId = txtRecords["id"], nodeId.count > 4 { + if nodeNameString.count > 0 { + nodeNameString += "_" + } + nodeNameString += String(decoding: nodeId.suffix(4), as: UTF8.self) + } + name = nodeNameString + } else { + name = "\(service.name) (\(ip))" + } let device = Device(id: idString, - name: "\(service.name) (\(ip))", + name: name, transportType: .tcp, identifier: "\(host):\(port)") continuation?.yield(.deviceFound(device)) @@ -134,16 +150,57 @@ class TCPTransport: NSObject, Transport, NetServiceBrowserDelegate, NetServiceDe } } - func manuallyConnect(withConnectionString: String) async throws { - let hashedIdentifier = withConnectionString.toUUIDFormatHash() ?? UUID() - let manualDevice = Device(id: hashedIdentifier, - name: "\(withConnectionString) (Manual)", - transportType: .tcp, identifier: withConnectionString) - try await AccessoryManager.shared.connect(to: manualDevice) + func device(forManualConnection connectionString: String) -> Device? { + let parts = connectionString.split(separator: ":") + var identifier: String + + switch parts.count { + case 1: + // host & default port + identifier = "\(parts[0]):4403" + + case 2: + // host & port + if parts[1].isValidTCPPort { + identifier = "\(parts[0]):\(parts[1])" + } else { + return nil + } + + default: + return nil + } + let hashedIdentifier = identifier.toUUIDFormatHash() + return Device(id: hashedIdentifier, + name: "\(connectionString) (Manual)", + transportType: .tcp, + identifier: connectionString, + isManualConnection: true) + } + + func manuallyConnect(toDevice device: Device) async throws { + try await AccessoryManager.shared.connect(to: device) } } +extension StringProtocol { + var isValidTCPPort: Bool { + // Check if the string is non-empty and contains only digits + guard !isEmpty, allSatisfy({ $0.isNumber }) else { + return false + } + + // Parse the string to an integer + guard let port = Int(self) else { + return false // Fails if the string can't be converted to an integer + } + + // Check if the port is in the valid TCP range (0–65535) + return port >= 0 && port <= 65535 + } +} + extension NetService { var ipv4Address: String? { for addressData in addresses ?? [] { diff --git a/Meshtastic/Assets.xcassets/HELTECV4.imageset/Contents.json b/Meshtastic/Assets.xcassets/HELTECV4.imageset/Contents.json new file mode 100644 index 00000000..a90a896f --- /dev/null +++ b/Meshtastic/Assets.xcassets/HELTECV4.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "heltec_v4.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Meshtastic/Assets.xcassets/HELTECV4.imageset/heltec_v4.svg b/Meshtastic/Assets.xcassets/HELTECV4.imageset/heltec_v4.svg new file mode 100644 index 00000000..849d056f --- /dev/null +++ b/Meshtastic/Assets.xcassets/HELTECV4.imageset/heltec_v4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Meshtastic/Assets.xcassets/MUZIR1NEO.imageset/Contents.json b/Meshtastic/Assets.xcassets/MUZIR1NEO.imageset/Contents.json new file mode 100644 index 00000000..ced0ad0c --- /dev/null +++ b/Meshtastic/Assets.xcassets/MUZIR1NEO.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "muzi_r1_neo.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Meshtastic/Assets.xcassets/MUZIR1NEO.imageset/muzi_r1_neo.svg b/Meshtastic/Assets.xcassets/MUZIR1NEO.imageset/muzi_r1_neo.svg new file mode 100644 index 00000000..2f2cb0bf --- /dev/null +++ b/Meshtastic/Assets.xcassets/MUZIR1NEO.imageset/muzi_r1_neo.svg @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Meshtastic/Assets.xcassets/THINKNODEM3.imageset/Contents.json b/Meshtastic/Assets.xcassets/THINKNODEM3.imageset/Contents.json new file mode 100644 index 00000000..625b6450 --- /dev/null +++ b/Meshtastic/Assets.xcassets/THINKNODEM3.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "thinknode_m3.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Meshtastic/Assets.xcassets/THINKNODEM3.imageset/thinknode_m3.svg b/Meshtastic/Assets.xcassets/THINKNODEM3.imageset/thinknode_m3.svg new file mode 100644 index 00000000..ce5ce6fc --- /dev/null +++ b/Meshtastic/Assets.xcassets/THINKNODEM3.imageset/thinknode_m3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Meshtastic/Assets.xcassets/THINKNODEM4.imageset/Contents.json b/Meshtastic/Assets.xcassets/THINKNODEM4.imageset/Contents.json new file mode 100644 index 00000000..2c2709dc --- /dev/null +++ b/Meshtastic/Assets.xcassets/THINKNODEM4.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "thinknode_m4.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Meshtastic/Assets.xcassets/THINKNODEM4.imageset/thinknode_m4.svg b/Meshtastic/Assets.xcassets/THINKNODEM4.imageset/thinknode_m4.svg new file mode 100644 index 00000000..a5050859 --- /dev/null +++ b/Meshtastic/Assets.xcassets/THINKNODEM4.imageset/thinknode_m4.svg @@ -0,0 +1 @@ +T&HStatusFunction \ No newline at end of file diff --git a/Meshtastic/Enums/LoraConfigEnums.swift b/Meshtastic/Enums/LoraConfigEnums.swift index b196a7a7..7be12c7c 100644 --- a/Meshtastic/Enums/LoraConfigEnums.swift +++ b/Meshtastic/Enums/LoraConfigEnums.swift @@ -313,6 +313,7 @@ enum ModemPresets: Int, CaseIterable, Identifiable { case longFast = 0 case longSlow = 1 case longModerate = 7 + case longTurbo = 9 case medSlow = 3 case medFast = 4 case shortSlow = 5 @@ -328,6 +329,8 @@ enum ModemPresets: Int, CaseIterable, Identifiable { return "Long Range - Slow".localized case .longModerate: return "Long Range - Moderate".localized + case .longTurbo: + return "Long Range - Turbo".localized case .medSlow: return "Medium Range - Slow".localized case .medFast: @@ -348,6 +351,8 @@ enum ModemPresets: Int, CaseIterable, Identifiable { return "LongSlow" case .longModerate: return "LongModerate" + case .longTurbo: + return "LongTurbo" case .medSlow: return "MediumSlow" case .medFast: @@ -366,6 +371,8 @@ enum ModemPresets: Int, CaseIterable, Identifiable { return -17.5 case .longSlow: return -7.5 + case .longTurbo: + return -12.5 case .longModerate: return -17.5 case .medSlow: @@ -388,6 +395,8 @@ enum ModemPresets: Int, CaseIterable, Identifiable { return Config.LoRaConfig.ModemPreset.longSlow case .longModerate: return Config.LoRaConfig.ModemPreset.longModerate + case .longTurbo: + return Config.LoRaConfig.ModemPreset.longTurbo case .medSlow: return Config.LoRaConfig.ModemPreset.mediumSlow case .medFast: diff --git a/Meshtastic/Extensions/Bundle.swift b/Meshtastic/Extensions/Bundle.swift index 0bb62acf..9f710bb7 100644 --- a/Meshtastic/Extensions/Bundle.swift +++ b/Meshtastic/Extensions/Bundle.swift @@ -23,4 +23,12 @@ extension Bundle { public var isTestFlight: Bool { return appStoreReceiptURL?.lastPathComponent == "sandboxReceipt" } + + public var isDebug: Bool { + #if DEBUG + return true + #else + return false + #endif + } } diff --git a/Meshtastic/Extensions/CoreData/ChannelEntityExtension.swift b/Meshtastic/Extensions/CoreData/ChannelEntityExtension.swift index c85eef4a..8fce761c 100644 --- a/Meshtastic/Extensions/CoreData/ChannelEntityExtension.swift +++ b/Meshtastic/Extensions/CoreData/ChannelEntityExtension.swift @@ -9,22 +9,45 @@ import CoreData import MeshtasticProtobufs extension ChannelEntity { + var messagePredicate: NSPredicate { + return NSPredicate(format: "channel == %ld AND toUser == nil AND isEmoji == false", self.index) + } + + var messageFetchRequest: NSFetchRequest { + let fetchRequest = MessageEntity.fetchRequest() + fetchRequest.sortDescriptors = [NSSortDescriptor(key: "messageTimestamp", ascending: true)] + fetchRequest.predicate = messagePredicate + return fetchRequest + } var allPrivateMessages: [MessageEntity] { let context = PersistenceController.shared.container.viewContext - let fetchRequest = MessageEntity.fetchRequest() - fetchRequest.sortDescriptors = [NSSortDescriptor(key: "messageTimestamp", ascending: true)] - fetchRequest.predicate = NSPredicate(format: "channel == %ld AND toUser == nil AND isEmoji == false", self.index) + let fetchRequest = messageFetchRequest return (try? context.fetch(fetchRequest)) ?? [MessageEntity]() } - var unreadMessages: Int { + var mostRecentPrivateMessage: MessageEntity? { + // Most recent channel message (descending, limit 1) + let context = PersistenceController.shared.container.viewContext + let fetchRequest = messageFetchRequest + fetchRequest.sortDescriptors = [NSSortDescriptor(key: "messageTimestamp", ascending: false)] + fetchRequest.fetchLimit = 1 - let unreadMessages = allPrivateMessages.filter { ($0 as AnyObject).read == false } - return unreadMessages.count + return (try? context.fetch(fetchRequest))?.first } + func unreadMessages(context: NSManagedObjectContext) -> Int { + let fetchRequest = messageFetchRequest + fetchRequest.sortDescriptors = [] // sort is irrelevant. + fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fetchRequest.predicate!, NSPredicate(format: "read == false")]) + + return (try? context.count(for: fetchRequest)) ?? 0 + } + + // Backwards-compatible property (uses viewContext) + var unreadMessages: Int { unreadMessages(context: PersistenceController.shared.container.viewContext) } + var protoBuf: Channel { var channel = Channel() channel.index = self.index @@ -32,7 +55,7 @@ extension ChannelEntity { channel.settings.psk = self.psk ?? Data() channel.role = Channel.Role(rawValue: Int(self.role)) ?? Channel.Role.secondary channel.settings.moduleSettings.positionPrecision = UInt32(self.positionPrecision) - channel.settings.moduleSettings.isClientMuted = self.mute + channel.settings.moduleSettings.isMuted = self.mute return channel } } diff --git a/Meshtastic/Extensions/CoreData/MessageEntityExtension.swift b/Meshtastic/Extensions/CoreData/MessageEntityExtension.swift index e7abb191..d6d2c997 100644 --- a/Meshtastic/Extensions/CoreData/MessageEntityExtension.swift +++ b/Meshtastic/Extensions/CoreData/MessageEntityExtension.swift @@ -5,10 +5,9 @@ // Created by Ben on 8/22/23. // -import Foundation - import CoreData import CoreLocation +import Foundation import MapKit import SwiftUI @@ -26,16 +25,62 @@ extension MessageEntity { var tapbacks: [MessageEntity] { let context = PersistenceController.shared.container.viewContext let fetchRequest = MessageEntity.fetchRequest() - fetchRequest.sortDescriptors = [NSSortDescriptor(key: "messageTimestamp", ascending: true)] - fetchRequest.predicate = NSPredicate(format: "replyID == %lld AND isEmoji == true", self.messageId) + fetchRequest.sortDescriptors = [ + NSSortDescriptor(key: "messageTimestamp", ascending: true) + ] + fetchRequest.predicate = NSPredicate( + format: "replyID == %lld AND isEmoji == true", + self.messageId + ) return (try? context.fetch(fetchRequest)) ?? [MessageEntity]() } func displayTimestamp(aboveMessage: MessageEntity?) -> Bool { if let aboveMessage = aboveMessage { - return aboveMessage.timestamp.addingTimeInterval(3600) < timestamp // 60 minutes + return aboveMessage.timestamp.addingTimeInterval(3600) < timestamp // 60 minutes + } + return false // First message will have no timestamp + } + + func relayDisplay() -> String? { + + guard self.relayNode != 0 else { return nil } + let context = PersistenceController.shared.container.viewContext + + let relaySuffix = Int64(self.relayNode & 0xFF) + let request: NSFetchRequest = UserEntity.fetchRequest() + request.predicate = NSPredicate( + format: "(num & 0xFF) == %lld", + relaySuffix + ) + + do { + let users = try context.fetch(request) + + // If exactly one match is found, return its name + if users.count == 1, let name = users.first?.longName, !name.isEmpty + { + return "\(name)" + } + + // If no exact match, find the node with the smallest hopsAway + if let closestNode = users.min(by: { lhs, rhs in + guard let lhsHops = lhs.userNode?.hopsAway, + let rhsHops = rhs.userNode?.hopsAway + else { + return false + } + return lhsHops < rhsHops + }), let name = closestNode.longName, !name.isEmpty { + return "\(name)" + } + + // Fallback to hex node number if no matches + return String(format: "Node 0x%02X", UInt32(self.relayNode & 0xFF)) + + } catch { + return String(format: "Node 0x%02X", UInt32(self.relayNode & 0xFF)) } - return false // First message will have no timestamp } } diff --git a/Meshtastic/Extensions/CoreData/MyInfoEntityExtension.swift b/Meshtastic/Extensions/CoreData/MyInfoEntityExtension.swift index 68a48ee1..c9e06d88 100644 --- a/Meshtastic/Extensions/CoreData/MyInfoEntityExtension.swift +++ b/Meshtastic/Extensions/CoreData/MyInfoEntityExtension.swift @@ -6,23 +6,39 @@ // import Foundation +import CoreData extension MyInfoEntity { + var messagePredicate: NSPredicate { + return NSPredicate(format: "toUser == nil AND isEmoji == false") + } + + var messageFetchRequest: NSFetchRequest { + let fetchRequest = MessageEntity.fetchRequest() + fetchRequest.sortDescriptors = [NSSortDescriptor(key: "messageTimestamp", ascending: true)] + fetchRequest.predicate = messagePredicate + return fetchRequest + } var messageList: [MessageEntity] { let context = PersistenceController.shared.container.viewContext - let fetchRequest = MessageEntity.fetchRequest() - fetchRequest.sortDescriptors = [NSSortDescriptor(key: "messageTimestamp", ascending: true)] - fetchRequest.predicate = NSPredicate(format: "toUser == nil") + let fetchRequest = messageFetchRequest - return (try? context.fetch(fetchRequest)) ?? [MessageEntity]() + return (try? context.fetch(messageFetchRequest)) ?? [MessageEntity]() } - var unreadMessages: Int { - let unreadMessages = messageList.filter { ($0 as AnyObject).read == false && ($0 as AnyObject).isEmoji == false } - return unreadMessages.count + func unreadMessages(context: NSManagedObjectContext) -> Int { + // Returns the count of unread *channel* messages + let fetchRequest = messageFetchRequest + fetchRequest.sortDescriptors = [] // sort is irrelevant. + fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fetchRequest.predicate!, NSPredicate(format: "read == false")]) + + return (try? context.count(for: fetchRequest)) ?? 0 } + // Backwards-compatible property (uses viewContext) + var unreadMessages: Int { unreadMessages(context: PersistenceController.shared.container.viewContext) } + var hasAdmin: Bool { let adminChannel = channels?.filter { ($0 as AnyObject).name?.lowercased() == "admin" } return adminChannel?.count ?? 0 > 0 diff --git a/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift b/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift index 3efa9af3..080693c2 100644 --- a/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift +++ b/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift @@ -96,10 +96,40 @@ extension PositionEntity { } return pointAnn } + + var isPreciseLocation: Bool { + precisionBits == 32 || precisionBits == 0 + } + + var fuzzedNodeCoordinate: CLLocationCoordinate2D? { + // With reduced precisionBits, many nodes can overlap on the map, making them unclickable. + // Use a hash of the position ID to fuzz coordinate slightly so that these nodes can be distinguished at the higest zoom levels. This allows them to be clicked individually. + if latitudeI != 0 && longitudeI != 0 { + // Derive two uniform pseudorandom numbers [0,1) from id.hashValue + let u1 = Double(id.hashValue & 0xFFFF) / 65536.0 + let u2 = Double((id.hashValue >> 16) & 0xFFFF) / 65536.0 + + // Angle and radius + let offsetAngle = 2.0 * .pi * u1 + let offsetRadius = 0.00001 * sqrt(u2) // 1.0e-5 degrees at equator is about 1.11 m or 4 ft + + let dLat = sin(offsetAngle) * offsetRadius + let dLon = cos(offsetAngle) * offsetRadius + + let coord = CLLocationCoordinate2D( + latitude: latitude! + dLat, + longitude: longitude! + dLon + ) + return coord + } else { + return nil + } + } } extension PositionEntity: MKAnnotation { public var coordinate: CLLocationCoordinate2D { nodeCoordinate ?? LocationsHandler.DefaultLocation } + public var fuzzedCoordinate: CLLocationCoordinate2D { fuzzedNodeCoordinate ?? LocationsHandler.DefaultLocation } public var title: String? { nodePosition?.user?.shortName ?? "Unknown".localized } public var subtitle: String? { time?.formatted() } } diff --git a/Meshtastic/Extensions/CoreData/UserEntityExtension.swift b/Meshtastic/Extensions/CoreData/UserEntityExtension.swift index 2a87ed9f..3a61ff4b 100644 --- a/Meshtastic/Extensions/CoreData/UserEntityExtension.swift +++ b/Meshtastic/Extensions/CoreData/UserEntityExtension.swift @@ -10,16 +10,37 @@ import CoreData import MeshtasticProtobufs extension UserEntity { + var messagePredicate: NSPredicate { + return NSPredicate(format: "((toUser == %@) OR (fromUser == %@)) AND toUser != nil AND fromUser != nil AND isEmoji == false AND admin = false AND portNum != 10", self, self) + } + + var messageFetchRequest: NSFetchRequest { + let fetchRequest = MessageEntity.fetchRequest() + fetchRequest.sortDescriptors = [NSSortDescriptor(key: "messageTimestamp", ascending: true)] + fetchRequest.predicate = messagePredicate + return fetchRequest + } var messageList: [MessageEntity] { let context = PersistenceController.shared.container.viewContext - let fetchRequest = MessageEntity.fetchRequest() - fetchRequest.sortDescriptors = [NSSortDescriptor(key: "messageTimestamp", ascending: true)] - fetchRequest.predicate = NSPredicate(format: "((toUser == %@) OR (fromUser == %@)) AND toUser != nil AND fromUser != nil AND isEmoji == false AND admin = false AND portNum != 10", self, self) + let fetchRequest = messageFetchRequest return (try? context.fetch(fetchRequest)) ?? [MessageEntity]() } + var mostRecentMessage: MessageEntity? { + // Most contacts will have no DMs history, so we can return early. + guard self.lastMessage != nil else { return nil; } + + // Most recent DM for this user (descending, limit 1) + let context = PersistenceController.shared.container.viewContext + let fetchRequest = messageFetchRequest + fetchRequest.sortDescriptors = [NSSortDescriptor(key: "messageTimestamp", ascending: false)] + fetchRequest.fetchLimit = 1 + + return (try? context.fetch(fetchRequest))?.first + } + var sensorMessageList: [MessageEntity] { let context = PersistenceController.shared.container.viewContext let fetchRequest = MessageEntity.fetchRequest() @@ -29,10 +50,21 @@ extension UserEntity { return (try? context.fetch(fetchRequest)) ?? [MessageEntity]() } - var unreadMessages: Int { - let unreadMessages = messageList.filter { ($0 as AnyObject).read == false && ($0 as AnyObject).isEmoji == false } - return unreadMessages.count + func unreadMessages(context: NSManagedObjectContext, skipLastMessageCheck: Bool = false) -> Int { + // Most contacts will have no DMs history, so we can return early. + // (For our own node, set skipLastMessageCheck=true, because we don't update lastMessage on our own connected node.) + guard self.lastMessage != nil || skipLastMessageCheck else { return 0; } + + let fetchRequest = messageFetchRequest + fetchRequest.sortDescriptors = [] // sort is irrelevant. + fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fetchRequest.predicate!, NSPredicate(format: "read == false")]) + + return (try? context.count(for: fetchRequest)) ?? 0 } + + // Backwards-compatible property (uses viewContext) + var unreadMessages: Int { unreadMessages(context: PersistenceController.shared.container.viewContext) } + /// SVG Images for Vendors who are signed project backers var hardwareImage: String? { guard let hwModel else { return nil } @@ -44,6 +76,8 @@ extension UserEntity { return "HELTECMESHNODET114" case "HELTECV3": return "HELTECV3" + case "HELTECV4": + return "HELTECV4" case "HELTECMESHPOCKET": return "HELTECMESHPOCKET" case "HELTECVISIONMASTERE213": @@ -102,8 +136,20 @@ extension UserEntity { return "NANOG1" case "NANOG2ULTRA": return "NANOG2ULTRA" + /// Muzi Works + case "MUZIR1NEO": + return "MUZIR1NEO" case "STATIONG2": return "STATIONG2" + /// Elecrow + case "THINKNODEM1": + return "THINKNODEM1" + case "THINKNODEM2": + return "THINKNODEM2" + case "THINKNODEM3": + return "THINKNODEM3" + case "THINKNODEM4": + return "THINKNODEM4" /// DIY Devices case "RPIPICO": return "RPIPICO" @@ -130,6 +176,7 @@ public func createUser(num: Int64, context: NSManagedObjectContext) throws -> Us newUser.longName = "Meshtastic \(last4)" newUser.shortName = last4 newUser.hwModel = "UNSET" + newUser.unmessagable = false } return newUser diff --git a/Meshtastic/Extensions/Url.swift b/Meshtastic/Extensions/Url.swift index 150bab42..fab43b98 100644 --- a/Meshtastic/Extensions/Url.swift +++ b/Meshtastic/Extensions/Url.swift @@ -31,6 +31,18 @@ extension URL { return nil } } + var queryParameters: [String: String]? { + guard let components = URLComponents(url: self, resolvingAgainstBaseURL: true), + let queryItems = components.queryItems else { + return nil + } + + var parameters = [String: String]() + for item in queryItems { + parameters[item.name] = item.value + } + return parameters + } var attributes: [FileAttributeKey: Any]? { do { return try FileManager.default.attributesOfItem(atPath: path) diff --git a/Meshtastic/Extensions/UserDefaults.swift b/Meshtastic/Extensions/UserDefaults.swift index d5a58e13..82e67773 100644 --- a/Meshtastic/Extensions/UserDefaults.swift +++ b/Meshtastic/Extensions/UserDefaults.swift @@ -6,6 +6,7 @@ // import Foundation +import OSLog @propertyWrapper struct UserDefault { @@ -79,6 +80,7 @@ extension UserDefaults { case showDeviceOnboarding case usageDataAndCrashReporting case autoconnectOnDiscovery + case manualConnections case testIntEnum } @@ -178,6 +180,36 @@ extension UserDefaults { @UserDefault(.testIntEnum, defaultValue: .one) static var testIntEnum: TestIntEnum + + static var manualConnections: [Device] { + get { + // Retrieve data from UserDefaults + guard let data = UserDefaults.standard.data(forKey: Keys.manualConnections.rawValue) else { + return [] + } + + // Decode the Data back to [Device] + do { + let decoder = JSONDecoder() + let devices = try decoder.decode([Device].self, from: data) + return devices + } catch { + return [] + } + } + set { + do { + // Encode the [Device] to Data + let encoder = JSONEncoder() + let data = try encoder.encode(newValue) + + // Store the Data in UserDefaults + UserDefaults.standard.set(data, forKey: Keys.manualConnections.rawValue) + } catch { + Logger.transport.error("💥 Failed to encode manualConnections: \(error, privacy: .public)") + } + } + } } enum TestIntEnum: Int, Decodable { diff --git a/Meshtastic/Helpers/LocationsHandler.swift b/Meshtastic/Helpers/LocationsHandler.swift index b174970a..6d44499d 100644 --- a/Meshtastic/Helpers/LocationsHandler.swift +++ b/Meshtastic/Helpers/LocationsHandler.swift @@ -26,6 +26,8 @@ import OSLog @Published var recordingStarted: Date? @Published var distanceTraveled = 0.0 @Published var elevationGain = 0.0 + @Published var heading: Double = 0.0 // Current heading in degrees + @Published var headingUpdatesStarted: Bool = false // Track heading updates state @Published var updatesStarted: Bool = UserDefaults.standard.bool(forKey: "liveUpdatesStarted") { @@ -131,6 +133,10 @@ import OSLog self.manager.desiredAccuracy = kCLLocationAccuracyBest // Set the distance filter to only receive updates when the device has moved a certain distance. self.manager.distanceFilter = kCLDistanceFilterNone // Receive all updates initially + if CLLocationManager.headingAvailable() { + self.manager.headingFilter = 1 // Update heading when it changes by 1 degree + self.manager.headingOrientation = .portrait // Adjust based on device orientation + } } func startLocationUpdates() { @@ -178,6 +184,39 @@ import OSLog // The Task completes implicitly here. } } + + // New method to start heading updates + func startHeadingUpdates() { + guard CLLocationManager.headingAvailable() else { + Logger.services.warning("📍 [App] Heading updates not available on this device.") + return + } + + guard manager.authorizationStatus == .authorizedAlways || manager.authorizationStatus == .authorizedWhenInUse else { + Logger.services.warning("📍 [App] Cannot start heading updates: insufficient authorization status.") + return + } + + Logger.services.info("📍 [App] Starting heading updates") + manager.startUpdatingHeading() + headingUpdatesStarted = true + } + + // New method to stop heading updates + func stopHeadingUpdates() { + Logger.services.info("🛑 [App] Stopping heading updates") + manager.stopUpdatingHeading() + headingUpdatesStarted = false + } + + // Implement the CLLocationManagerDelegate method for heading updates + func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) { + // Update heading on the main thread + Task { @MainActor in + self.heading = newHeading.trueHeading >= 0 ? newHeading.trueHeading : newHeading.magneticHeading + } + } + /// Stops receiving live location updates. func stopLocationUpdates() { Logger.services.info("🛑 [App] Stopping location updates") diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index 4d217dc7..255417c4 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -181,7 +181,7 @@ func channelPacket (channel: Channel, fromNum: Int64, context: NSManagedObjectCo newChannel.psk = channel.settings.psk if channel.settings.hasModuleSettings { newChannel.positionPrecision = Int32(truncatingIfNeeded: channel.settings.moduleSettings.positionPrecision) - newChannel.mute = channel.settings.moduleSettings.isClientMuted + newChannel.mute = channel.settings.moduleSettings.isMuted } guard let mutableChannels = fetchedMyInfo[0].channels!.mutableCopy() as? NSMutableOrderedSet else { return @@ -264,7 +264,7 @@ func deviceMetadataPacket (metadata: DeviceMetadata, fromNum: Int64, sessionPass } } -func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObjectContext) -> NodeInfoEntity? { +func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObjectContext, deferSave: Bool = false) -> NodeInfoEntity? { let logString = String.localizedStringWithFormat("[NodeInfo] received for: %@".localized, String(nodeInfo.num)) Logger.mesh.info("📟 \(logString, privacy: .public)") @@ -375,8 +375,10 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje newNode.myInfo = fetchedMyInfo[0] } do { - try context.save() - Logger.data.info("💾 Saved a new Node Info For: \(String(nodeInfo.num), privacy: .public)") + if !deferSave { + try context.save() + Logger.data.info("💾 Saved a new Node Info For: \(String(nodeInfo.num), privacy: .public)") + } return newNode } catch { context.rollback() @@ -500,8 +502,10 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje fetchedNode[0].myInfo = fetchedMyInfo[0] } do { - try context.save() - Logger.data.info("💾 [NodeInfo] saved for \(nodeInfo.num.toHex(), privacy: .public)") + if !deferSave { + try context.save() + Logger.data.info("💾 [NodeInfo] saved for \(nodeInfo.num.toHex(), privacy: .public)") + } return fetchedNode[0] } catch { context.rollback() @@ -620,6 +624,7 @@ func adminResponseAck (packet: MeshPacket, context: NSManagedObjectContext) { fetchedMessage[0].ackError = Int32(RoutingError.none.rawValue) fetchedMessage[0].receivedACK = true fetchedMessage[0].realACK = true + fetchedMessage[0].relayNode = Int64(packet.relayNode) fetchedMessage[0].ackSNR = packet.rxSnr if fetchedMessage[0].fromUser != nil { fetchedMessage[0].fromUser?.objectWillChange.send() @@ -695,9 +700,11 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana fetchedMessage[0].realACK = true } } + fetchedMessage[0].relayNode = Int64(packet.relayNode) fetchedMessage[0].ackError = Int32(routingMessage.errorReason.rawValue) if routingMessage.errorReason == Routing.Error.none { fetchedMessage[0].receivedACK = true + fetchedMessage[0].relays += 1 } fetchedMessage[0].ackSNR = packet.rxSnr @@ -940,6 +947,9 @@ func textMessageAppPacket( } else { newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970) } + if packet.relayNode != 0 { + newMessage.relayNode = Int64(packet.relayNode) + } newMessage.receivedACK = false newMessage.snr = packet.rxSnr newMessage.rssi = packet.rxRssi @@ -979,6 +989,7 @@ func textMessageAppPacket( 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 { @@ -1040,7 +1051,10 @@ func textMessageAppPacket( if newMessage.fromUser != nil && newMessage.toUser != nil { // Set Unread Message Indicators if packet.to == connectedNode { - appState?.unreadDirectMessages = newMessage.toUser?.unreadMessages ?? 0 + let unreadCount = newMessage.toUser?.unreadMessages(context: context, skipLastMessageCheck: true) ?? 0 // skipLastMessageCheck=true because we don't update lastMessage on our own connected node + Task { @MainActor in + appState?.unreadDirectMessages = unreadCount + } } if !(newMessage.fromUser?.mute ?? false) && newMessage.isEmoji == false { // Create an iOS Notification for the received DM message @@ -1068,7 +1082,7 @@ func textMessageAppPacket( do { let fetchedMyInfo = try context.fetch(fetchMyInfoRequest) if !fetchedMyInfo.isEmpty { - appState?.unreadChannelMessages = fetchedMyInfo[0].unreadMessages + appState?.unreadChannelMessages = fetchedMyInfo[0].unreadMessages(context: context) for channel in (fetchedMyInfo[0].channels?.array ?? []) as? [ChannelEntity] ?? [] { if channel.index == newMessage.channel { context.refresh(channel, mergeChanges: true) diff --git a/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift b/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift index 853533e9..936f23ad 100644 --- a/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift +++ b/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift @@ -25,6 +25,7 @@ class MqttClientProxyManager { var mqttClientProxy: CocoaMQTT? var topic = "msh" var debugLog = false + var shouldSubscribe = true func connectFromConfigSettings(node: NodeInfoEntity) { let originalAddress = node.mqttConfig?.address ?? "mqtt.meshtastic.org" let defaultServerAddress = "mqtt.meshtastic.org" @@ -43,6 +44,20 @@ class MqttClientProxyManager { let port = defaultServerPort let root = node.mqttConfig?.root?.count ?? 0 > 0 ? node.mqttConfig?.root : "msh" let prefix = root! + // Safely iterate channels and determine if any has downlink enabled + var hasAnyDownlinkEnabled = false + if let anyChannels = node.myInfo?.channels as? NSOrderedSet { + let channelEntities: [ChannelEntity] = anyChannels.array.compactMap { $0 as? ChannelEntity } + for channel in channelEntities { + if channel.downlinkEnabled == true { + hasAnyDownlinkEnabled = true + break + } + } + } + + shouldSubscribe = hasAnyDownlinkEnabled + topic = prefix + "/2/e" + "/#" // Require opt in to map report terms to connect if node.mqttConfig?.mapReportingEnabled ?? false && UserDefaults.mapReportingOptIn || !(node.mqttConfig?.mapReportingEnabled ?? false) { @@ -169,3 +184,4 @@ extension MqttClientProxyManager: CocoaMQTTDelegate { Logger.mqtt.debug("📲 [MQTT Client Proxy] pong") } } + diff --git a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 55.xcdatamodel/contents b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 55.xcdatamodel/contents index b5e4a81e..a6e5465f 100644 --- a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 55.xcdatamodel/contents +++ b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 55.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -164,6 +164,8 @@ + + diff --git a/Meshtastic/MeshtasticApp.swift b/Meshtastic/MeshtasticApp.swift index a83ddb9b..d60ed940 100644 --- a/Meshtastic/MeshtasticApp.swift +++ b/Meshtastic/MeshtasticApp.swift @@ -11,6 +11,7 @@ import DatadogRUM import DatadogTrace import DatadogLogs import DatadogSessionReplay + @main struct MeshtasticAppleApp: App { @@ -19,10 +20,8 @@ struct MeshtasticAppleApp: App { private let persistenceController: PersistenceController private let accessoryManager: AccessoryManager @Environment(\.scenePhase) var scenePhase - @State var saveChannels = false + @State var saveChannelLink: SaveChannelLinkData? @State var incomingUrl: URL? - @State var channelSettings: String? - @State var addChannels = false init() { @@ -36,7 +35,7 @@ struct MeshtasticAppleApp: App { let appID = "79fe92a9-74c9-4c8f-ba63-6308384ecfa9" let clientToken = "pub4427bea20dbdb08a6af68034de22cd3b" var environment = "AppStore" - + #if DEBUG environment = "Local" #else @@ -44,7 +43,7 @@ struct MeshtasticAppleApp: App { environment = "TestFlight" } #endif - + Datadog.initialize( with: Datadog.Configuration( clientToken: clientToken, @@ -57,7 +56,7 @@ struct MeshtasticAppleApp: App { Logs.enable() Trace.enable( with: Trace.Configuration( - sampleRate: 100, networkInfoEnabled: true // 100% sampling for development/testing, reduce for production + sampleRate: 100, networkInfoEnabled: true // 100% sampling for development/testing, reduce for production ) ) @@ -98,32 +97,54 @@ struct MeshtasticAppleApp: App { #endif if !UserDefaults.firstLaunch { // If this is first launch, we will show onboarding screens which - // Step through the authorization process. Do not start discovery + // Step through the authorization process. Do not start discovery // unitl this workflow completes, otherwise the discovery process // may trigger permission dialogs too soon. accessoryManager.startDiscovery() } } - var body: some Scene { - WindowGroup { + + private func handleChannelLinkURL(_ url: URL, fromActivity: Bool) { + // Reset the state before processing a new URL + self.saveChannelLink = nil + + guard url.absoluteString.lowercased().contains("meshtastic.org/e/") else { + return + } + + let queryParams = url.queryParameters + let addChannels = Bool(queryParams?["add"] ?? "false") ?? false + var channelData: String? + let urlString = url.absoluteString + + if let fragment = urlString.components(separatedBy: "#").last, !fragment.isEmpty { + channelData = fragment.components(separatedBy: "?").first + } + + guard let finalChannelData = channelData, !finalChannelData.isEmpty else { + Logger.mesh.error("Could not extract channel data from URL: \(url.absoluteString, privacy: .public)") + return + } + + self.saveChannelLink = SaveChannelLinkData(data: finalChannelData, add: addChannels) + Logger.services.debug("Add Channel \(addChannels, privacy: .public) with data: \(finalChannelData, privacy: .public)") + + // Log based on the calling context + let source = fromActivity ? "User Activity" : "Open URL" + Logger.mesh.debug("User wants to open a Channel Settings URL (\(source)): \(url.absoluteString, privacy: .public)") + } + + var body: some Scene { + WindowGroup { ContentView( appState: appState, router: appState.router ) - .sheet(isPresented: Binding( - get: { - saveChannels && !(channelSettings == nil) - }, - set: { newValue in - saveChannels = newValue - if !newValue { - channelSettings = nil - } - } - )) { + .sheet(item: $saveChannelLink + ) { link in SaveChannelQRCode( - channelSetLink: channelSettings ?? "Empty Channel URL", - addChannels: addChannels, + channelSetLink: link.data, + addChannels: link.add, // <-- Uses the now reliable 'add' boolean accessoryManager: accessoryManager ) .presentationDetents([.large]) .presentationDragIndicator(.visible) @@ -131,55 +152,30 @@ struct MeshtasticAppleApp: App { .onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in Logger.mesh.debug("URL received \(userActivity, privacy: .public)") self.incomingUrl = userActivity.webpageURL - self.saveChannels = false - if self.incomingUrl?.absoluteString.lowercased().contains("meshtastic.org/v/#") == true { - ContactURLHandler.handleContactUrl(url: self.incomingUrl!, accessoryManager: accessoryManager) - } else if self.incomingUrl?.absoluteString.lowercased().contains("meshtastic.org/e/") == true { - if let components = self.incomingUrl?.absoluteString.components(separatedBy: "#") { - self.addChannels = Bool(self.incomingUrl?["add"] ?? "false") ?? false - if (self.incomingUrl?.absoluteString.lowercased().contains("?")) != nil { - guard let cs = components.last!.components(separatedBy: "?").first else { - return - } - self.channelSettings = cs - } else { - guard let cs = components.first else { - return - } - self.channelSettings = cs - } - Logger.services.debug("Add Channel \(self.addChannels, privacy: .public)") + self.saveChannelLink = nil + + if let url = userActivity.webpageURL { + if url.absoluteString.lowercased().contains("meshtastic.org/v/#") == true { + ContactURLHandler.handleContactUrl(url: url, accessoryManager: accessoryManager) + } else if url.absoluteString.lowercased().contains("meshtastic.org/e/") == true { + // **Consolidated Call for User Activity** + handleChannelLinkURL(url, fromActivity: true) } - self.saveChannels = true - Logger.mesh.debug("User wants to open a Channel Settings URL: \(self.incomingUrl?.absoluteString ?? "No QR Code Link")") } - if self.saveChannels { + + if self.saveChannelLink != nil { Logger.mesh.debug("User wants to open Channel Settings URL: \(String(describing: self.incomingUrl!.relativeString), privacy: .public)") } } .onOpenURL(perform: { (url) in Logger.mesh.debug("Some sort of URL was received \(url, privacy: .public)") self.incomingUrl = url + if url.absoluteString.lowercased().contains("meshtastic.org/v/#") { ContactURLHandler.handleContactUrl(url: url, accessoryManager: accessoryManager) } else if url.absoluteString.lowercased().contains("meshtastic.org/e/") { - if let components = self.incomingUrl?.absoluteString.components(separatedBy: "#") { - self.addChannels = Bool(self.incomingUrl?["add"] ?? "false") ?? false - if self.incomingUrl?.absoluteString.lowercased().contains("?") != nil { - guard let cs = components.last!.components(separatedBy: "?").first else { - return - } - self.channelSettings = cs - } else { - guard let cs = components.first else { - return - } - self.channelSettings = cs - } - Logger.services.debug("Add Channel \(self.addChannels, privacy: .public)") - } - self.saveChannels = true - Logger.mesh.debug("User wants to open a Channel Settings URL: \(self.incomingUrl?.absoluteString ?? "No QR Code Link", privacy: .public)") + // **Consolidated Call for Open URL** + handleChannelLinkURL(url, fromActivity: false) } else if url.absoluteString.lowercased().contains("meshtastic:///") { appState.router.route(url: url) } @@ -194,7 +190,7 @@ struct MeshtasticAppleApp: App { .displayFrequency(.immediate) ] ) - } + } } .onChange(of: scenePhase) { (_, newScenePhase) in switch newScenePhase { @@ -221,7 +217,5 @@ struct MeshtasticAppleApp: App { .environment(\.managedObjectContext, persistenceController.container.viewContext) .environmentObject(appState) .environmentObject(accessoryManager) - .environmentObject(appState.router) } - } diff --git a/Meshtastic/Persistence/UpdateCoreData.swift b/Meshtastic/Persistence/UpdateCoreData.swift index 3f758329..c56644a5 100644 --- a/Meshtastic/Persistence/UpdateCoreData.swift +++ b/Meshtastic/Persistence/UpdateCoreData.swift @@ -165,6 +165,60 @@ public func clearCoreDataDatabase(context: NSManagedObjectContext, includeRoutes } } +func updateAnyPacketFrom (packet: MeshPacket, activeDeviceNum: Int64, context: NSManagedObjectContext) { + // Update NodeInfoEntity for any packet received. This mirrors the firmware's NodeDB::updateFrom, which sniffs ALL received packets and updates the radio's nodeDB with packet.from's: + // - last_heard (from rxTime) + // - snr + // - via_mqtt + // - hops_away + + // However, unlike the firmware, this function will NOT create a new NodeInfoEntity if we don't have it already. We'll leave that to the existing code paths. + + // We do NOT update fetchedNode[0].channel, because we may hear a node over multiple channels, and only some packet types should update what we consider the node's channel to be. (Example: primary private channel, secondary public channel. A text message on the secondary public channel should NOT change fetchedNode[0].channel.) + + guard packet.from > 0 else { return } + guard packet.from != activeDeviceNum else { return } // Ignore if packet is from our own node + + let fetchNodeInfoAppRequest = NodeInfoEntity.fetchRequest() + fetchNodeInfoAppRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from)) + + do { + let fetchedNode = try context.fetch(fetchNodeInfoAppRequest) + if fetchedNode.count >= 1 { + fetchedNode[0].id = Int64(packet.from) + fetchedNode[0].num = Int64(packet.from) + + if packet.rxTime > 0 { + fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime))) + Logger.data.info("💾 [updateAnyPacketFrom] Updating node \(packet.from.toHex(), privacy: .public) lastHeard from rxTime=\(packet.rxTime)") + } else { + fetchedNode[0].lastHeard = Date() + Logger.data.info("💾 [updateAnyPacketFrom] Updating node \(packet.from.toHex(), privacy: .public) lastHeard to now (rxTime==0)") + } + + fetchedNode[0].snr = packet.rxSnr + fetchedNode[0].rssi = packet.rxRssi + fetchedNode[0].viaMqtt = packet.viaMqtt + + if packet.hopStart != 0 && packet.hopLimit <= packet.hopStart { + fetchedNode[0].hopsAway = Int32(packet.hopStart - packet.hopLimit) + Logger.data.info("💾 [updateAnyPacketFrom] Updating node \(packet.from.toHex(), privacy: .public) hopsAway=\(fetchedNode[0].hopsAway)") + } + + do { + try context.save() + Logger.data.info("💾 [updateAnyPacketFrom] Updating node \(fetchedNode[0].num.toHex(), privacy: .public) snr=\(fetchedNode[0].snr), rssi=\(fetchedNode[0].rssi) from packet \(packet.id.toHex(), privacy: .public)") + } catch { + context.rollback() + let nsError = error as NSError + Logger.data.error("💥 [updateAnyPacketFrom] Error Saving node \(fetchedNode[0].num.toHex(), privacy: .public) from packet \(packet.id.toHex(), privacy: .public) \(nsError, privacy: .public)") + } + } + } catch { + Logger.data.error("💥 [updateAnyPacketFrom] fetch data error") + } +} + func upsertNodeInfoPacket (packet: MeshPacket, favorite: Bool = false, context: NSManagedObjectContext) { let logString = String.localizedStringWithFormat("[NodeInfo] received for: %@".localized, packet.from.toHex()) @@ -316,16 +370,6 @@ func upsertNodeInfoPacket (packet: MeshPacket, favorite: Bool = false, context: } else { // Update an existing node - fetchedNode[0].id = Int64(packet.from) - fetchedNode[0].num = Int64(packet.from) - if packet.rxTime > 0 { - fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime))) - } else { - fetchedNode[0].lastHeard = Date() - } - fetchedNode[0].snr = packet.rxSnr - fetchedNode[0].rssi = packet.rxRssi - fetchedNode[0].viaMqtt = packet.viaMqtt if packet.to == Constants.maximumNodeNum || packet.to == UserDefaults.preferredPeripheralNum { fetchedNode[0].channel = Int32(packet.channel) } @@ -463,18 +507,7 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext) mutablePositions.removeAllObjects() } mutablePositions.add(position) - fetchedNode[0].id = Int64(packet.from) - fetchedNode[0].num = Int64(packet.from) - if positionMessage.time > 0 { - fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(positionMessage.time))) - } else if packet.rxTime > 0 { - fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime))) - } else { - fetchedNode[0].lastHeard = Date() - } - fetchedNode[0].snr = packet.rxSnr - fetchedNode[0].rssi = packet.rxRssi - fetchedNode[0].viaMqtt = packet.viaMqtt + fetchedNode[0].channel = Int32(packet.channel) fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet @@ -1499,6 +1532,7 @@ func upsertTelemetryModuleConfigPacket(config: ModuleConfig.TelemetryConfig, nod if fetchedNode[0].telemetryConfig == nil { let newTelemetryConfig = TelemetryConfigEntity(context: context) newTelemetryConfig.deviceUpdateInterval = Int32(truncatingIfNeeded: config.deviceUpdateInterval) + newTelemetryConfig.deviceTelemetryEnabled = config.deviceTelemetryEnabled newTelemetryConfig.environmentUpdateInterval = Int32(truncatingIfNeeded: config.environmentUpdateInterval) newTelemetryConfig.environmentMeasurementEnabled = config.environmentMeasurementEnabled newTelemetryConfig.environmentScreenEnabled = config.environmentScreenEnabled @@ -1509,6 +1543,7 @@ func upsertTelemetryModuleConfigPacket(config: ModuleConfig.TelemetryConfig, nod fetchedNode[0].telemetryConfig = newTelemetryConfig } else { fetchedNode[0].telemetryConfig?.deviceUpdateInterval = Int32(truncatingIfNeeded: config.deviceUpdateInterval) + fetchedNode[0].telemetryConfig?.deviceTelemetryEnabled = config.deviceTelemetryEnabled fetchedNode[0].telemetryConfig?.environmentUpdateInterval = Int32(truncatingIfNeeded: config.environmentUpdateInterval) fetchedNode[0].telemetryConfig?.environmentMeasurementEnabled = config.environmentMeasurementEnabled fetchedNode[0].telemetryConfig?.environmentScreenEnabled = config.environmentScreenEnabled diff --git a/Meshtastic/Resources/DeviceHardware.json b/Meshtastic/Resources/DeviceHardware.json index 1306cfd2..3db1437d 100644 --- a/Meshtastic/Resources/DeviceHardware.json +++ b/Meshtastic/Resources/DeviceHardware.json @@ -908,6 +908,22 @@ "thinknode_m2.svg" ] }, + { + "hwModel": 93, + "hwModelSlug": "MUZI_BASE", + "platformioTarget": "muzi-base", + "architecture": "nrf52840", + "activelySupported": false, + "supportLevel": 1, + "displayName": "muzi base", + "tags": [ + "muzi" + ], + "requiresDfu": true, + "images": [ + "muzi_base.svg" + ] + }, { "hwModel": 94, "hwModelSlug": "HELTEC_MESH_POCKET", @@ -923,7 +939,28 @@ "heltec_mesh_pocket.svg" ], "requiresDfu": true, - "hasInkHud": true + "hasInkHud": true, + "key": "HELTEC_MESH_POCKET", + "variant": "10000mAh" + }, + { + "hwModel": 94, + "hwModelSlug": "HELTEC_MESH_POCKET", + "platformioTarget": "heltec-mesh-pocket-5000", + "architecture": "nrf52840", + "activelySupported": true, + "supportLevel": 1, + "displayName": "Heltec MeshPocket", + "tags": [ + "Heltec" + ], + "images": [ + "heltec_mesh_pocket.svg" + ], + "requiresDfu": true, + "hasInkHud": true, + "key": "HELTEC_MESH_POCKET", + "variant": "5000mAh" }, { "hwModel": 95, @@ -1051,7 +1088,7 @@ "hwModelSlug": "MUZI_R1_NEO", "platformioTarget": "r1-neo", "architecture": "nrf52840", - "activelySupported": false, + "activelySupported": true, "supportLevel": 1, "displayName": "muzi R1 Neo", "tags": [ @@ -1181,5 +1218,70 @@ "images": [ "rak_3312.svg" ] + }, + { + "hwModel": 115, + "hwModelSlug": "THINKNODE_M3", + "platformioTarget": "thinknode_m3", + "architecture": "nrf52840", + "activelySupported": true, + "supportLevel": 1, + "displayName": "ThinkNode M3", + "tags": [ + "Elecrow" + ], + "requiresDfu": true, + "images": [ + "thinknode_m3.svg" + ] + }, + { + "hwModel": 116, + "hwModelSlug": "WISMESH_TAP_V2", + "platformioTarget": "rak_wismesh_tap_v2", + "architecture": "esp32-s3", + "activelySupported": false, + "supportLevel": 1, + "displayName": "RAK WisMesh Tap V2", + "tags": [ + "RAK" + ], + "hasMui": true, + "partitionScheme": "8MB", + "images": [ + "rak-wismesh-tap-v2.svg" + ] + }, + { + "hwModel": 119, + "hwModelSlug": "THINKNODE_M4", + "platformioTarget": "thinknode_m4", + "architecture": "nrf52840", + "activelySupported": false, + "supportLevel": 1, + "displayName": "ThinkNode M4", + "tags": [ + "Elecrow" + ], + "requiresDfu": true, + "images": [ + "thinknode_m4.svg" + ] + }, + { + "hwModel": 120, + "hwModelSlug": "THINKNODE_M6", + "platformioTarget": "thinknode_m6", + "architecture": "nrf52840", + "activelySupported": false, + "supportLevel": 1, + "displayName": "ThinkNode M6", + "tags": [ + "Elecrow" + ], + "requiresDfu": true, + "images": [ + "thinknode_m6.svg" + ] } ] diff --git a/Meshtastic/Views/Connect/Connect.swift b/Meshtastic/Views/Connect/Connect.swift index 8915d9ff..bb43ae04 100644 --- a/Meshtastic/Views/Connect/Connect.swift +++ b/Meshtastic/Views/Connect/Connect.swift @@ -26,8 +26,7 @@ struct Connect: View { @State var isUnsetRegion = false @State var invalidFirmwareVersion = false @State var liveActivityStarted = false - @State var presentingSwitchPreferredPeripheral = false - @State var selectedPeripherialId = "" + @ObservedObject var manualConnections = ManualConnectionList.shared var body: some View { NavigationStack { @@ -264,61 +263,33 @@ struct Connect: View { .textCase(nil) if !(accessoryManager.isConnected || accessoryManager .isConnecting) { - Section(header: HStack { - Text("Available Radios").font(.title) - Spacer() - ManualConnectionMenu() - }) { - ForEach(accessoryManager.devices.sorted(by: { $0.name < $1.name })) { device in - HStack { - if UserDefaults.preferredPeripheralId == device.id.uuidString { - Image(systemName: "star.fill") - .imageScale(.large).foregroundColor(.yellow) - .padding(.trailing) - } else { - Image(systemName: "circle.fill") - .imageScale(.large).foregroundColor(.gray) - .padding(.trailing) - } - VStack(alignment: .leading) { - Button(action: { - if UserDefaults.preferredPeripheralId.count > 0 && device.id.uuidString != UserDefaults.preferredPeripheralId { - if accessoryManager.allowDisconnect { - Task { try await accessoryManager.disconnect() } - } - presentingSwitchPreferredPeripheral = true - selectedPeripherialId = device.id.uuidString - } else { - Task { - try? await accessoryManager.connect(to: device) + Group { + Section(header: HStack { + Text("Available Radios").font(.title) + Spacer() + ManualConnectionMenu() + }) { + ForEach(accessoryManager.devices.sorted(by: { $0.name < $1.name })) { device in + DeviceConnectRow(device: device) + } + } + if manualConnections.connectionsList.count > 0 { + Section(header: Text("Manual Connections").font(.title)) { + ForEach(manualConnections.connectionsList) { device in + DeviceConnectRow(device: device) +#if targetEnvironment(macCatalyst) + .contextMenu { + Button { + manualConnections.remove(device: device) + } label: { + Label("Delete", systemImage: "trash") } } - }) { - Text(device.name).font(.callout) - } - // Show transport type - TransportIcon(transportType: device.transportType) - } - Spacer() - VStack { - device.getSignalStrength().map { SignalStrengthIndicator(signalStrength: $0) } - } - }.padding([.bottom, .top]) - } - } - .confirmationDialog("Connecting to a new radio will clear all app data on the phone.", isPresented: $presentingSwitchPreferredPeripheral, titleVisibility: .visible) { - Button("Connect to new radio?", role: .destructive) { - UserDefaults.preferredPeripheralId = selectedPeripherialId - UserDefaults.preferredPeripheralNum = 0 - if accessoryManager.allowDisconnect { - Task { try await accessoryManager.disconnect() } - } - clearCoreDataDatabase(context: context, includeRoutes: false) - clearNotifications() - if let radio = accessoryManager.devices.first(where: { $0.id.uuidString == selectedPeripherialId }) { - Task { - try await accessoryManager.connect(to: radio) +#endif + }.onDelete { offsets in + manualConnections.remove(atOffsets: offsets) } + } } } @@ -472,6 +443,10 @@ struct TransportIcon: View { } struct ManualConnectionMenu: View { + + @EnvironmentObject var accessoryManager: AccessoryManager + @Environment(\.managedObjectContext) var context + private struct IterableTransport: Identifiable { let id: UUID let icon: Image @@ -490,7 +465,9 @@ struct ManualConnectionMenu: View { @State private var selectedTransport: IterableTransport? @State private var showAlert: Bool = false @State private var connectionString = "" - + @State var presentingSwitchPreferredPeripheral = false + @State var deviceForManualConnection: Device? + var body: some View { Menu { ForEach(transports) { transport in @@ -520,11 +497,114 @@ struct ManualConnectionMenu: View { Button("OK", action: { if !connectionString.isEmpty { - Task { - try await selectedTransport.transport.manuallyConnect(withConnectionString: connectionString) + if let device = selectedTransport.transport.device(forManualConnection: connectionString) { + if UserDefaults.preferredPeripheralId == device.id.uuidString { + Task { + try await selectedTransport.transport.manuallyConnect(toDevice: device) + } + } else { + deviceForManualConnection = device + presentingSwitchPreferredPeripheral = true + } } } }) - } + }.confirmationDialog("Connecting to a new radio will clear all app data on the phone.", isPresented: $presentingSwitchPreferredPeripheral, titleVisibility: .visible) { + Button("Connect to new radio?", role: .destructive) { + if let device = deviceForManualConnection { + UserDefaults.preferredPeripheralId = device.id.uuidString + UserDefaults.preferredPeripheralNum = 0 + if accessoryManager.allowDisconnect { + Task { try await accessoryManager.disconnect() } + } + clearCoreDataDatabase(context: context, includeRoutes: false) + clearNotifications() + Task { + try await selectedTransport?.transport.manuallyConnect(toDevice: device) + } + + // Clean up just in case + deviceForManualConnection = nil + } + } + } } } + +struct DeviceConnectRow: View { + @Environment(\.managedObjectContext) var context + @EnvironmentObject var accessoryManager: AccessoryManager + @State var presentingSwitchPreferredPeripheral = false + let device: Device + + var body: some View { + HStack { + if UserDefaults.preferredPeripheralId == device.id.uuidString { + Image(systemName: "star.fill") + .imageScale(.large).foregroundColor(.yellow) + .padding(.trailing) + } else { + Image(systemName: "circle.fill") + .imageScale(.large).foregroundColor(.gray) + .padding(.trailing) + } + VStack(alignment: .leading) { + Button(action: { + if UserDefaults.preferredPeripheralId.count > 0 && device.id.uuidString != UserDefaults.preferredPeripheralId { + if accessoryManager.allowDisconnect { + Task { try await accessoryManager.disconnect() } + } + presentingSwitchPreferredPeripheral = true + } else { + Task { + try? await accessoryManager.connect(to: device) + } + } + }) { + Text(device.name).font(.callout) + } + // Show transport type +#if !targetEnvironment(macCatalyst) + HStack(alignment: .center){ + TransportIcon(transportType: device.transportType) + if device.isManualConnection && (device.longName != nil || device.shortName != nil) { + VStack (alignment: .leading) { + Text("Last seen device:") + Text("\(String(describing: device))") + } + } + }.padding(.top, 3.0) +#else + //Different alignment for Mac + HStack(alignment: .firstTextBaseline){ + TransportIcon(transportType: device.transportType) + if device.isManualConnection && (device.longName != nil || device.shortName != nil) { + Text("Last seen device: \(String(describing: device))") + } + } +#endif + } + Spacer() + VStack { + device.getSignalStrength().map { + SignalStrengthIndicator(signalStrength: $0) + } + } + }.padding([.bottom, .top]) + .confirmationDialog("Connecting to a new radio will clear all app data on the phone.", isPresented: $presentingSwitchPreferredPeripheral, titleVisibility: .visible) { + Button("Connect to new radio?", role: .destructive) { + UserDefaults.preferredPeripheralId = device.id.uuidString + UserDefaults.preferredPeripheralNum = 0 + if accessoryManager.allowDisconnect { + Task { try await accessoryManager.disconnect() } + } + clearCoreDataDatabase(context: context, includeRoutes: false) + clearNotifications() + Task { + try await accessoryManager.connect(to: device) + } + } + } + } +} + diff --git a/Meshtastic/Views/Helpers/CompassView.swift b/Meshtastic/Views/Helpers/CompassView.swift new file mode 100644 index 00000000..1e58b224 --- /dev/null +++ b/Meshtastic/Views/Helpers/CompassView.swift @@ -0,0 +1,295 @@ +// +// CompassView.swift +// Meshtastic +// +// Created by Benjamin Faershtein on 11/14/25. +// + +import SwiftUI +import CoreLocation +import UIKit + +struct CompassView: View { + + /// Single waypoint parameter + let waypointLocation: CLLocationCoordinate2D? + + let waypointName: String? + + let color: Color + + @ObservedObject private var locationsHandler = LocationsHandler.shared + + // Haptic alignment tracking + private let alignmentTolerance: Double = 5.0 + @State private var inAlignment = false + + // Compute bearing from user → waypoint + private func bearingToWaypoint() -> Double? { + guard + let waypoint = waypointLocation, + let user = LocationsHandler.currentLocation + else { return nil } + + return BearingCalculator.bearingBetween( + userLocation: user, + waypoint: waypoint + ) + } + + // Trigger a vibration if aligned with waypoint + private func checkAlignment(bearing: Double,heading: Double) { + // Compute minimal angular difference between heading and bearing in [0, 180] + let rawDiff = abs(heading - bearing).truncatingRemainder(dividingBy: 360) + let diff = min(rawDiff, 360 - rawDiff) + + if diff <= alignmentTolerance { + if !inAlignment { + inAlignment = true + let generator = UIImpactFeedbackGenerator(style: .heavy) + generator.impactOccurred() + } + } else { + inAlignment = false + } + } + + + private func distanceToWaypoint() -> CLLocationDistance? { + guard + let waypoint = waypointLocation, + let user = LocationsHandler.currentLocation + else { return nil } + + let userLocation = CLLocation(latitude: user.latitude, longitude: user.longitude) + let waypointLocation = CLLocation(latitude: waypoint.latitude, longitude: waypoint.longitude) + + return userLocation.distance(from: waypointLocation) + } + + // Format distance with localization + private func formatDistance(_ distance: CLLocationDistance) -> String { + let measurement = Measurement(value: distance, unit: UnitLength.meters) + let formatter = MeasurementFormatter() + formatter.unitOptions = .naturalScale + formatter.numberFormatter.maximumFractionDigits = 2 + return formatter.string(from: measurement) + } + + + var body: some View { + NavigationStack { + VStack(spacing: 15) { + + VStack(spacing: 8) { + Text(waypointName ?? "Waypoint") + .font(.title2) + .bold() + .foregroundColor(color) + + if let wp = waypointLocation { + HStack{ + Image(systemName: "mappin.and.ellipse") + Text("\(String(format: "%.4f", wp.latitude)), \(String(format: "%.4f", wp.longitude))") + .font(.subheadline) + } + + if let distance = distanceToWaypoint() { + HStack{ + Image(systemName: "lines.measurement.horizontal") + Text("Distance: \(formatDistance(distance))") + .font(.subheadline) + .fontWeight(.semibold) + } + } + HStack { + Image(systemName: "location.north") + if let bearing = bearingToWaypoint() { + Text("Bearing: \(String(format: "%.0f°", bearing))") + .font(.subheadline) + } else { + Text("Bearing: N/A") + .font(.subheadline) + } + } + } + } + .padding() + + Capsule() + .frame(width: 5, height: 50) + ZStack { + + // Cardinal/degree markers + ForEach(Marker.markers(), id: \.self) { marker in + CompassMarkerView( + marker: marker, + compassDegrees: -locationsHandler.heading + ) + } + + // Waypoint bearing indicator + if let bearing = bearingToWaypoint() { + WaypointMarkerView( + bearing: bearing, + compassDegrees: locationsHandler.heading, + color: color + ) + // Move waypoint marker outside compass + .onChange(of: locationsHandler.heading) { _, _ in + checkAlignment(bearing: bearing,heading:locationsHandler.heading) + } + } + + } + .frame(width: 300, height: 300) + .rotationEffect(Angle(degrees: -locationsHandler.heading)) + .statusBar(hidden: true) + .onAppear { + locationsHandler.startHeadingUpdates() + locationsHandler.startLocationUpdates() + } + .onDisappear { + locationsHandler.stopHeadingUpdates() + locationsHandler.stopLocationUpdates() + } + .navigationTitle("Compass") + } + } + } +} + + +// MARK: - Waypoint Marker View + +struct WaypointMarkerView: View { + let bearing: Double + let compassDegrees: Double + let color: Color + + var body: some View { + Circle() + .frame(width: 20, height: 20) + .foregroundColor(color) + .offset(y: -170) + .rotationEffect(Angle(degrees: bearing)) + } + +} + + +// MARK: - Bearing Calculator + +struct BearingCalculator { + + static func bearingBetween( + userLocation: CLLocationCoordinate2D, + waypoint: CLLocationCoordinate2D + ) -> Double { + + let lat1 = userLocation.latitude * .pi / 180 + let lon1 = userLocation.longitude * .pi / 180 + let lat2 = waypoint.latitude * .pi / 180 + let lon2 = waypoint.longitude * .pi / 180 + + let dLon = lon2 - lon1 + + let y = sin(dLon) * cos(lat2) + let x = cos(lat1) * sin(lat2) + - sin(lat1) * cos(lat2) * cos(dLon) + + var bearing = atan2(y, x) * 180 / .pi + if bearing < 0 { bearing += 360 } + + return bearing + } +} + + +// MARK: - Marker Model + +struct Marker: Hashable { + let degrees: Double + let label: String + + init(degrees: Double, label: String = "") { + self.degrees = degrees + self.label = label + } + + func degreeText() -> String { + return String(format: "%.0f", self.degrees) + } + + static func markers() -> [Marker] { + return [ + Marker(degrees: 0, label: "N"), + Marker(degrees: 30), + Marker(degrees: 60), + Marker(degrees: 90, label: "E"), + Marker(degrees: 120), + Marker(degrees: 150), + Marker(degrees: 180, label: "S"), + Marker(degrees: 210), + Marker(degrees: 240), + Marker(degrees: 270, label: "W"), + Marker(degrees: 300), + Marker(degrees: 330) + ] + } +} + + +// MARK: - Compass Marker View + +struct CompassMarkerView: View { + let marker: Marker + let compassDegrees: Double + + var body: some View { + VStack { + Text(marker.degreeText()) + .fontWeight(.light) + .rotationEffect(textAngle()) + + Capsule() + .frame(width: capsuleWidth(), height: capsuleHeight()) + .foregroundColor(capsuleColor()) + + Text(marker.label) + .fontWeight(.bold) + .rotationEffect(textAngle()) + .padding(.bottom, 180) + } + .rotationEffect(Angle(degrees: marker.degrees)) + } + + private func capsuleWidth() -> CGFloat { + marker.degrees == 0 ? 7 : 3 + } + + private func capsuleHeight() -> CGFloat { + marker.degrees == 0 ? 45 : 30 + } + + private func capsuleColor() -> Color { + marker.degrees == 0 ? .red : .gray + } + + private func textAngle() -> Angle { + Angle(degrees: -compassDegrees - marker.degrees) + } +} + + +// MARK: - Preview + +struct CompassView_Previews: PreviewProvider { + static var previews: some View { + CompassView( + waypointLocation: CLLocationCoordinate2D(latitude: 37.3346, longitude: -122.0090), + waypointName: "Apple Park", + color: Color.orange + ) + } +} diff --git a/Meshtastic/Views/Helpers/ConnectedDevice.swift b/Meshtastic/Views/Helpers/ConnectedDevice.swift index 1cb46948..deb26509 100644 --- a/Meshtastic/Views/Helpers/ConnectedDevice.swift +++ b/Meshtastic/Views/Helpers/ConnectedDevice.swift @@ -1,22 +1,31 @@ /* -Abstract: -A view draws the indicator used in the upper right corner for views using BLE -*/ + Abstract: + A view draws the indicator used in the upper right corner for views using BLE + */ import SwiftUI struct ConnectedDevice: View { - @EnvironmentObject var accessoryManager: AccessoryManager - var deviceConnected: Bool - var name: String - var mqttProxyConnected: Bool = false - var mqttUplinkEnabled: Bool = false - var mqttDownlinkEnabled: Bool = false - var mqttTopic: String = "" - var phoneOnly: Bool = false - var showActivityLights: Bool - - init(deviceConnected: Bool, name: String, mqttProxyConnected: Bool = false, mqttUplinkEnabled: Bool = false, mqttDownlinkEnabled: Bool = false, mqttTopic: String = "", phoneOnly: Bool = false, showActivityLights: Bool = true) { + + let deviceConnected: Bool + let name: String + let mqttProxyConnected: Bool + let mqttUplinkEnabled: Bool + let mqttDownlinkEnabled: Bool + let mqttTopic: String + let phoneOnly: Bool + let showActivityLights: Bool + + init( + deviceConnected: Bool, + name: String, + mqttProxyConnected: Bool = false, + mqttUplinkEnabled: Bool = false, + mqttDownlinkEnabled: Bool = false, + mqttTopic: String = "", + phoneOnly: Bool = false, + showActivityLights: Bool = true + ) { self.deviceConnected = deviceConnected self.name = name self.mqttProxyConnected = mqttProxyConnected @@ -27,12 +36,12 @@ struct ConnectedDevice: View { self.showActivityLights = showActivityLights } - var body: some View { + var body: some View { HStack { if showActivityLights { RXTXIndicatorWidget() } - if (phoneOnly && UIDevice.current.userInterfaceIdiom == .phone) || !phoneOnly { + if (phoneOnly && UIDevice.current.userInterfaceIdiom == .phone) || !phoneOnly { if deviceConnected { // Create an HStack for connected state with proper accessibility HStack { @@ -64,24 +73,37 @@ struct ConnectedDevice: View { .accessibilityElement(children: .ignore) .accessibilityLabel("No Bluetooth device connected".localized) } - } + } } .if(.os26) { $0.padding(.leading, 5.0) } - } + } } -struct ConnectedDevice_Previews: PreviewProvider { - static var previews: some View { - VStack(alignment: .trailing) { - ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: true) - ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: true, mqttDownlinkEnabled: true) - ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: true, mqttDownlinkEnabled: true, mqttTopic: "msh/US/2/e/#") - ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: true, mqttDownlinkEnabled: false) - ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: true, mqttDownlinkEnabled: false) - ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: false, mqttDownlinkEnabled: true) - ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: false, mqttDownlinkEnabled: true) - ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: true) - ConnectedDevice(deviceConnected: false, name: "MEMO", mqttProxyConnected: false) - }.previewLayout(.fixed(width: 150, height: 275)) - } +#Preview("Multiple variants") { + VStack(alignment: .trailing) { + ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: true) + ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: true, mqttDownlinkEnabled: true) + ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: true, mqttDownlinkEnabled: true, mqttTopic: "msh/US/2/e/#") + ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: true, mqttDownlinkEnabled: false) + ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: true, mqttDownlinkEnabled: false) + ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: false, mqttUplinkEnabled: false, mqttDownlinkEnabled: true) + ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: true, mqttUplinkEnabled: false, mqttDownlinkEnabled: true) + ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: true) + ConnectedDevice(deviceConnected: false, name: "MEMO", mqttProxyConnected: false) + } + .environmentObject(AccessoryManager.shared) +} + +#Preview("Navigation header item") { + NavigationView { + Text("Connect screen") + .navigationTitle("Connect") + .navigationBarItems( + leading: MeshtasticLogo(), + trailing: ZStack { + ConnectedDevice(deviceConnected: true, name: "MEMO", mqttProxyConnected: false) + .environmentObject(AccessoryManager.shared) + } + ) + } } diff --git a/Meshtastic/Views/Helpers/RXTXIndicatorView.swift b/Meshtastic/Views/Helpers/RXTXIndicatorView.swift index 25168718..860b3734 100644 --- a/Meshtastic/Views/Helpers/RXTXIndicatorView.swift +++ b/Meshtastic/Views/Helpers/RXTXIndicatorView.swift @@ -12,7 +12,7 @@ import OSLog struct RXTXIndicatorWidget: View { @EnvironmentObject var accessoryManager: AccessoryManager @State private var isPopoverOpen = false - + let fontSize: CGFloat = 7.0 var body: some View { Button( action: { @@ -38,7 +38,7 @@ struct RXTXIndicatorWidget: View { #else self.isPopoverOpen.toggle() #endif - + }) { VStack(spacing: 3.0) { HStack(spacing: 2.0) { @@ -102,9 +102,9 @@ struct LEDIndicator: View { @Environment(\.colorScheme) var colorScheme @Binding var flash: Int let color: Color - + @State private var brightness: Double = 0.0 - + var body: some View { Circle() .foregroundColor(color.opacity(brightness)) diff --git a/Meshtastic/Views/Messages/ChannelList.swift b/Meshtastic/Views/Messages/ChannelList.swift index 5b3af8f6..16660203 100644 --- a/Meshtastic/Views/Messages/ChannelList.swift +++ b/Meshtastic/Views/Messages/ChannelList.swift @@ -37,14 +37,16 @@ struct ChannelList: View { let dateFormatString = (localeDateFormat ?? "MM/dd/YY") NavigationLink(value: channel) { - let mostRecent = channel.allPrivateMessages.last(where: { $0.channel == channel.index }) + let mostRecent = channel.mostRecentPrivateMessage + let hasMessages = mostRecent != nil + let hasUnreadMessages = hasMessages && (channel.unreadMessages > 0) let lastMessageTime = Date(timeIntervalSince1970: TimeInterval(Int64((mostRecent?.messageTimestamp ?? 0 )))) let lastMessageDay = Calendar.current.dateComponents([.day], from: lastMessageTime).day ?? 0 let currentDay = Calendar.current.dateComponents([.day], from: Date()).day ?? 0 ZStack { Image(systemName: "circle.fill") - .opacity(channel.unreadMessages > 0 ? 1 : 0) + .opacity(hasUnreadMessages ? 1 : 0) .font(.system(size: 10)) .foregroundColor(.accentColor) .brightness(0.2) @@ -70,7 +72,7 @@ struct ChannelList: View { Spacer() - if channel.allPrivateMessages.count > 0 { + if hasMessages { if lastMessageDay == currentDay { Text(lastMessageTime, style: .time ) @@ -95,7 +97,7 @@ struct ChannelList: View { } } - if channel.allPrivateMessages.count > 0 { + if hasMessages { HStack(alignment: .top) { Text("\(mostRecent != nil ? mostRecent!.messagePayload! : " ")") // .font(.system(size: 16)) @@ -112,6 +114,7 @@ struct ChannelList: View { if let node, let myInfo = node.myInfo { List(selection: $channelSelection) { ForEach(channels) { (channel: ChannelEntity) in + let hasMessages = channel.mostRecentPrivateMessage != nil if !restrictedChannels.contains(channel.name?.lowercased() ?? "") { makeChannelRow(myInfo: myInfo, channel: channel) .alignmentGuide(.listRowSeparatorLeading) { @@ -119,7 +122,7 @@ struct ChannelList: View { } .frame(height: 62) .contextMenu { - if channel.allPrivateMessages.count > 0 { + if hasMessages { Button(role: .destructive) { isPresentingDeleteChannelMessagesConfirm = true channelToDeleteMessages = channel diff --git a/Meshtastic/Views/Messages/ChannelMessageList.swift b/Meshtastic/Views/Messages/ChannelMessageList.swift index 857028f1..be3959d2 100644 --- a/Meshtastic/Views/Messages/ChannelMessageList.swift +++ b/Meshtastic/Views/Messages/ChannelMessageList.swift @@ -12,7 +12,7 @@ import SwiftUI struct ChannelMessageList: View { @EnvironmentObject var appState: AppState - @EnvironmentObject var router: Router + @Environment(\.scenePhase) var scenePhase @Environment(\.managedObjectContext) var context @EnvironmentObject var accessoryManager: AccessoryManager @FocusState var messageFieldFocused: Bool @@ -58,14 +58,29 @@ struct ChannelMessageList: View { Logger.data.error("Failed to read messages: \(error.localizedDescription, privacy: .public)") } } - + + private func routerIsShowingThisChannel() -> Bool { + guard appState.router.navigationState.selectedTab == .messages else { return false } + return scenePhase == .active + } + var body: some View { + // Cast allPrivateMessages to an array for easier indexing and ForEach. + let messages: [MessageEntity] = Array(allPrivateMessages) + + // Precompute previous message + let previousByID: [Int64: MessageEntity?] = { + var dict = [Int64: MessageEntity?]() + var prev: MessageEntity? + for m in messages { dict[m.messageId] = prev; prev = m } + return dict + }() + ScrollViewReader { scrollView in ScrollView { LazyVStack { - ForEach(allPrivateMessages.indices, id: \.self) { index in - let message = allPrivateMessages[index] - let previousMessage = index > 0 ? allPrivateMessages[index - 1] : nil + ForEach(messages, id: \.messageId) { message in + let previousMessage: MessageEntity? = previousByID[message.messageId] ?? nil ChannelMessageRow( message: message, @@ -92,7 +107,7 @@ struct ChannelMessageList: View { } } } - .id(redrawTapbacksTrigger) + } Color.clear .frame(height: 1) diff --git a/Meshtastic/Views/Messages/ChannelMessageRow.swift b/Meshtastic/Views/Messages/ChannelMessageRow.swift index 9e3c8124..eb0f2a9f 100644 --- a/Meshtastic/Views/Messages/ChannelMessageRow.swift +++ b/Meshtastic/Views/Messages/ChannelMessageRow.swift @@ -3,7 +3,7 @@ import MeshtasticProtobufs import SwiftUI struct ChannelMessageRow: View { - @EnvironmentObject var router: Router + @EnvironmentObject var appState: AppState // Core Data object observed for changes (like Tapbacks being received) @ObservedObject var message: MessageEntity @@ -98,7 +98,7 @@ struct ChannelMessageRow: View { CircleText(text: message.fromUser?.shortName ?? "?", color: Color(UIColor(hex: UInt32(message.fromUser?.num ?? 0))), circleSize: 50) .onTapGesture(count: 2) { if let nodeNum = message.fromUser?.num { - router.navigateToNodeDetail(nodeNum: Int64(nodeNum)) + appState.router.navigateToNodeDetail(nodeNum: Int64(nodeNum)) } } .padding(.all, 5).offset(y: -7) diff --git a/Meshtastic/Views/Messages/MessageContextMenuItems.swift b/Meshtastic/Views/Messages/MessageContextMenuItems.swift index 33554de7..63104320 100644 --- a/Meshtastic/Views/Messages/MessageContextMenuItems.swift +++ b/Meshtastic/Views/Messages/MessageContextMenuItems.swift @@ -11,6 +11,7 @@ struct MessageContextMenuItems: View { let isCurrentUser: Bool @Binding var isShowingDeleteConfirmation: Bool let onReply: () -> Void + @State var relayDisplay: String? = nil var body: some View { VStack { @@ -19,6 +20,14 @@ struct MessageContextMenuItems: View { } Text("Channel") + Text(": \(message.channel)") } + .onAppear { + DispatchQueue.global(qos: .userInitiated).async { + let result = message.relayDisplay() + DispatchQueue.main.async { + relayDisplay = result + } + } + } Menu("Tapback") { ForEach(Tapbacks.allCases) { tb in @@ -59,12 +68,27 @@ struct MessageContextMenuItems: View { } Menu("Message Details") { + // Precompute values to avoid executing non-View code inside the ViewBuilder + let messageDate = Date(timeIntervalSince1970: TimeInterval(message.messageTimestamp)) + let ackDate = Date(timeIntervalSince1970: TimeInterval(message.ackTimestamp)) + let sixMonthsAgo = Calendar.current.date(byAdding: .month, value: -6, to: Date()) + + // Compute a relay display string if relayNode is present + + VStack { - let messageDate = Date(timeIntervalSince1970: TimeInterval(message.messageTimestamp)) - Text("\(messageDate.formattedDate(format: MessageText.dateFormatString))").foregroundColor(.gray) + Text("\(messageDate.formattedDate(format: MessageText.dateFormatString))") + .foregroundColor(.gray) } - if !isCurrentUser && !(message.fromUser?.userNode?.viaMqtt ?? false) && message.fromUser?.userNode?.hopsAway ?? -1 == 0 { + if let relayDisplay { + let prefix = message.realACK ? "Ack Relay: " : "Relay: " + Text(prefix + relayDisplay) + .foregroundColor(relayDisplay.contains("Node ") ? .gray : .primary) + .font(relayDisplay.contains("Node ") ? .caption : .body) + } + + if !isCurrentUser && !(message.fromUser?.userNode?.viaMqtt ?? false) && message.fromUser?.userNode?.hopsAway ?? -1 == 0 { VStack { Text("SNR \(String(format: "%.2f", message.snr)) dB") Text("RSSI \(String(format: "%.2f", message.rssi)) dBm") @@ -74,29 +98,29 @@ struct MessageContextMenuItems: View { Text("Hops Away \(message.fromUser?.userNode?.hopsAway ?? 0)") } } + if message.relays != 0 && message.realACK == false { + Text("Relayed by \(message.relays) \(message.relays == 1 ? "node" : "nodes")") + } if isCurrentUser && message.receivedACK { VStack { - Text("Received Ack") + Text(": \(message.receivedACK ? "✔️" : "")") - Text("Recipient Ack") + Text(": \(message.realACK ? "✔️" : "")") + Text("Received Ack: \(message.receivedACK ? "✔️" : "")") + Text("Recipient Ack: \(message.realACK ? "✔️" : "")") } } else if isCurrentUser && message.ackError == 0 { - // Empty Error Text("Waiting") } else if isCurrentUser && message.ackError > 0 { let ackErrorVal = RoutingError(rawValue: Int(message.ackError)) Text("\(ackErrorVal?.display ?? "Empty Ack Error")") .fixedSize(horizontal: false, vertical: true) } + if isCurrentUser { - VStack { - let ackDate = Date(timeIntervalSince1970: TimeInterval(message.ackTimestamp)) - let sixMonthsAgo = Calendar.current.date(byAdding: .month, value: -6, to: Date()) - if ackDate >= sixMonthsAgo! { - Text("Ack Time: \(ackDate.formattedDate(format: MessageText.timeFormatString))") - .foregroundColor(.gray) - } + if let sixMonthsAgo, ackDate >= sixMonthsAgo { + Text("Ack Time: \(ackDate.formattedDate(format: MessageText.timeFormatString))") + .foregroundColor(.gray) } } + if message.ackSNR != 0 { VStack { Text("Ack SNR: \(String(format: "%.2f", message.ackSNR)) dB") diff --git a/Meshtastic/Views/Messages/MessageText.swift b/Meshtastic/Views/Messages/MessageText.swift index 19d0c715..28df8fba 100644 --- a/Meshtastic/Views/Messages/MessageText.swift +++ b/Meshtastic/Views/Messages/MessageText.swift @@ -25,9 +25,7 @@ struct MessageText: View { let isCurrentUser: Bool let onReply: () -> Void // State for handling channel URL sheet - @State private var saveChannels = false - @State private var channelSettings: String? - @State private var addChannels = false + @State private var saveChannelLink: SaveChannelLinkData? @State private var isShowingDeleteConfirmation = false var body: some View { @@ -97,7 +95,8 @@ struct MessageText: View { ) } .environment(\.openURL, OpenURLAction { url in - channelSettings = nil + saveChannelLink = nil + var addChannels = false if url.absoluteString.lowercased().contains("meshtastic.org/v/#") { // Handle contact URL ContactURLHandler.handleContactUrl(url: url, accessoryManager: AccessoryManager.shared) @@ -109,35 +108,25 @@ struct MessageText: View { Logger.services.error("No valid components found in channel URL: \(url.absoluteString, privacy: .public)") return .discarded } - self.addChannels = Bool(url.query?.contains("add=true") ?? false) + addChannels = Bool(url.query?.contains("add=true") ?? false) guard let lastComponent = components.last else { Logger.services.error("Channel URL missing fragment component: \(url.absoluteString, privacy: .public)") - self.channelSettings = nil + self.saveChannelLink = nil return .discarded } - self.channelSettings = lastComponent.components(separatedBy: "?").first ?? "" - Logger.services.debug("Add Channel: \(self.addChannels, privacy: .public)") - self.saveChannels = true + let cs = lastComponent.components(separatedBy: "?").first ?? "" + self.saveChannelLink = SaveChannelLinkData(data: cs, add: addChannels) + Logger.services.debug("Add Channel: \(addChannels, privacy: .public)") Logger.mesh.debug("Opening Channel Settings URL: \(url.absoluteString, privacy: .public)") return .handled // Prevent default browser opening } return .systemAction // Open other URLs in browser }) // Display sheet for channel settings - .sheet(isPresented: Binding( - get: { - saveChannels && !(channelSettings == nil) - }, - set: { newValue in - saveChannels = newValue - if !newValue { - channelSettings = nil - } - } - )) { + .sheet(item: $saveChannelLink) { link in SaveChannelQRCode( - channelSetLink: channelSettings ?? "Empty Channel URL", - addChannels: addChannels, + channelSetLink: link.data, + addChannels: link.add, accessoryManager: accessoryManager ) .presentationDetents([.large]) diff --git a/Meshtastic/Views/Messages/UserList.swift b/Meshtastic/Views/Messages/UserList.swift index 2199e997..16ba0b7b 100644 --- a/Meshtastic/Views/Messages/UserList.swift +++ b/Meshtastic/Views/Messages/UserList.swift @@ -11,7 +11,7 @@ import OSLog import TipKit struct UserList: View { - + @Environment(\.managedObjectContext) var context @EnvironmentObject var accessoryManager: AccessoryManager @State private var editingFilters = false @@ -20,7 +20,7 @@ struct UserList: View { @StateObject private var filters: NodeFilterParameters = NodeFilterParameters() @Binding var node: NodeInfoEntity? @Binding var userSelection: UserEntity? - + var body: some View { VStack { FilteredUserList(withFilters: filters, node: $node, userSelection: $userSelection) @@ -92,13 +92,15 @@ fileprivate struct FilteredUserList: View { self._node = node self._userSelection = userSelection } - + var body: some View { let localeDateFormat = DateFormatter.dateFormat(fromTemplate: "yyMMdd", options: 0, locale: Locale.current) let dateFormatString = (localeDateFormat ?? "MM/dd/YY") List(users, selection: $userSelection) { user in - let mostRecent = user.messageList.last + let mostRecent = user.mostRecentMessage + let hasMessages = mostRecent != nil + let hasUnreadMessages = user.unreadMessages > 0 let lastMessageTime = Date(timeIntervalSince1970: TimeInterval(Int64((mostRecent?.messageTimestamp ?? 0 )))) let lastMessageDay = Calendar.current.dateComponents([.day], from: lastMessageTime).day ?? 0 let currentDay = Calendar.current.dateComponents([.day], from: Date()).day ?? 0 @@ -106,14 +108,14 @@ fileprivate struct FilteredUserList: View { NavigationLink(value: user) { ZStack { Image(systemName: "circle.fill") - .opacity(user.unreadMessages > 0 ? 1 : 0) + .opacity(hasUnreadMessages ? 1 : 0) .font(.system(size: 10)) .foregroundColor(.accentColor) .brightness(0.2) } - + CircleText(text: user.shortName ?? "?", color: Color(UIColor(hex: UInt32(user.num)))) - + VStack(alignment: .leading) { HStack { if user.pkiEncrypted { @@ -137,7 +139,7 @@ fileprivate struct FilteredUserList: View { Image(systemName: "star.fill") .foregroundColor(.yellow) } - if user.messageList.count > 0 { + if hasMessages { if lastMessageDay == currentDay { Text(lastMessageTime, style: .time ) .font(.footnote) @@ -157,8 +159,8 @@ fileprivate struct FilteredUserList: View { } } } - - if user.messageList.count > 0 { + + if hasMessages { HStack(alignment: .top) { Text("\(mostRecent != nil ? mostRecent!.messagePayload! : " ")") .font(.footnote) @@ -207,7 +209,7 @@ fileprivate struct FilteredUserList: View { } label: { Label(user.mute ? "Show Alerts" : "Hide Alerts", systemImage: user.mute ? "bell" : "bell.slash") } - if user.messageList.count > 0 { + if hasMessages { Button(role: .destructive) { isPresentingDeleteUserMessagesConfirm = true userToDeleteMessages = user @@ -316,7 +318,7 @@ fileprivate extension NodeFilterParameters { predicates.append(isIgnoredPredicate) let isConnectedNodePredicate = NSPredicate(format: "NOT (numString CONTAINS %@)", String(UserDefaults.preferredPeripheralNum)) predicates.append(isConnectedNodePredicate) - + // Combine all predicates let finalPredicate = predicates.isEmpty ? NSPredicate(value: true) : NSCompoundPredicate(type: .and, subpredicates: predicates) return finalPredicate diff --git a/Meshtastic/Views/Messages/UserMessageList.swift b/Meshtastic/Views/Messages/UserMessageList.swift index 87afb16f..9a3425bc 100644 --- a/Meshtastic/Views/Messages/UserMessageList.swift +++ b/Meshtastic/Views/Messages/UserMessageList.swift @@ -11,9 +11,9 @@ import OSLog import MeshtasticProtobufs // Added to ensure RoutingError is accessible if needed struct UserMessageList: View { - @EnvironmentObject var appState: AppState @EnvironmentObject var accessoryManager: AccessoryManager + @Environment(\.scenePhase) var scenePhase @Environment(\.managedObjectContext) var context @FocusState var messageFieldFocused: Bool @ObservedObject var user: UserEntity @@ -21,17 +21,21 @@ struct UserMessageList: View { @State private var messageToHighlight: Int64 = 0 @State private var redrawTapbacksTrigger = UUID() @AppStorage("preferredPeripheralNum") private var preferredPeripheralNum = -1 - - private var allPrivateMessages: [MessageEntity] { - // Cast user.messageList to an array for easier indexing and ForEach. - return user.messageList.compactMap { $0 as MessageEntity } + @FetchRequest private var allPrivateMessages: FetchedResults + + init(user: UserEntity) { + self.user = user + + // Configure fetch request here + let request: NSFetchRequest = user.messageFetchRequest + _allPrivateMessages = FetchRequest(fetchRequest: request) } - + func handleInteractionComplete() { markMessagesAsRead() redrawTapbacksTrigger = UUID() } - + func markMessagesAsRead() { do { for unreadMessage in allPrivateMessages.filter({ !$0.read }) { @@ -39,25 +43,46 @@ struct UserMessageList: View { } try context.save() Logger.data.info("📖 [App] All unread direct messages marked as read for user \(user.num, privacy: .public).") - appState.unreadDirectMessages = user.unreadMessages + + if let connectedPeripheralNum = accessoryManager.activeDeviceNum, + let connectedNode = getNodeInfo(id: connectedPeripheralNum, context: context), + let connectedUser = connectedNode.user { + appState.unreadDirectMessages = connectedUser.unreadMessages(context: context, skipLastMessageCheck: true) // skipLastMessageCheck=true because we don't update lastMessage on our own connected node + } + context.refresh(user, mergeChanges: true) } catch { Logger.data.error("Failed to read direct messages: \(error.localizedDescription, privacy: .public)") } } - + + private func routerIsShowingThisUser() -> Bool { + guard appState.router.navigationState.selectedTab == .messages else { return false } + return scenePhase == .active + } + var body: some View { + // Cast user.messageList to an array for easier indexing and ForEach. + let messages: [MessageEntity] = Array(allPrivateMessages) + + // Precompute previous message + let previousByID: [Int64: MessageEntity?] = { + var dict = [Int64: MessageEntity?]() + var prev: MessageEntity? + for m in messages { dict[m.messageId] = prev; prev = m } + return dict + }() + VStack { ScrollViewReader { scrollView in ScrollView { LazyVStack { - ForEach(allPrivateMessages.indices, id: \.self) { index in - let message = allPrivateMessages[index] - let previousMessage = index > 0 ? allPrivateMessages[index - 1] : nil + ForEach(messages, id: \.messageId) { message in + let previousMessage: MessageEntity? = previousByID[message.messageId] ?? nil UserMessageRow( message: message, - allMessages: allPrivateMessages, + allMessages: messages, previousMessage: previousMessage, preferredPeripheralNum: preferredPeripheralNum, user: user, @@ -80,7 +105,7 @@ struct UserMessageList: View { } } } - .id(redrawTapbacksTrigger) + } // Invisible spacer to detect reaching bottom Color.clear diff --git a/Meshtastic/Views/Messages/UserMessageRow.swift b/Meshtastic/Views/Messages/UserMessageRow.swift index 00579fb3..d469462b 100644 --- a/Meshtastic/Views/Messages/UserMessageRow.swift +++ b/Meshtastic/Views/Messages/UserMessageRow.swift @@ -11,7 +11,7 @@ import SwiftUI struct UserMessageRow: View { - @EnvironmentObject var router: Router + @EnvironmentObject var appState: AppState @ObservedObject var message: MessageEntity let allMessages: [MessageEntity] let previousMessage: MessageEntity? @@ -105,7 +105,7 @@ struct UserMessageRow: View { CircleText(text: message.fromUser?.shortName ?? "?", color: Color(UIColor(hex: UInt32(message.fromUser?.num ?? 0))), circleSize: 50) .onTapGesture(count: 2) { if let nodeNum = message.fromUser?.num { - router.navigateToNodeDetail(nodeNum: Int64(nodeNum)) + appState.router.navigateToNodeDetail(nodeNum: Int64(nodeNum)) } } .padding(.all, 5).offset(y: -7) diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/ExchangePositionsButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/ExchangePositionsButton.swift index 05747fa9..f303f21e 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/ExchangePositionsButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/ExchangePositionsButton.swift @@ -3,6 +3,7 @@ import SwiftUI struct ExchangePositionsButton: View { var node: NodeInfoEntity + var connectedNode: NodeInfoEntity @EnvironmentObject var accessoryManager: AccessoryManager @@ -10,7 +11,7 @@ struct ExchangePositionsButton: View { @State private var isPresentingPositionFailedAlert: Bool = false var body: some View { - let hopsAway = Int32(truncatingIfNeeded: node.hopsAway > node.loRaConfig?.hopLimit ?? 0 ? node.hopsAway : node.loRaConfig?.hopLimit ?? 0) + let hopsAway = Int32(truncatingIfNeeded: node.hopsAway > connectedNode.loRaConfig?.hopLimit ?? 0 ? node.hopsAway : connectedNode.loRaConfig?.hopLimit ?? 0) Button { Task { do { diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/FavoriteNodeButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/FavoriteNodeButton.swift index 4ca8009b..83bac1d3 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/FavoriteNodeButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/FavoriteNodeButton.swift @@ -8,39 +8,20 @@ struct FavoriteNodeButton: View { @Environment(\.managedObjectContext) var context @ObservedObject var node: NodeInfoEntity + @State var isShowingClientBaseConfirmation = false var body: some View { + let connectedRoleIsClientBase = accessoryManager.connectedDeviceRole == DeviceRoles.clientBase Button { + // Special case for CLIENT_BASE: show confirmation when attempting to favorite a node + if connectedRoleIsClientBase && !node.favorite { + isShowingClientBaseConfirmation = true + return + } + // Normal case: perform action immediately guard let connectedNodeNum = accessoryManager.activeDeviceNum else { return } Task { - do { - if node.favorite { - try await accessoryManager.removeFavoriteNode( - node: node, - connectedNodeNum: Int64(connectedNodeNum) - ) - } else { - try await accessoryManager.setFavoriteNode( - node: node, - connectedNodeNum: Int64(connectedNodeNum) - ) - } - - Task { @MainActor in - // Update CoreData - node.favorite = !node.favorite - - do { - try context.save() - } catch { - context.rollback() - Logger.data.error("Save Node Favorite Error") - } - Logger.data.debug("Favorited a node") - } - } catch { - - } + await assignFavorite(node: node, setToFavorite: !node.favorite, connectedNodeNum: Int64(connectedNodeNum)) } } label: { Label { @@ -50,5 +31,51 @@ struct FavoriteNodeButton: View { .symbolRenderingMode(.multicolor) } } + .confirmationDialog( + "Are you sure?", + isPresented: $isShowingClientBaseConfirmation, + titleVisibility: .visible + ) { + Button("Yes, I control this node") { + guard let connectedNodeNum = accessoryManager.activeDeviceNum else { return } + Task { + await assignFavorite(node: node, setToFavorite: true, connectedNodeNum: Int64(connectedNodeNum)) + } + } + Button("Cancel", role: .cancel) { } + } message: { + Text("Client Base should only favorite other nodes you control. Improper use will hurt your local mesh.") + } + } + + private func assignFavorite (node: NodeInfoEntity, setToFavorite: Bool, connectedNodeNum: Int64) async { + do { + if setToFavorite { + try await accessoryManager.setFavoriteNode( + node: node, + connectedNodeNum: Int64(connectedNodeNum) + ) + } else { + try await accessoryManager.removeFavoriteNode( + node: node, + connectedNodeNum: Int64(connectedNodeNum) + ) + } + + Task { @MainActor in + // Update CoreData + node.favorite = setToFavorite + + do { + try context.save() + } catch { + context.rollback() + Logger.data.error("Save Node Favorite Error") + } + Logger.data.debug("Favorited a node") + } + } catch { + + } } } diff --git a/Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift index 4941dd30..480a5cba 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift @@ -15,6 +15,12 @@ struct IdentifiableOverlay: Identifiable { var id: ObjectIdentifier { ObjectIdentifier(overlay as AnyObject) } } +struct ReducedPrecisionMapCircleKey: Hashable { + let latitudeI: Int32 + let longitudeI: Int32 + let precisionBits: Int32 +} + struct MeshMapContent: MapContent { /// Parameters @@ -43,35 +49,85 @@ struct MeshMapContent: MapContent { @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "name", ascending: true)], predicate: NSPredicate(format: "enabled == true", ""), animation: .none) private var routes: FetchedResults - + @MapContentBuilder var positionAnnotations: some MapContent { ForEach(positions, id: \.id) { position in + /// Apply favorites filter and don't show ignored nodes if (!showFavorites || (position.nodePosition?.favorite == true)) && !(position.nodePosition?.ignored == true) { - - let nodeColor = UIColor(hex: UInt32(position.nodePosition?.num ?? 0)) - let positionName = position.nodePosition?.user?.longName ?? "?" - // Use a hash of the position ID to stagger animation delays for each node, preventing synchronized animations and improving visual distinction. - let calculatedDelay = Double(position.id.hashValue % 100) / 100.0 * 0.5 - - Annotation(positionName, coordinate: position.coordinate) { - LazyVStack { - AnimatedNodePin( - nodeColor: nodeColor, - shortName: position.nodePosition?.user?.shortName, - hasDetectionSensorMetrics: position.nodePosition?.hasDetectionSensorMetrics ?? false, - isOnline: position.nodePosition?.isOnline ?? false, - calculatedDelay: calculatedDelay - ) + let coordinateForNodePin: CLLocationCoordinate2D = if position.isPreciseLocation { + // Precise location: place node pin at actual location. + position.coordinate + } else { + // Imprecise location: fuzz slightly so overlapping nodes are visible and clickable at highest zoom levels. + position.fuzzedCoordinate + } + if 12...15 ~= position.precisionBits || position.precisionBits == 32 { + + let nodeColor = UIColor(hex: UInt32(position.nodePosition?.num ?? 0)) + let positionName = position.nodePosition?.user?.longName ?? "?" + + // Use a hash of the position ID to stagger animation delays for each node, preventing synchronized animations and improving visual distinction. + let calculatedDelay = Double(position.id.hashValue % 100) / 100.0 * 0.5 + + Annotation(positionName, coordinate: coordinateForNodePin) { + LazyVStack { + AnimatedNodePin( + nodeColor: nodeColor, + shortName: position.nodePosition?.user?.shortName, + hasDetectionSensorMetrics: position.nodePosition?.hasDetectionSensorMetrics ?? false, + isOnline: position.nodePosition?.isOnline ?? false, + calculatedDelay: calculatedDelay + ) + } + .highPriorityGesture(TapGesture().onEnded { _ in + selectedPosition = (selectedPosition == position ? nil : position) + }) } - .highPriorityGesture(TapGesture().onEnded { _ in - selectedPosition = (selectedPosition == position ? nil : position) - }) } } } } - + + private var reducedPrecisionCircleItems: [(nodeNum: Int64, circleKey: ReducedPrecisionMapCircleKey)] { + // Precompute *unique* reduced-precision circles so we don't have to redraw tons of identical (center, radius) circles in dense map areas. (Since they're all transparent, this causes severe FPS drop when zoomed into areas where there are a ton of overlapping circles.) + var lowestNumForKey: [ReducedPrecisionMapCircleKey: Int64] = [:] + // Populate a dict where the key is (lat, lon, bits) and the value is the *lowest* node.num seen for that key. + // That lowest node.num value is used to create a stable color for the MapCircle and stable id for ForEach. + for position in positions { + // Same filter criteria as positionAnnotations: + if (!showFavorites || (position.nodePosition?.favorite == true)) && !(position.nodePosition?.ignored == true) { + if 12...15 ~= position.precisionBits { + let nodeNum = position.nodePosition?.num ?? 0 + let key = ReducedPrecisionMapCircleKey(latitudeI: position.latitudeI, longitudeI: position.longitudeI, precisionBits: position.precisionBits) + if let existing = lowestNumForKey[key] { + if nodeNum < existing { lowestNumForKey[key] = nodeNum } + } else { + lowestNumForKey[key] = nodeNum + } + } + } + } + // Sort by nodeNum just to keep draw order stable. + return lowestNumForKey.map { ($0.value, $0.key) }.sorted { $0.nodeNum < $1.nodeNum } + } + + @MapContentBuilder + var reducedPrecisionMapCircles: some MapContent { + ForEach(reducedPrecisionCircleItems, id: \.nodeNum) { item in + let circleKey = item.circleKey + let nodeNum = item.nodeNum + let radius = PositionPrecision(rawValue: Int(circleKey.precisionBits))?.precisionMeters ?? 0 + if radius > 0.0 { + let center = CLLocationCoordinate2D(latitude: Double(circleKey.latitudeI) / 1e7, longitude: Double(circleKey.longitudeI) / 1e7) + let nodeColor = UIColor(hex: UInt32(nodeNum)) + MapCircle(center: center, radius: radius) + .foregroundStyle(Color(nodeColor).opacity(0.25)) + .stroke(.white, lineWidth: 1) + } + } + } + @MapContentBuilder var routeAnnotations: some MapContent { ForEach(routes) { route in @@ -147,6 +203,7 @@ struct MeshMapContent: MapContent { } positionAnnotations + reducedPrecisionMapCircles routeAnnotations waypointAnnotations } diff --git a/Meshtastic/Views/Nodes/Helpers/Map/MapContent/NodeMapContent.swift b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/NodeMapContent.swift index 6059a57c..02635dd8 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/MapContent/NodeMapContent.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/MapContent/NodeMapContent.swift @@ -11,42 +11,32 @@ import CoreData struct NodeMapContent: MapContent { @ObservedObject var node: NodeInfoEntity - @State var showUserLocation: Bool = false - @State var positions: [PositionEntity] = [] /// Map State User Defaults @AppStorage("meshMapShowNodeHistory") private var showNodeHistory = false @AppStorage("meshMapShowRouteLines") private var showRouteLines = false - @AppStorage("enableMapWaypoints") private var showWaypoints = true @AppStorage("enableMapConvexHull") private var showConvexHull = false - @AppStorage("enableMapTraffic") private var showTraffic: Bool = false - @AppStorage("enableMapPointsOfInterest") private var showPointsOfInterest: Bool = false - @AppStorage("mapLayer") private var selectedMapLayer: MapLayer = .hybrid // Map Configuration @Namespace var mapScope - @State var mapStyle: MapStyle = MapStyle.hybrid(elevation: .realistic, pointsOfInterest: .all, showsTraffic: true) - @State var position = MapCameraPosition.automatic - @State var scene: MKLookAroundScene? - @State var isLookingAround = false - @State var isShowingAltitude = false - @State var isEditingSettings = false @State var selectedPosition: PositionEntity? - @State var isMeshMap = false @MapContentBuilder var nodeMap: some MapContent { let positionArray = node.positions?.array as? [PositionEntity] ?? [] - let lineCoords = positionArray.compactMap({(position) -> CLLocationCoordinate2D in - return position.nodeCoordinate ?? LocationsHandler.DefaultLocation - }) /// Node Color from node.num let nodeColor = UIColor(hex: UInt32(node.num)) + let nodeColorSwift = Color(nodeColor) + let nodeBorderColor: Color = nodeColorSwift.isLight() ? .black : .white + + // Prerender node history point views as UIImages for speedup when there are thousands of history points + let prerenderedHistoryPointCircleImage = showNodeHistory ? prerenderHistoryPointCircle(fill: nodeColorSwift, stroke: nodeBorderColor) : UIImage() + let prerenderedHistoryPointArrowImage = showNodeHistory ? prerenderHistoryPointArrow(fill: nodeColorSwift, stroke: nodeBorderColor) : UIImage() + + let pf = PositionFlags(rawValue: Int(node.metadata?.positionFlags ?? 771)) /// Node Annotations - ForEach(node.positions?.array as? [PositionEntity] ?? [], id: \.id) { position in - - let pf = PositionFlags(rawValue: Int(position.nodePosition?.metadata?.positionFlags ?? 771)) + ForEach(positionArray, id: \.id) { position in let headingDegrees = Angle.degrees(Double(position.heading)) /// Reduced Precision Map Circle if position.latest && 12...15 ~= position.precisionBits { @@ -58,32 +48,6 @@ struct NodeMapContent: MapContent { .stroke(.white, lineWidth: 2) } } - let loraNodes = positions.filter { $0.nodePosition?.viaMqtt ?? true == false } - let loraCoords = Array(loraNodes).compactMap({(position) -> CLLocationCoordinate2D in - return position.nodeCoordinate ?? LocationsHandler.DefaultLocation - }) - /// Convex Hull - if showConvexHull { - if loraCoords.count > 0 { - let hull = loraCoords.getConvexHull() - MapPolygon(coordinates: hull) - .stroke(.blue, lineWidth: 3) - .foregroundStyle(.indigo.opacity(0.4)) - } - } - /// Route Lines - if showRouteLines { - let gradient = LinearGradient( - colors: [Color(nodeColor.lighter().lighter().lighter()), Color(nodeColor.lighter()), Color(nodeColor)], - startPoint: .leading, endPoint: .trailing - ) - let dashed = StrokeStyle( - lineWidth: 3, - lineCap: .round, lineJoin: .round, dash: [10, 10] - ) - MapPolyline(coordinates: lineCoords) - .stroke(gradient, style: dashed) - } /// Lastest Position Pin if position.latest { /// Node Annotations @@ -93,7 +57,7 @@ struct NodeMapContent: MapContent { if pf.contains(.Heading) { Image(systemName: pf.contains(.Speed) && position.speed > 1 ? "location.north" : "octagon") .padding(5) - .foregroundStyle(Color(nodeColor).isLight() ? .black : .white) + .foregroundStyle(nodeBorderColor) .background(Color(nodeColor.darker())) .clipShape(Circle()) .rotationEffect(headingDegrees) @@ -111,7 +75,7 @@ struct NodeMapContent: MapContent { Image(systemName: "flipphone") .symbolEffect(.pulse.byLayer) .padding(5) - .foregroundStyle(Color(nodeColor).isLight() ? .black : .white) + .foregroundStyle(nodeBorderColor) .background(Color(UIColor(hex: UInt32(node.num)).darker())) .clipShape(Circle()) .onTapGesture { @@ -133,27 +97,25 @@ struct NodeMapContent: MapContent { } /// Node History if showNodeHistory { - if position.latest == false && position.nodePosition?.favorite ?? false { - let pf = PositionFlags(rawValue: Int(position.nodePosition?.metadata?.positionFlags ?? 771)) + // Having showNodeHistory enabled can be quite slow if there are thousands of history points. + if position.latest == false && node.favorite { let headingDegrees = Angle.degrees(Double(position.heading)) Annotation("", coordinate: position.coordinate) { - LazyVStack { - if pf.contains(.Heading) { - Image(systemName: "location.north.circle") - .resizable() - .scaledToFit() - .foregroundStyle(Color(UIColor(hex: UInt32(position.nodePosition?.num ?? 0))).isLight() ? .black : .white) - .background(Color(UIColor(hex: UInt32(position.nodePosition?.num ?? 0)))) - .clipShape(Circle()) - .rotationEffect(headingDegrees) - .frame(width: 16, height: 16) - - } else { - Circle() - .fill(Color(UIColor(hex: UInt32(position.nodePosition?.num ?? 0)))) - .strokeBorder(Color(UIColor(hex: UInt32(position.nodePosition?.num ?? 0))).isLight() ? .black : .white, lineWidth: 2) - .frame(width: 12, height: 12) - } + if pf.contains(.Heading) { + Image(uiImage: prerenderedHistoryPointArrowImage) + .renderingMode(.original) + .interpolation(.none) + .rotationEffect(headingDegrees) + .frame(width: 16, height: 16) + .allowsHitTesting(false) + .accessibilityHidden(true) + } else { + Image(uiImage: prerenderedHistoryPointCircleImage) + .renderingMode(.original) + .interpolation(.none) + .frame(width: 12, height: 12) + .allowsHitTesting(false) + .accessibilityHidden(true) } } .annotationTitles(.hidden) @@ -161,6 +123,33 @@ struct NodeMapContent: MapContent { } } } + + // Shared coordinate list for Route Lines and Convex Hull + let allCoords: [CLLocationCoordinate2D] = (showRouteLines || showConvexHull) ? positionArray.compactMap(\.nodeCoordinate) : [] + + /// Route Lines + if showRouteLines { + let gradient = LinearGradient( + colors: [Color(nodeColor.lighter().lighter().lighter()), Color(nodeColor.lighter()), Color(nodeColor)], + startPoint: .leading, endPoint: .trailing + ) + let dashed = StrokeStyle( + lineWidth: 3, + lineCap: .round, lineJoin: .round, dash: [10, 10] + ) + MapPolyline(coordinates: allCoords) + .stroke(gradient, style: dashed) + } + + /// Convex Hull + if showConvexHull { + if allCoords.count > 0 { + let hull = allCoords.getConvexHull() + MapPolygon(coordinates: hull) + .stroke(.blue, lineWidth: 3) + .foregroundStyle(.indigo.opacity(0.4)) + } + } } @MapContentBuilder @@ -169,4 +158,29 @@ struct NodeMapContent: MapContent { nodeMap } } + + private func prerenderHistoryPointCircle(fill: Color, stroke: Color) -> UIImage { + // Render to UIImage once so we don't have to do a ton of vector operations and layers when there are thousands of history points. + let content = Circle() + .fill(fill) + .strokeBorder(stroke, lineWidth: 2) + .frame(width: 12, height: 12) + let renderer = ImageRenderer(content: content) + renderer.scale = UIScreen.main.scale + return renderer.uiImage! + } + + private func prerenderHistoryPointArrow(fill: Color, stroke: Color) -> UIImage { + // Render to UIImage once so we don't have to do a ton of vector operations and layers when there are thousands of history points. + let content = Image(systemName: "location.north.circle") + .resizable() + .scaledToFit() + .foregroundStyle(stroke) + .background(fill) + .clipShape(Circle()) + .frame(width: 16, height: 16) + let renderer = ImageRenderer(content: content) + renderer.scale = UIScreen.main.scale + return renderer.uiImage! + } } diff --git a/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift b/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift index 304c5e69..ca17c6fa 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift @@ -84,15 +84,12 @@ struct MapSettingsForm: View { Label("Node History", systemImage: "building.columns.fill") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) - .onTapGesture { - self.nodeHistory.toggle() - UserDefaults.enableMapNodeHistoryPins = self.nodeHistory + Toggle(isOn: $enableMapRouteLines) { + Label("Route Lines", systemImage: "road.lanes") } + .tint(.accentColor) + } - Toggle(isOn: $enableMapRouteLines) { - Label("Route Lines", systemImage: "road.lanes") - } - .tint(.accentColor) Toggle(isOn: $convexHull) { Label("Convex Hull", systemImage: "button.angledbottom.horizontal.right") } diff --git a/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift b/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift index 67707590..5181586c 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift @@ -9,6 +9,26 @@ import SwiftUI import CoreLocation import MapKit +struct NodeMapContentSignature: Equatable { + // Used to decide if NodeMapContent needs to be reevaluated. + // Only include fields that are used within NodeMapContent (or approximations like positionCount and lastPositionTime). + let nodeNum: Int64 + let positionCount: Int + let lastPositionTime: Date? + let showNodeHistory: Bool + let showRouteLines: Bool + let showConvexHull: Bool + let favorite: Bool +} + +private struct NodeMapContentEquatableWrapper: View, Equatable { + // Prevent slow, needless recomputation of NodeMapContent if the NodeMapContentSignature hasn't changed. + let signature: NodeMapContentSignature + @ViewBuilder let content: () -> Content + static func == (lhs: NodeMapContentEquatableWrapper, rhs: NodeMapContentEquatableWrapper) -> Bool { lhs.signature == rhs.signature } + var body: some View { content() } +} + struct NodeMapSwiftUI: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var accessoryManager: AccessoryManager @@ -17,6 +37,9 @@ struct NodeMapSwiftUI: View { @State var showUserLocation: Bool = false @State var positions: [PositionEntity] = [] /// Map State User Defaults + @AppStorage("meshMapShowNodeHistory") private var showNodeHistory = false + @AppStorage("meshMapShowRouteLines") private var showRouteLines = false + @AppStorage("enableMapConvexHull") private var showConvexHull = false @AppStorage("enableMapTraffic") private var showTraffic: Bool = false @AppStorage("enableMapPointsOfInterest") private var showPointsOfInterest: Bool = false @AppStorage("mapLayer") private var selectedMapLayer: MapLayer = .hybrid @@ -91,9 +114,17 @@ struct NodeMapSwiftUI: View { } } + private var mapContentSignature: NodeMapContentSignature { + let positionCount = node.positions?.count ?? 0 + let lastPositionTime = (node.positions?.lastObject as? PositionEntity)?.time + return NodeMapContentSignature(nodeNum: node.num, positionCount: positionCount, lastPositionTime: lastPositionTime, showNodeHistory: showNodeHistory, showRouteLines: showRouteLines, showConvexHull: showConvexHull, favorite: node.favorite) + } + private var baseMap: some View { - Map(position: $position, bounds: MapCameraBounds(minimumDistance: 0, maximumDistance: .infinity), scope: mapScope) { - NodeMapContent(node: node) + NodeMapContentEquatableWrapper(signature: mapContentSignature) { + Map(position: $position, bounds: MapCameraBounds(minimumDistance: 0, maximumDistance: .infinity), scope: mapScope) { + NodeMapContent(node: node) + } } .mapScope(mapScope) .mapStyle(mapStyle) @@ -110,6 +141,7 @@ struct NodeMapSwiftUI: View { .mapControlVisibility(.visible) } .controlSize(.regular) + .transaction { $0.animation = nil } } private var lookAroundView: some View { diff --git a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift index e9d11aa4..8ab7b29f 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift @@ -12,13 +12,16 @@ struct PositionPopover: View { @ObservedObject var locationsHandler = LocationsHandler.shared @Environment(\.managedObjectContext) var context - @EnvironmentObject var router: Router + @EnvironmentObject var appState: AppState private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom } @Environment(\.dismiss) private var dismiss @Environment(\.openURL) var openURL var position: PositionEntity var popover: Bool = true let distanceFormatter = MKDistanceFormatter() + + @State private var detentSelection: PresentationDetent = .fraction(0.65) + @State private var navigateToCompass = false var body: some View { // Node Color from node.num @@ -29,7 +32,7 @@ struct PositionPopover: View { ZStack { Button { if let nodeNum = position.nodePosition?.num { - router.navigateToNodeDetail(nodeNum: Int64(nodeNum)) + appState.router.navigateToNodeDetail(nodeNum: Int64(nodeNum)) dismiss() } } label: { @@ -42,6 +45,19 @@ struct PositionPopover: View { Divider() HStack(alignment: .center) { VStack(alignment: .leading) { + Button { + detentSelection = .large + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + navigateToCompass = true + } + } label: { + HStack { + Image(systemName: "safari") + Text("Open Compass") + } + } + .padding(.bottom, 5) + /// Time Label { if idiom != .phone { @@ -131,6 +147,7 @@ struct PositionPopover: View { } .padding(.bottom, 5) } + /// Heading let degrees = Angle.degrees(Double(position.heading)) Label { @@ -234,10 +251,17 @@ struct PositionPopover: View { #endif } } + .presentationDetents([.fraction(0.65), .large], selection: $detentSelection) + .presentationContentInteraction(.scrolls) + .presentationDragIndicator(.visible) + .presentationBackgroundInteraction(.enabled(upThrough: .large)) + .navigationDestination(isPresented: $navigateToCompass) { + CompassView( + waypointLocation: position.coordinate, + waypointName: position.nodePosition?.user?.longName ?? "Unknown node", + color: (position.nodePosition?.user?.num != nil && position.nodePosition?.user?.num != 0) ? Color(UIColor(hex: UInt32(position.nodePosition!.user!.num))) : .orange + ) + } } - .presentationDetents([.fraction(0.65), .large]) - .presentationContentInteraction(.scrolls) - .presentationDragIndicator(.visible) - .presentationBackgroundInteraction(.enabled(upThrough: .large)) } } diff --git a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift index 7ad12716..dc394f35 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift @@ -27,6 +27,7 @@ struct NodeDetail: View { var connectedNode: NodeInfoEntity? @ObservedObject var node: NodeInfoEntity @State private var environmentSectionHeight: CGFloat = 0 + @State var showingCompassSheet = false var body: some View { NavigationStack { @@ -40,7 +41,7 @@ struct NodeDetail: View { context: context ) Section("Hardware") { - + NodeInfoItem(node: node) // .id("topOfList") } @@ -260,18 +261,18 @@ struct NodeDetail: View { // Update the state with the new height self.environmentSectionHeight = newHeight } - } else { + } else if let metrics = node.latestEnvironmentMetrics { // 👈 REFACTORED: Unwraps metrics safely VStack { - if node.latestEnvironmentMetrics?.iaq ?? -1 > 0 { - IndoorAirQuality(iaq: Int(node.latestEnvironmentMetrics?.iaq ?? 0), displayMode: .gradient) + if metrics.iaq ?? -1 > 0 { // Use unwrapped 'metrics' + IndoorAirQuality(iaq: Int(metrics.iaq ?? 0), displayMode: .gradient) .padding(.vertical) } LazyVGrid(columns: gridItemLayout) { - if let temperature = node.latestEnvironmentMetrics?.temperature?.shortFormattedTemperature() { + if let temperature = metrics.temperature?.shortFormattedTemperature() { WeatherConditionsCompactWidget(temperature: String(temperature), symbolName: "cloud.sun", description: "TEMP") } - if let humidity = node.latestEnvironmentMetrics?.relativeHumidity { - if let temperature = node.latestEnvironmentMetrics?.temperature { + if let humidity = metrics.relativeHumidity { + if let temperature = metrics.temperature { let dewPoint = calculateDewPoint(temp: temperature, relativeHumidity: humidity) .formatted(.number.precision(.fractionLength(0))) + "°" HumidityCompactWidget(humidity: Int(humidity), dewPoint: dewPoint) @@ -279,17 +280,17 @@ struct NodeDetail: View { HumidityCompactWidget(humidity: Int(humidity), dewPoint: nil) } } - if let pressure = node.latestEnvironmentMetrics?.barometricPressure { + if let pressure = metrics.barometricPressure { PressureCompactWidget(pressure: pressure.formatted(.number.precision(.fractionLength(2))), unit: "hPA", low: pressure <= 1009.144) } - if let windSpeed = node.latestEnvironmentMetrics?.windSpeed { + if let windSpeed = metrics.windSpeed { let windSpeedMeasurement = Measurement(value: Double(windSpeed), unit: UnitSpeed.metersPerSecond) - let windGust = node.latestEnvironmentMetrics?.windGust.map { Measurement(value: Double($0), unit: UnitSpeed.metersPerSecond) } - let direction = cardinalValue(from: Double(node.latestEnvironmentMetrics?.windDirection ?? 0)) + let windGust = metrics.windGust.map { Measurement(value: Double($0), unit: UnitSpeed.metersPerSecond) } + let direction = cardinalValue(from: Double(metrics.windDirection ?? 0)) // Use unwrapped 'metrics' WindCompactWidget(speed: windSpeedMeasurement.formatted(.measurement(width: .abbreviated, numberFormatStyle: .number.precision(.fractionLength(0)))), - gust: node.latestEnvironmentMetrics?.windGust ?? 0.0 > 0.0 ? windGust?.formatted(.measurement(width: .abbreviated, numberFormatStyle: .number.precision(.fractionLength(0)))) : "", direction: direction) + gust: metrics.windGust ?? 0.0 > 0.0 ? windGust?.formatted(.measurement(width: .abbreviated, numberFormatStyle: .number.precision(.fractionLength(0)))) : "", direction: direction) } - if let rainfall1h = node.latestEnvironmentMetrics?.rainfall1H { + if let rainfall1h = metrics.rainfall1H { let locale = NSLocale.current as NSLocale let usesMetricSystem = locale.usesMetricSystem // Returns true for metric (mm), false for imperial (inches) let unit = usesMetricSystem ? UnitLength.millimeters : UnitLength.inches @@ -299,7 +300,7 @@ struct NodeDetail: View { let formattedRain = measurement.converted(to: unit).value.formatted(.number.precision(.fractionLength(decimals))) RainfallCompactWidget(timespan: .rainfall1H, rainfall: formattedRain, unit: unitLabel) } - if let rainfall24h = node.latestEnvironmentMetrics?.rainfall24H { + if let rainfall24h = metrics.rainfall24H { let locale = NSLocale.current as NSLocale let usesMetricSystem = locale.usesMetricSystem // Returns true for metric (mm), false for imperial (inches) let unit = usesMetricSystem ? UnitLength.millimeters : UnitLength.inches @@ -309,26 +310,26 @@ struct NodeDetail: View { let formattedRain = measurement.converted(to: unit).value.formatted(.number.precision(.fractionLength(decimals))) RainfallCompactWidget(timespan: .rainfall24H, rainfall: formattedRain, unit: unitLabel) } - if let radiation = node.latestEnvironmentMetrics?.radiation { + if let radiation = metrics.radiation { RadiationCompactWidget(radiation: radiation.formatted(.number.precision(.fractionLength(1))), unit: "µR/hr") } - if let weight = node.latestEnvironmentMetrics?.weight { + if let weight = metrics.weight { WeightCompactWidget(weight: weight.formatted(.number.precision(.fractionLength(1))), unit: "kg") } - if let distance = node.latestEnvironmentMetrics?.distance { + if let distance = metrics.distance { DistanceCompactWidget(distance: distance.formatted(.number.precision(.fractionLength(0))), unit: "mm") } - if let soilTemperature = node.latestEnvironmentMetrics?.soilTemperature { + if let soilTemperature = metrics.soilTemperature { let locale = NSLocale.current as NSLocale let localeUnit = locale.object(forKey: NSLocale.Key(rawValue: "kCFLocaleTemperatureUnitKey")) let unit = localeUnit as? String ?? "Celsius" == "Fahrenheit" ? "°F" : "°C" SoilTemperatureCompactWidget(temperature: soilTemperature.localeTemperature().formatted(.number.precision(.fractionLength(0))), unit: unit) } - if let soilMoisture = node.latestEnvironmentMetrics?.soilMoisture { + if let soilMoisture = metrics.soilMoisture { SoilMoistureCompactWidget(moisture: soilMoisture.formatted(.number.precision(.fractionLength(0))), unit: "%") } } - .padding(node.latestEnvironmentMetrics?.iaq ?? -1 > 0 ? .bottom : .vertical) + .padding(metrics.iaq ?? -1 > 0 ? .bottom : .vertical) } } } @@ -460,7 +461,8 @@ struct NodeDetail: View { } } ExchangePositionsButton( - node: node + node: node, + connectedNode: connectedNode ) TraceRouteButton( node: node @@ -472,6 +474,17 @@ struct NodeDetail: View { ) } if node.hasPositions { + #if !targetEnvironment(macCatalyst) + Button { + showingCompassSheet = true + } label: { + Label { + Text("Open Compass") + } icon: { + Image(systemName: "safari") + } + } + #endif NavigateToButton(node: node) } IgnoreNodeButton( @@ -558,6 +571,9 @@ struct NodeDetail: View { } } } + .sheet(isPresented: $showingCompassSheet) { + CompassView(waypointLocation: node.latestPosition?.nodeCoordinate ?? nil, waypointName: node.user?.longName ?? nil, color: Color(UIColor(hex: UInt32(node.num)))) + } .onAppear { scrollView.scrollTo("topOfList", anchor: .top) } diff --git a/Meshtastic/Views/Nodes/Helpers/ShareContactQRDialog.swift b/Meshtastic/Views/Nodes/Helpers/ShareContactQRDialog.swift index 4bc56e24..cf30b441 100644 --- a/Meshtastic/Views/Nodes/Helpers/ShareContactQRDialog.swift +++ b/Meshtastic/Views/Nodes/Helpers/ShareContactQRDialog.swift @@ -13,12 +13,14 @@ import MeshtasticProtobufs import OSLog struct ShareContactQRDialog: View { + let manuallyVerified = false let node: NodeInfo @Environment(\.dismiss) private var dismiss var qrString: String { var contact = SharedContact() contact.nodeNum = node.num contact.user = node.user + contact.manuallyVerified = manuallyVerified do { let contactString = try contact.serializedData().base64EncodedString() return ("https://meshtastic.org/v/#" + contactString.base64ToBase64url()) diff --git a/Meshtastic/Views/Nodes/MeshMap.swift b/Meshtastic/Views/Nodes/MeshMap.swift index 9d8911ab..d72987da 100644 --- a/Meshtastic/Views/Nodes/MeshMap.swift +++ b/Meshtastic/Views/Nodes/MeshMap.swift @@ -75,7 +75,8 @@ struct MeshMap: View { } .controlSize(.regular) .offset(y: 100) - .onMapCameraChange(frequency: MapCameraUpdateFrequency.continuous, { context in + .onMapCameraChange(frequency: MapCameraUpdateFrequency.onEnd, { context in + // distance is only used for long-press waypoint creation, so we don't need continuous updates which touch @State and force rerenders as we pan and (for distance in particular) zoom around the map. onEnd is more than enough. distance = context.camera.distance }) .onTapGesture(count: 1, perform: { position in diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 34393253..f324ed8b 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -24,14 +24,14 @@ struct NodeList: View { @StateObject var filters = NodeFilterParameters() @State var isEditingFilters = false @SceneStorage("selectedDetailView") var selectedDetailView: String? - + var connectedNode: NodeInfoEntity? { if let num = accessoryManager.activeDeviceNum { return getNodeInfo(id: num, context: context) } return nil } - + var body: some View { NavigationSplitView { FilteredNodeList( @@ -137,7 +137,7 @@ struct NodeList: View { } } } - + // Helper to get the count of nodes for the navigation title private func getNodeCount() -> Int { let request: NSFetchRequest = NodeInfoEntity.fetchRequest() @@ -154,7 +154,7 @@ fileprivate struct FilteredNodeList: View { @EnvironmentObject var accessoryManager: AccessoryManager @FetchRequest private var nodes: FetchedResults @Environment(\.managedObjectContext) var context - + @Binding var selectedNode: NodeInfoEntity? var connectedNode: NodeInfoEntity? @Binding var isPresentingDeleteNodeAlert: Bool @@ -179,17 +179,19 @@ fileprivate struct FilteredNodeList: View { ] request.predicate = withFilters.buildPredicate() self._nodes = FetchRequest(fetchRequest: request) - + self._selectedNode = selectedNode self.connectedNode = connectedNode self._isPresentingDeleteNodeAlert = isPresentingDeleteNodeAlert self._deleteNodeId = deleteNodeId self._shareContactNode = shareContactNode } - + // The body of the view var body: some View { - List(nodes, id: \.self, selection: $selectedNode) { node in + // If the connected node passes filters, always show it first + let nodesWithConnectedFirst = nodes.filter { $0.num == accessoryManager.activeDeviceNum } + nodes.filter { $0.num != accessoryManager.activeDeviceNum } + List(nodesWithConnectedFirst, id: \.self, selection: $selectedNode) { node in NavigationLink(value: node) { NodeListItem( node: node, @@ -205,7 +207,7 @@ fileprivate struct FilteredNodeList: View { } } } - + @ViewBuilder func contextMenuActions( node: NodeInfoEntity, @@ -276,7 +278,7 @@ fileprivate struct FilteredNodeList: View { fileprivate extension NodeFilterParameters { func buildPredicate() -> NSPredicate? { var predicates: [NSPredicate] = [] - + // Search text predicates if !searchText.isEmpty { let searchKeys = [ @@ -288,19 +290,19 @@ fileprivate extension NodeFilterParameters { } predicates.append(NSCompoundPredicate(orPredicateWithSubpredicates: textPredicates)) } - + // Favorite filter if isFavorite { predicates.append(NSPredicate(format: "favorite == YES")) } - + // Via Lora/MQTT filters if viaLora && !viaMqtt { predicates.append(NSPredicate(format: "viaMqtt == NO")) } else if !viaLora && viaMqtt { predicates.append(NSPredicate(format: "viaMqtt == YES")) } - + // Role filter if roleFilter && !deviceRoles.isEmpty { let rolesPredicates = deviceRoles.map { @@ -308,41 +310,41 @@ fileprivate extension NodeFilterParameters { } predicates.append(NSCompoundPredicate(type: .or, subpredicates: rolesPredicates)) } - + // Hops Away filter if hopsAway == 0.0 { predicates.append(NSPredicate(format: "hopsAway == %i", 0)) } else if hopsAway > 0.0 { predicates.append(NSPredicate(format: "hopsAway > 0 AND hopsAway <= %i", Int32(hopsAway))) } - + // Online filter if isOnline { let isOnlinePredicate = NSPredicate(format: "lastHeard >= %@", Calendar.current.date(byAdding: .minute, value: -120, to: Date())! as NSDate) predicates.append(isOnlinePredicate) } - + // Encrypted filter if isPkiEncrypted { predicates.append(NSPredicate(format: "user.pkiEncrypted == YES")) } - + // Ignored filter if isIgnored { predicates.append(NSPredicate(format: "ignored == YES")) } else { predicates.append(NSPredicate(format: "ignored == NO")) } - + // Environment filter if isEnvironment { predicates.append(NSPredicate(format: "SUBQUERY(telemetries, $tel, $tel.metricsType == 1).@count > 0")) } - + // Distance filter if distanceFilter { if let pointOfInterest = LocationsHandler.currentLocation { - + if pointOfInterest.latitude != LocationsHandler.DefaultLocation.latitude && pointOfInterest.longitude != LocationsHandler.DefaultLocation.longitude { let d: Double = maxDistance * 1.1 let r: Double = 6371009 diff --git a/Meshtastic/Views/Onboarding/DeviceOnboarding.swift b/Meshtastic/Views/Onboarding/DeviceOnboarding.swift index 6f7c87a3..d95d6977 100644 --- a/Meshtastic/Views/Onboarding/DeviceOnboarding.swift +++ b/Meshtastic/Views/Onboarding/DeviceOnboarding.swift @@ -59,7 +59,7 @@ struct DeviceOnboarding: View { makeRow( icon: "person.2.shield", title: String(localized: "User Privacy"), - subtitle: String(localized: "Meshtastic does not collect any personal information. We do anonymously collect usage and crash data to improve the app. This helps us understand how the app is being used and where we can make improvements. The data we collect is non-personally identifiable and cannot be linked to you as an individual. You can opt out of this under app settings.") + subtitle: String(localized: "Meshtastic does not collect any personal information. We do anonymously collect usage and crash data to improve the app. You can opt out under app settings.") ) } .padding() diff --git a/Meshtastic/Views/Settings/AppSettings.swift b/Meshtastic/Views/Settings/AppSettings.swift index 4e1ab892..2f10c2af 100644 --- a/Meshtastic/Views/Settings/AppSettings.swift +++ b/Meshtastic/Views/Settings/AppSettings.swift @@ -56,6 +56,9 @@ struct AppSettings: View { } .tint(.accentColor) } +#if targetEnvironment(macCatalyst) + // App Icon Picker is disabled on macOS Catalyst +#else Button { isPresentingAppIconSheet.toggle() } label: { @@ -65,6 +68,7 @@ struct AppSettings: View { AppIconPicker(isPresenting: self.$isPresentingAppIconSheet) .presentationDetents([.medium]) } +#endif } Section(header: Text("environment")) { VStack(alignment: .leading) { diff --git a/Meshtastic/Views/Settings/Channels.swift b/Meshtastic/Views/Settings/Channels.swift index 29f76966..f5c89071 100644 --- a/Meshtastic/Views/Settings/Channels.swift +++ b/Meshtastic/Views/Settings/Channels.swift @@ -217,13 +217,13 @@ struct Channels: View { } Task { _ = try await accessoryManager.saveChannel(channel: channel, fromUser: node!.user!, toUser: node!.user!) - Task { @MainActor in selectedChannel = nil channelName = "" channelRole = 2 hasChanges = false } + accessoryManager.mqttManager.connectFromConfigSettings(node: node!) } } label: { Label("Save", systemImage: "square.and.arrow.down") diff --git a/Meshtastic/Views/Settings/Config/DeviceConfig.swift b/Meshtastic/Views/Settings/Config/DeviceConfig.swift index 80fe3dba..a03c8a22 100644 --- a/Meshtastic/Views/Settings/Config/DeviceConfig.swift +++ b/Meshtastic/Views/Settings/Config/DeviceConfig.swift @@ -29,8 +29,9 @@ struct DeviceConfig: View { @State var ledHeartbeatEnabled = true @State var tripleClickAsAdHocPing = true @State var tzdef = "" - @State private var showRouterWarning = false - + @State private var showSpecialRoleWarning = false + @State private var showSpecialRoleWarningForRole: Int = 0 + var body: some View { Form { ConfigHeader(title: "Device", config: \.deviceConfig, node: node, onAppear: setDeviceValues) @@ -43,13 +44,14 @@ struct DeviceConfig: View { } } .onChange(of: deviceRole) { _, newRole in - if hasChanges && [DeviceRoles.router.rawValue, DeviceRoles.routerLate.rawValue].contains(newRole) { - showRouterWarning = true + if hasChanges && [DeviceRoles.router.rawValue, DeviceRoles.routerLate.rawValue, DeviceRoles.clientBase.rawValue].contains(newRole) { + showSpecialRoleWarningForRole = newRole + showSpecialRoleWarning = true } } .confirmationDialog( "Are you sure?", - isPresented: $showRouterWarning, + isPresented: $showSpecialRoleWarning, titleVisibility: .visible ) { @@ -60,7 +62,7 @@ struct DeviceConfig: View { setDeviceValues() } } message: { - Text("The Router roles are only for high vantage locations like mountaintops and towers with few nearby nodes, not for use in urban areas. Improper use will hurt your local mesh.") + Text(specialRoleWarningMessage(newRole: showSpecialRoleWarningForRole)) } Text(DeviceRoles(rawValue: deviceRole)?.description ?? "") .foregroundColor(.gray) @@ -332,4 +334,14 @@ struct DeviceConfig: View { self.tzdef = node?.deviceConfig?.tzdef ?? "" hasChanges = false } + + private func specialRoleWarningMessage(newRole: Int) -> String { + if [DeviceRoles.router.rawValue, DeviceRoles.routerLate.rawValue].contains(newRole) { + return "The Router roles are only for high vantage locations like mountaintops and towers with few nearby nodes, not for use in urban areas. Improper use will hurt your local mesh." + } else if newRole == DeviceRoles.clientBase.rawValue { + return "Switching to Client Base will clear this node's favorites. Client Base should only favorite other nodes you control. Improper use will hurt your local mesh." + } else { + return "" + } + } } diff --git a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift index 985bd878..5336c5ef 100644 --- a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift @@ -263,6 +263,7 @@ struct MQTTConfig: View { mqtt.jsonEnabled = self.jsonEnabled mqtt.tlsEnabled = self.tlsEnabled mqtt.mapReportingEnabled = self.mapReportingEnabled + mqtt.mapReportSettings.shouldReportLocation = UserDefaults.mapReportingOptIn mqtt.mapReportSettings.positionPrecision = UInt32(self.mapPositionPrecision) mqtt.mapReportSettings.publishIntervalSecs = UInt32(self.mapPublishIntervalSecs.intValue) Task { diff --git a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift index 83958ff7..ed65ce4e 100644 --- a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift @@ -5,6 +5,7 @@ // Copyright (c) Garth Vander Houwen 6/13/22. // import MeshtasticProtobufs +import CoreData import OSLog import SwiftUI @@ -21,6 +22,19 @@ struct RangeTestConfig: View { @State var enabled = false @State var save = false @State private var sender: UpdateInterval = UpdateInterval(from: 0) + private var isPrimaryChannelPublic: Bool { + guard let channels = node?.myInfo?.channels?.array as? [ChannelEntity] else { + return false + } + // Treat the primary channel on this node as "public" when it is effectively unencrypted + // or using a minimal 1-byte key (hexDescription shorter than 3 characters). + guard let primary = channels.first(where: { $0.index == 0 && $0.role > 0 }) else { + return false + } + let hexLen = primary.psk?.hexDescription.count ?? 0 + return hexLen < 3 + } + var body: some View { Form { @@ -51,14 +65,15 @@ struct RangeTestConfig: View { } } - .disabled(!accessoryManager.isConnected || node?.rangeTestConfig == nil) + .disabled(!accessoryManager.isConnected || node?.rangeTestConfig == nil || isPrimaryChannelPublic) .safeAreaInset(edge: .bottom, alignment: .center) { HStack(spacing: 0) { SaveConfigButton(node: node, hasChanges: $hasChanges) { let connectedNode = getNodeInfo(id: accessoryManager.activeDeviceNum ?? -1, context: context) if connectedNode != nil { var rtc = ModuleConfig.RangeTestConfig() - rtc.enabled = enabled + let effectiveEnabled = isPrimaryChannelPublic ? false : enabled + rtc.enabled = effectiveEnabled rtc.save = save rtc.sender = UInt32(sender.intValue) Task { @@ -110,6 +125,8 @@ struct RangeTestConfig: View { } .onChange(of: enabled) { _, newEnabled in if newEnabled != node?.rangeTestConfig?.enabled { hasChanges = true } + + // Note: even if this is the connected node, we don't have to update AccessoryManager.wantRangeTestPackets here, because the node will reboot after we save config changes, and we'll pick up the new value after we reconnect. } .onChange(of: save) { _, newSave in if newSave != node?.rangeTestConfig?.save { hasChanges = true } diff --git a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift index 397945fb..bc35258d 100644 --- a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift @@ -167,6 +167,8 @@ struct StoreForwardConfig: View { } .onChange(of: enabled) { oldEnabled, newEnabled in if oldEnabled != newEnabled && newEnabled != node!.storeForwardConfig!.enabled { hasChanges = true } + + // Note: even if this is the connected node, we don't have to update AccessoryManager.wantStoreAndForwardPackets here, because the node will reboot after we save config changes, and we'll pick up the new value after we reconnect. } .onChange(of: isServer) { oldIsServer, newIsServer in if oldIsServer != newIsServer && newIsServer != node!.storeForwardConfig!.isRouter { hasChanges = true } diff --git a/Meshtastic/Views/Settings/SaveChannelQRCode.swift b/Meshtastic/Views/Settings/SaveChannelQRCode.swift index 71a032b4..089b12c2 100644 --- a/Meshtastic/Views/Settings/SaveChannelQRCode.swift +++ b/Meshtastic/Views/Settings/SaveChannelQRCode.swift @@ -9,11 +9,17 @@ import CoreData import OSLog import MeshtasticProtobufs +struct SaveChannelLinkData: Identifiable { + let id = UUID() + let data: String + let add: Bool +} + struct SaveChannelQRCode: View { @Environment(\.dismiss) private var dismiss @Environment(\.managedObjectContext) var context let channelSetLink: String - var addChannels: Bool = false + @State var addChannels: Bool = false var accessoryManager: AccessoryManager @State private var showError: Bool = false @@ -25,13 +31,13 @@ struct SaveChannelQRCode: View { VStack { Text("\(addChannels ? "Add" : "Replace all") Channels?") .font(.title) - Text("These settings will \(addChannels ? "add" : "replace all") channels. The current LoRa Config will be replaced, if there are substantial changes to the LoRa config the device will reboot") + Text("These settings will \(addChannels ? "add channels without changing any LoRa config values." : "replace all channels. The current LoRa Config will be replaced, if there are substantial changes to the LoRa config the device will reboot automatically.")") .fixedSize(horizontal: false, vertical: true) .foregroundColor(.gray) .font(.title3) .padding() - if !loraChanges.isEmpty { + if !loraChanges.isEmpty && !addChannels { VStack(alignment: .leading) { Text("LoRa Config Changes:") .font(.headline) diff --git a/Meshtastic/Views/Settings/UpdateIntervalPicker.swift b/Meshtastic/Views/Settings/UpdateIntervalPicker.swift index b7d6d153..c8601624 100644 --- a/Meshtastic/Views/Settings/UpdateIntervalPicker.swift +++ b/Meshtastic/Views/Settings/UpdateIntervalPicker.swift @@ -1,15 +1,15 @@ // -// UpdateIntervalPicker.swift -// Meshtastic +//  UpdateIntervalPicker.swift +//  Meshtastic // -// Copyright(c) Garth Vander Houwen 10/4/25. +//  Copyright(c) Garth Vander Houwen 10/4/25. // import SwiftUI struct UpdateIntervalPicker: View { let config: IntervalConfiguration let pickerLabel: String - let formatter = DateComponentsFormatter() + let formatter: DateComponentsFormatter // Make it a stored property @Binding var selectedInterval: UpdateInterval @@ -17,11 +17,14 @@ struct UpdateIntervalPicker: View { config.allowedCases .map { UpdateInterval(from: $0.rawValue) } } - + init(config: IntervalConfiguration, pickerLabel: String, selectedInterval: Binding) { self.config = config self.pickerLabel = pickerLabel self._selectedInterval = selectedInterval + let f = DateComponentsFormatter() + f.unitsStyle = .full + self.formatter = f } var body: some View { @@ -36,7 +39,7 @@ struct UpdateIntervalPicker: View { if isOutOfRange { let interval: TimeInterval = Double(selectedInterval.intValue) if let formattedString = formatter.string(from: interval) { - Text("⚠️ The configured value: (\(formattedString) seconds) is not one of the optimized options.") + Text("⚠️ The configured value: (\(formattedString)) is not one of the optimized options.") .font(.caption) .foregroundColor(.orange) } @@ -44,11 +47,11 @@ struct UpdateIntervalPicker: View { } } private var isOutOfRange: Bool { - switch selectedInterval.type { - case .manual: - return true - case .fixed(let fixedCase): - return !config.allowedCases.contains(fixedCase) - } - } + switch selectedInterval.type { + case .manual: + return true + case .fixed(let fixedCase): + return !config.allowedCases.contains(fixedCase) + } + } } diff --git a/MeshtasticProtobufs/Package.swift b/MeshtasticProtobufs/Package.swift index d329c439..f8715190 100644 --- a/MeshtasticProtobufs/Package.swift +++ b/MeshtasticProtobufs/Package.swift @@ -11,7 +11,7 @@ let package = Package( ), ], dependencies: [ - .package(url: "https://github.com/apple/swift-protobuf.git", from: "1.19.0"), + .package(url: "https://github.com/apple/swift-protobuf.git", from: "1.33.3"), ], targets: [ .target( diff --git a/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift index 138d2ed1..fa6a9e61 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/admin.proto @@ -24,7 +25,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// This message is handled by the Admin module and is responsible for all settings/channel read/write operations. /// This message is used to do settings operations to both remote AND local nodes. /// (Prior to 1.2 these operations were done via special ToRadio operations) -public struct AdminMessage { +public struct AdminMessage: Sendable { // 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. @@ -582,10 +583,11 @@ public struct AdminMessage { /// /// Tell the node to reset the nodedb. - public var nodedbReset: Int32 { + /// When true, favorites are preserved through reset. + public var nodedbReset: Bool { get { if case .nodedbReset(let v)? = payloadVariant {return v} - return 0 + return false } set {payloadVariant = .nodedbReset(newValue)} } @@ -594,7 +596,7 @@ public struct AdminMessage { /// /// TODO: REPLACE - public enum OneOf_PayloadVariant: Equatable { + public enum OneOf_PayloadVariant: Equatable, Sendable { /// /// Send the specified channel in the response to this message /// NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present) @@ -767,239 +769,14 @@ public struct AdminMessage { case factoryResetConfig(Int32) /// /// Tell the node to reset the nodedb. - case nodedbReset(Int32) + /// When true, favorites are preserved through reset. + case nodedbReset(Bool) - #if !swift(>=4.1) - public static func ==(lhs: AdminMessage.OneOf_PayloadVariant, rhs: AdminMessage.OneOf_PayloadVariant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.getChannelRequest, .getChannelRequest): return { - guard case .getChannelRequest(let l) = lhs, case .getChannelRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getChannelResponse, .getChannelResponse): return { - guard case .getChannelResponse(let l) = lhs, case .getChannelResponse(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getOwnerRequest, .getOwnerRequest): return { - guard case .getOwnerRequest(let l) = lhs, case .getOwnerRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getOwnerResponse, .getOwnerResponse): return { - guard case .getOwnerResponse(let l) = lhs, case .getOwnerResponse(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getConfigRequest, .getConfigRequest): return { - guard case .getConfigRequest(let l) = lhs, case .getConfigRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getConfigResponse, .getConfigResponse): return { - guard case .getConfigResponse(let l) = lhs, case .getConfigResponse(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getModuleConfigRequest, .getModuleConfigRequest): return { - guard case .getModuleConfigRequest(let l) = lhs, case .getModuleConfigRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getModuleConfigResponse, .getModuleConfigResponse): return { - guard case .getModuleConfigResponse(let l) = lhs, case .getModuleConfigResponse(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getCannedMessageModuleMessagesRequest, .getCannedMessageModuleMessagesRequest): return { - guard case .getCannedMessageModuleMessagesRequest(let l) = lhs, case .getCannedMessageModuleMessagesRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getCannedMessageModuleMessagesResponse, .getCannedMessageModuleMessagesResponse): return { - guard case .getCannedMessageModuleMessagesResponse(let l) = lhs, case .getCannedMessageModuleMessagesResponse(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getDeviceMetadataRequest, .getDeviceMetadataRequest): return { - guard case .getDeviceMetadataRequest(let l) = lhs, case .getDeviceMetadataRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getDeviceMetadataResponse, .getDeviceMetadataResponse): return { - guard case .getDeviceMetadataResponse(let l) = lhs, case .getDeviceMetadataResponse(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getRingtoneRequest, .getRingtoneRequest): return { - guard case .getRingtoneRequest(let l) = lhs, case .getRingtoneRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getRingtoneResponse, .getRingtoneResponse): return { - guard case .getRingtoneResponse(let l) = lhs, case .getRingtoneResponse(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getDeviceConnectionStatusRequest, .getDeviceConnectionStatusRequest): return { - guard case .getDeviceConnectionStatusRequest(let l) = lhs, case .getDeviceConnectionStatusRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getDeviceConnectionStatusResponse, .getDeviceConnectionStatusResponse): return { - guard case .getDeviceConnectionStatusResponse(let l) = lhs, case .getDeviceConnectionStatusResponse(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setHamMode, .setHamMode): return { - guard case .setHamMode(let l) = lhs, case .setHamMode(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getNodeRemoteHardwarePinsRequest, .getNodeRemoteHardwarePinsRequest): return { - guard case .getNodeRemoteHardwarePinsRequest(let l) = lhs, case .getNodeRemoteHardwarePinsRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getNodeRemoteHardwarePinsResponse, .getNodeRemoteHardwarePinsResponse): return { - guard case .getNodeRemoteHardwarePinsResponse(let l) = lhs, case .getNodeRemoteHardwarePinsResponse(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.enterDfuModeRequest, .enterDfuModeRequest): return { - guard case .enterDfuModeRequest(let l) = lhs, case .enterDfuModeRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.deleteFileRequest, .deleteFileRequest): return { - guard case .deleteFileRequest(let l) = lhs, case .deleteFileRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setScale, .setScale): return { - guard case .setScale(let l) = lhs, case .setScale(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.backupPreferences, .backupPreferences): return { - guard case .backupPreferences(let l) = lhs, case .backupPreferences(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.restorePreferences, .restorePreferences): return { - guard case .restorePreferences(let l) = lhs, case .restorePreferences(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.removeBackupPreferences, .removeBackupPreferences): return { - guard case .removeBackupPreferences(let l) = lhs, case .removeBackupPreferences(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.sendInputEvent, .sendInputEvent): return { - guard case .sendInputEvent(let l) = lhs, case .sendInputEvent(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setOwner, .setOwner): return { - guard case .setOwner(let l) = lhs, case .setOwner(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setChannel, .setChannel): return { - guard case .setChannel(let l) = lhs, case .setChannel(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setConfig, .setConfig): return { - guard case .setConfig(let l) = lhs, case .setConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setModuleConfig, .setModuleConfig): return { - guard case .setModuleConfig(let l) = lhs, case .setModuleConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setCannedMessageModuleMessages, .setCannedMessageModuleMessages): return { - guard case .setCannedMessageModuleMessages(let l) = lhs, case .setCannedMessageModuleMessages(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setRingtoneMessage, .setRingtoneMessage): return { - guard case .setRingtoneMessage(let l) = lhs, case .setRingtoneMessage(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.removeByNodenum, .removeByNodenum): return { - guard case .removeByNodenum(let l) = lhs, case .removeByNodenum(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setFavoriteNode, .setFavoriteNode): return { - guard case .setFavoriteNode(let l) = lhs, case .setFavoriteNode(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.removeFavoriteNode, .removeFavoriteNode): return { - guard case .removeFavoriteNode(let l) = lhs, case .removeFavoriteNode(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setFixedPosition, .setFixedPosition): return { - guard case .setFixedPosition(let l) = lhs, case .setFixedPosition(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.removeFixedPosition, .removeFixedPosition): return { - guard case .removeFixedPosition(let l) = lhs, case .removeFixedPosition(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.setTimeOnly, .setTimeOnly): return { - guard case .setTimeOnly(let l) = lhs, case .setTimeOnly(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getUiConfigRequest, .getUiConfigRequest): return { - guard case .getUiConfigRequest(let l) = lhs, case .getUiConfigRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.getUiConfigResponse, .getUiConfigResponse): return { - guard case .getUiConfigResponse(let l) = lhs, case .getUiConfigResponse(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.storeUiConfig, .storeUiConfig): return { - 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 - }() - case (.commitEditSettings, .commitEditSettings): return { - guard case .commitEditSettings(let l) = lhs, case .commitEditSettings(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.addContact, .addContact): return { - guard case .addContact(let l) = lhs, case .addContact(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.keyVerification, .keyVerification): return { - guard case .keyVerification(let l) = lhs, case .keyVerification(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.factoryResetDevice, .factoryResetDevice): return { - guard case .factoryResetDevice(let l) = lhs, case .factoryResetDevice(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.rebootOtaSeconds, .rebootOtaSeconds): return { - guard case .rebootOtaSeconds(let l) = lhs, case .rebootOtaSeconds(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.exitSimulator, .exitSimulator): return { - guard case .exitSimulator(let l) = lhs, case .exitSimulator(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.rebootSeconds, .rebootSeconds): return { - guard case .rebootSeconds(let l) = lhs, case .rebootSeconds(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 - }() - case (.factoryResetConfig, .factoryResetConfig): return { - guard case .factoryResetConfig(let l) = lhs, case .factoryResetConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.nodedbReset, .nodedbReset): return { - guard case .nodedbReset(let l) = lhs, case .nodedbReset(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } /// /// TODO: REPLACE - public enum ConfigType: SwiftProtobuf.Enum { + public enum ConfigType: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1079,11 +856,25 @@ public struct AdminMessage { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [AdminMessage.ConfigType] = [ + .deviceConfig, + .positionConfig, + .powerConfig, + .networkConfig, + .displayConfig, + .loraConfig, + .bluetoothConfig, + .securityConfig, + .sessionkeyConfig, + .deviceuiConfig, + ] + } /// /// TODO: REPLACE - public enum ModuleConfigType: SwiftProtobuf.Enum { + public enum ModuleConfigType: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1181,9 +972,26 @@ public struct AdminMessage { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [AdminMessage.ModuleConfigType] = [ + .mqttConfig, + .serialConfig, + .extnotifConfig, + .storeforwardConfig, + .rangetestConfig, + .telemetryConfig, + .cannedmsgConfig, + .audioConfig, + .remotehardwareConfig, + .neighborinfoConfig, + .ambientlightingConfig, + .detectionsensorConfig, + .paxcounterConfig, + ] + } - public enum BackupLocation: SwiftProtobuf.Enum { + public enum BackupLocation: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1215,11 +1023,17 @@ public struct AdminMessage { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [AdminMessage.BackupLocation] = [ + .flash, + .sd, + ] + } /// /// Input event message to be sent to the node. - public struct InputEvent { + public struct InputEvent: Sendable { // 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. @@ -1248,56 +1062,9 @@ public struct AdminMessage { public init() {} } -#if swift(>=4.2) - -extension AdminMessage.ConfigType: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [AdminMessage.ConfigType] = [ - .deviceConfig, - .positionConfig, - .powerConfig, - .networkConfig, - .displayConfig, - .loraConfig, - .bluetoothConfig, - .securityConfig, - .sessionkeyConfig, - .deviceuiConfig, - ] -} - -extension AdminMessage.ModuleConfigType: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [AdminMessage.ModuleConfigType] = [ - .mqttConfig, - .serialConfig, - .extnotifConfig, - .storeforwardConfig, - .rangetestConfig, - .telemetryConfig, - .cannedmsgConfig, - .audioConfig, - .remotehardwareConfig, - .neighborinfoConfig, - .ambientlightingConfig, - .detectionsensorConfig, - .paxcounterConfig, - ] -} - -extension AdminMessage.BackupLocation: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [AdminMessage.BackupLocation] = [ - .flash, - .sd, - ] -} - -#endif // swift(>=4.2) - /// /// Parameters for setting up Meshtastic for ameteur radio usage -public struct HamParameters { +public struct HamParameters: Sendable { // 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. @@ -1327,7 +1094,7 @@ public struct HamParameters { /// /// Response envelope for node_remote_hardware_pins -public struct NodeRemoteHardwarePinsResponse { +public struct NodeRemoteHardwarePinsResponse: Sendable { // 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. @@ -1341,7 +1108,7 @@ public struct NodeRemoteHardwarePinsResponse { public init() {} } -public struct SharedContact { +public struct SharedContact: Sendable { // 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. @@ -1378,7 +1145,7 @@ public struct SharedContact { /// /// This message is used by a client to initiate or complete a key verification -public struct KeyVerificationAdmin { +public struct KeyVerificationAdmin: Sendable { // 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. @@ -1408,7 +1175,7 @@ public struct KeyVerificationAdmin { /// /// Three stages of this request. - public enum MessageType: SwiftProtobuf.Enum { + public enum MessageType: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1453,6 +1220,14 @@ public struct KeyVerificationAdmin { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [KeyVerificationAdmin.MessageType] = [ + .initiateVerification, + .provideSecurityNumber, + .doVerify, + .doNotVerify, + ] + } public init() {} @@ -1460,97 +1235,13 @@ public struct KeyVerificationAdmin { fileprivate var _securityNumber: UInt32? = nil } -#if swift(>=4.2) - -extension KeyVerificationAdmin.MessageType: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [KeyVerificationAdmin.MessageType] = [ - .initiateVerification, - .provideSecurityNumber, - .doVerify, - .doNotVerify, - ] -} - -#endif // swift(>=4.2) - -#if swift(>=5.5) && canImport(_Concurrency) -extension AdminMessage: @unchecked Sendable {} -extension AdminMessage.OneOf_PayloadVariant: @unchecked Sendable {} -extension AdminMessage.ConfigType: @unchecked Sendable {} -extension AdminMessage.ModuleConfigType: @unchecked Sendable {} -extension AdminMessage.BackupLocation: @unchecked Sendable {} -extension AdminMessage.InputEvent: @unchecked Sendable {} -extension HamParameters: @unchecked Sendable {} -extension NodeRemoteHardwarePinsResponse: @unchecked Sendable {} -extension SharedContact: @unchecked Sendable {} -extension KeyVerificationAdmin: @unchecked Sendable {} -extension KeyVerificationAdmin.MessageType: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".AdminMessage" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 101: .standard(proto: "session_passkey"), - 1: .standard(proto: "get_channel_request"), - 2: .standard(proto: "get_channel_response"), - 3: .standard(proto: "get_owner_request"), - 4: .standard(proto: "get_owner_response"), - 5: .standard(proto: "get_config_request"), - 6: .standard(proto: "get_config_response"), - 7: .standard(proto: "get_module_config_request"), - 8: .standard(proto: "get_module_config_response"), - 10: .standard(proto: "get_canned_message_module_messages_request"), - 11: .standard(proto: "get_canned_message_module_messages_response"), - 12: .standard(proto: "get_device_metadata_request"), - 13: .standard(proto: "get_device_metadata_response"), - 14: .standard(proto: "get_ringtone_request"), - 15: .standard(proto: "get_ringtone_response"), - 16: .standard(proto: "get_device_connection_status_request"), - 17: .standard(proto: "get_device_connection_status_response"), - 18: .standard(proto: "set_ham_mode"), - 19: .standard(proto: "get_node_remote_hardware_pins_request"), - 20: .standard(proto: "get_node_remote_hardware_pins_response"), - 21: .standard(proto: "enter_dfu_mode_request"), - 22: .standard(proto: "delete_file_request"), - 23: .standard(proto: "set_scale"), - 24: .standard(proto: "backup_preferences"), - 25: .standard(proto: "restore_preferences"), - 26: .standard(proto: "remove_backup_preferences"), - 27: .standard(proto: "send_input_event"), - 32: .standard(proto: "set_owner"), - 33: .standard(proto: "set_channel"), - 34: .standard(proto: "set_config"), - 35: .standard(proto: "set_module_config"), - 36: .standard(proto: "set_canned_message_module_messages"), - 37: .standard(proto: "set_ringtone_message"), - 38: .standard(proto: "remove_by_nodenum"), - 39: .standard(proto: "set_favorite_node"), - 40: .standard(proto: "remove_favorite_node"), - 41: .standard(proto: "set_fixed_position"), - 42: .standard(proto: "remove_fixed_position"), - 43: .standard(proto: "set_time_only"), - 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"), - 66: .standard(proto: "add_contact"), - 67: .standard(proto: "key_verification"), - 94: .standard(proto: "factory_reset_device"), - 95: .standard(proto: "reboot_ota_seconds"), - 96: .standard(proto: "exit_simulator"), - 97: .standard(proto: "reboot_seconds"), - 98: .standard(proto: "shutdown_seconds"), - 99: .standard(proto: "factory_reset_config"), - 100: .standard(proto: "nodedb_reset"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}get_channel_request\0\u{3}get_channel_response\0\u{3}get_owner_request\0\u{3}get_owner_response\0\u{3}get_config_request\0\u{3}get_config_response\0\u{3}get_module_config_request\0\u{3}get_module_config_response\0\u{4}\u{2}get_canned_message_module_messages_request\0\u{3}get_canned_message_module_messages_response\0\u{3}get_device_metadata_request\0\u{3}get_device_metadata_response\0\u{3}get_ringtone_request\0\u{3}get_ringtone_response\0\u{3}get_device_connection_status_request\0\u{3}get_device_connection_status_response\0\u{3}set_ham_mode\0\u{3}get_node_remote_hardware_pins_request\0\u{3}get_node_remote_hardware_pins_response\0\u{3}enter_dfu_mode_request\0\u{3}delete_file_request\0\u{3}set_scale\0\u{3}backup_preferences\0\u{3}restore_preferences\0\u{3}remove_backup_preferences\0\u{3}send_input_event\0\u{4}\u{5}set_owner\0\u{3}set_channel\0\u{3}set_config\0\u{3}set_module_config\0\u{3}set_canned_message_module_messages\0\u{3}set_ringtone_message\0\u{3}remove_by_nodenum\0\u{3}set_favorite_node\0\u{3}remove_favorite_node\0\u{3}set_fixed_position\0\u{3}remove_fixed_position\0\u{3}set_time_only\0\u{3}get_ui_config_request\0\u{3}get_ui_config_response\0\u{3}store_ui_config\0\u{3}set_ignored_node\0\u{3}remove_ignored_node\0\u{4}\u{10}begin_edit_settings\0\u{3}commit_edit_settings\0\u{3}add_contact\0\u{3}key_verification\0\u{4}\u{1b}factory_reset_device\0\u{3}reboot_ota_seconds\0\u{3}exit_simulator\0\u{3}reboot_seconds\0\u{3}shutdown_seconds\0\u{3}factory_reset_config\0\u{3}nodedb_reset\0\u{3}session_passkey\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2073,8 +1764,8 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat } }() case 100: try { - var v: Int32? - try decoder.decodeSingularInt32Field(value: &v) + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) if let v = v { if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} self.payloadVariant = .nodedbReset(v) @@ -2306,7 +1997,7 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat }() case .nodedbReset?: try { guard case .nodedbReset(let v)? = self.payloadVariant else { preconditionFailure() } - try visitor.visitSingularInt32Field(value: v, fieldNumber: 100) + try visitor.visitSingularBoolField(value: v, fieldNumber: 100) }() case nil: break } @@ -2325,53 +2016,20 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat } extension AdminMessage.ConfigType: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DEVICE_CONFIG"), - 1: .same(proto: "POSITION_CONFIG"), - 2: .same(proto: "POWER_CONFIG"), - 3: .same(proto: "NETWORK_CONFIG"), - 4: .same(proto: "DISPLAY_CONFIG"), - 5: .same(proto: "LORA_CONFIG"), - 6: .same(proto: "BLUETOOTH_CONFIG"), - 7: .same(proto: "SECURITY_CONFIG"), - 8: .same(proto: "SESSIONKEY_CONFIG"), - 9: .same(proto: "DEVICEUI_CONFIG"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DEVICE_CONFIG\0\u{1}POSITION_CONFIG\0\u{1}POWER_CONFIG\0\u{1}NETWORK_CONFIG\0\u{1}DISPLAY_CONFIG\0\u{1}LORA_CONFIG\0\u{1}BLUETOOTH_CONFIG\0\u{1}SECURITY_CONFIG\0\u{1}SESSIONKEY_CONFIG\0\u{1}DEVICEUI_CONFIG\0") } extension AdminMessage.ModuleConfigType: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "MQTT_CONFIG"), - 1: .same(proto: "SERIAL_CONFIG"), - 2: .same(proto: "EXTNOTIF_CONFIG"), - 3: .same(proto: "STOREFORWARD_CONFIG"), - 4: .same(proto: "RANGETEST_CONFIG"), - 5: .same(proto: "TELEMETRY_CONFIG"), - 6: .same(proto: "CANNEDMSG_CONFIG"), - 7: .same(proto: "AUDIO_CONFIG"), - 8: .same(proto: "REMOTEHARDWARE_CONFIG"), - 9: .same(proto: "NEIGHBORINFO_CONFIG"), - 10: .same(proto: "AMBIENTLIGHTING_CONFIG"), - 11: .same(proto: "DETECTIONSENSOR_CONFIG"), - 12: .same(proto: "PAXCOUNTER_CONFIG"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0MQTT_CONFIG\0\u{1}SERIAL_CONFIG\0\u{1}EXTNOTIF_CONFIG\0\u{1}STOREFORWARD_CONFIG\0\u{1}RANGETEST_CONFIG\0\u{1}TELEMETRY_CONFIG\0\u{1}CANNEDMSG_CONFIG\0\u{1}AUDIO_CONFIG\0\u{1}REMOTEHARDWARE_CONFIG\0\u{1}NEIGHBORINFO_CONFIG\0\u{1}AMBIENTLIGHTING_CONFIG\0\u{1}DETECTIONSENSOR_CONFIG\0\u{1}PAXCOUNTER_CONFIG\0") } extension AdminMessage.BackupLocation: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "FLASH"), - 1: .same(proto: "SD"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0FLASH\0\u{1}SD\0") } extension AdminMessage.InputEvent: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = AdminMessage.protoMessageName + ".InputEvent" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "event_code"), - 2: .standard(proto: "kb_char"), - 3: .standard(proto: "touch_x"), - 4: .standard(proto: "touch_y"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}event_code\0\u{3}kb_char\0\u{3}touch_x\0\u{3}touch_y\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2416,12 +2074,7 @@ extension AdminMessage.InputEvent: SwiftProtobuf.Message, SwiftProtobuf._Message extension HamParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".HamParameters" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "call_sign"), - 2: .standard(proto: "tx_power"), - 3: .same(proto: "frequency"), - 4: .standard(proto: "short_name"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}call_sign\0\u{3}tx_power\0\u{1}frequency\0\u{3}short_name\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2445,7 +2098,7 @@ extension HamParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa if self.txPower != 0 { try visitor.visitSingularInt32Field(value: self.txPower, fieldNumber: 2) } - if self.frequency != 0 { + if self.frequency.bitPattern != 0 { try visitor.visitSingularFloatField(value: self.frequency, fieldNumber: 3) } if !self.shortName.isEmpty { @@ -2466,9 +2119,7 @@ extension HamParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa extension NodeRemoteHardwarePinsResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".NodeRemoteHardwarePinsResponse" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "node_remote_hardware_pins"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}node_remote_hardware_pins\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2498,12 +2149,7 @@ extension NodeRemoteHardwarePinsResponse: SwiftProtobuf.Message, SwiftProtobuf._ extension SharedContact: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".SharedContact" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "node_num"), - 2: .same(proto: "user"), - 3: .standard(proto: "should_ignore"), - 4: .standard(proto: "manually_verified"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}node_num\0\u{1}user\0\u{3}should_ignore\0\u{3}manually_verified\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2552,12 +2198,7 @@ extension SharedContact: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa extension KeyVerificationAdmin: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".KeyVerificationAdmin" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "message_type"), - 2: .standard(proto: "remote_nodenum"), - 3: .same(proto: "nonce"), - 4: .standard(proto: "security_number"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}message_type\0\u{3}remote_nodenum\0\u{1}nonce\0\u{3}security_number\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2605,10 +2246,5 @@ extension KeyVerificationAdmin: SwiftProtobuf.Message, SwiftProtobuf._MessageImp } extension KeyVerificationAdmin.MessageType: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "INITIATE_VERIFICATION"), - 1: .same(proto: "PROVIDE_SECURITY_NUMBER"), - 2: .same(proto: "DO_VERIFY"), - 3: .same(proto: "DO_NOT_VERIFY"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0INITIATE_VERIFICATION\0\u{1}PROVIDE_SECURITY_NUMBER\0\u{1}DO_VERIFY\0\u{1}DO_NOT_VERIFY\0") } diff --git a/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift index 0457077c..9ade8540 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/apponly.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -26,7 +26,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// any SECONDARY channels. /// No DISABLED channels are included. /// This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL -public struct ChannelSet { +public struct ChannelSet: Sendable { // 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. @@ -53,20 +53,13 @@ public struct ChannelSet { fileprivate var _loraConfig: Config.LoRaConfig? = nil } -#if swift(>=5.5) && canImport(_Concurrency) -extension ChannelSet: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension ChannelSet: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ChannelSet" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "settings"), - 2: .standard(proto: "lora_config"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}settings\0\u{3}lora_config\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift index 867648a9..3076a6da 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/atak.proto @@ -20,7 +21,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum Team: SwiftProtobuf.Enum { +public enum Team: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -130,11 +131,6 @@ public enum Team: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension Team: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Team] = [ .unspecifedColor, @@ -153,13 +149,12 @@ extension Team: CaseIterable { .darkGreen, .brown, ] -} -#endif // swift(>=4.2) +} /// /// Role of the group member -public enum MemberRole: SwiftProtobuf.Enum { +public enum MemberRole: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -233,11 +228,6 @@ public enum MemberRole: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension MemberRole: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [MemberRole] = [ .unspecifed, @@ -250,13 +240,12 @@ extension MemberRole: CaseIterable { .rto, .k9, ] -} -#endif // swift(>=4.2) +} /// /// Packets for the official ATAK Plugin -public struct TAKPacket { +public struct TAKPacket: Sendable { // 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. @@ -337,7 +326,7 @@ public struct TAKPacket { /// /// The payload of the packet - public enum OneOf_PayloadVariant: Equatable { + public enum OneOf_PayloadVariant: Equatable, Sendable { /// /// TAK position report case pli(PLI) @@ -349,28 +338,6 @@ public struct TAKPacket { /// May be compressed / truncated by the sender (EUD) case detail(Data) - #if !swift(>=4.1) - public static func ==(lhs: TAKPacket.OneOf_PayloadVariant, rhs: TAKPacket.OneOf_PayloadVariant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.pli, .pli): return { - guard case .pli(let l) = lhs, case .pli(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.chat, .chat): return { - 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 - } - } - #endif } public init() {} @@ -382,7 +349,7 @@ public struct TAKPacket { /// /// ATAK GeoChat message -public struct GeoChat { +public struct GeoChat: Sendable { // 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. @@ -424,7 +391,7 @@ public struct GeoChat { /// /// ATAK Group /// <__group role='Team Member' name='Cyan'/> -public struct Group { +public struct Group: Sendable { // 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. @@ -446,7 +413,7 @@ public struct Group { /// /// ATAK EUD Status /// -public struct Status { +public struct Status: Sendable { // 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. @@ -463,7 +430,7 @@ public struct Status { /// /// ATAK Contact /// -public struct Contact { +public struct Contact: Sendable { // 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. @@ -483,7 +450,7 @@ public struct Contact { /// /// Position Location Information from ATAK -public struct PLI { +public struct PLI: Sendable { // 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. @@ -515,67 +482,21 @@ public struct PLI { public init() {} } -#if swift(>=5.5) && canImport(_Concurrency) -extension Team: @unchecked Sendable {} -extension MemberRole: @unchecked Sendable {} -extension TAKPacket: @unchecked Sendable {} -extension TAKPacket.OneOf_PayloadVariant: @unchecked Sendable {} -extension GeoChat: @unchecked Sendable {} -extension Group: @unchecked Sendable {} -extension Status: @unchecked Sendable {} -extension Contact: @unchecked Sendable {} -extension PLI: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension Team: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "Unspecifed_Color"), - 1: .same(proto: "White"), - 2: .same(proto: "Yellow"), - 3: .same(proto: "Orange"), - 4: .same(proto: "Magenta"), - 5: .same(proto: "Red"), - 6: .same(proto: "Maroon"), - 7: .same(proto: "Purple"), - 8: .same(proto: "Dark_Blue"), - 9: .same(proto: "Blue"), - 10: .same(proto: "Cyan"), - 11: .same(proto: "Teal"), - 12: .same(proto: "Green"), - 13: .same(proto: "Dark_Green"), - 14: .same(proto: "Brown"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0Unspecifed_Color\0\u{1}White\0\u{1}Yellow\0\u{1}Orange\0\u{1}Magenta\0\u{1}Red\0\u{1}Maroon\0\u{1}Purple\0\u{1}Dark_Blue\0\u{1}Blue\0\u{1}Cyan\0\u{1}Teal\0\u{1}Green\0\u{1}Dark_Green\0\u{1}Brown\0") } extension MemberRole: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "Unspecifed"), - 1: .same(proto: "TeamMember"), - 2: .same(proto: "TeamLead"), - 3: .same(proto: "HQ"), - 4: .same(proto: "Sniper"), - 5: .same(proto: "Medic"), - 6: .same(proto: "ForwardObserver"), - 7: .same(proto: "RTO"), - 8: .same(proto: "K9"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0Unspecifed\0\u{1}TeamMember\0\u{1}TeamLead\0\u{1}HQ\0\u{1}Sniper\0\u{1}Medic\0\u{1}ForwardObserver\0\u{1}RTO\0\u{1}K9\0") } extension TAKPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".TAKPacket" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "is_compressed"), - 2: .same(proto: "contact"), - 3: .same(proto: "group"), - 4: .same(proto: "status"), - 5: .same(proto: "pli"), - 6: .same(proto: "chat"), - 7: .same(proto: "detail"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}is_compressed\0\u{1}contact\0\u{1}group\0\u{1}status\0\u{1}pli\0\u{1}chat\0\u{1}detail\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -674,11 +595,7 @@ extension TAKPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation extension GeoChat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".GeoChat" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "message"), - 2: .same(proto: "to"), - 3: .standard(proto: "to_callsign"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}message\0\u{1}to\0\u{3}to_callsign\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -722,10 +639,7 @@ extension GeoChat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa extension Group: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Group" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "role"), - 2: .same(proto: "team"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}role\0\u{1}team\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -760,9 +674,7 @@ extension Group: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase extension Status: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Status" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "battery"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}battery\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -792,10 +704,7 @@ extension Status: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas extension Contact: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Contact" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "callsign"), - 2: .standard(proto: "device_callsign"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}callsign\0\u{3}device_callsign\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -830,13 +739,7 @@ extension Contact: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa extension PLI: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".PLI" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "latitude_i"), - 2: .standard(proto: "longitude_i"), - 3: .same(proto: "altitude"), - 4: .same(proto: "speed"), - 5: .same(proto: "course"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}latitude_i\0\u{3}longitude_i\0\u{1}altitude\0\u{1}speed\0\u{1}course\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift index 1b8c84de..8776adbf 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/cannedmessages.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Canned message module configuration. -public struct CannedMessageModuleConfig { +public struct CannedMessageModuleConfig: Sendable { // 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. @@ -36,19 +36,13 @@ public struct CannedMessageModuleConfig { public init() {} } -#if swift(>=5.5) && canImport(_Concurrency) -extension CannedMessageModuleConfig: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension CannedMessageModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".CannedMessageModuleConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "messages"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}messages\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift index 9af4a87a..15995842 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/channel.proto @@ -36,13 +37,15 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// FIXME: Add description of multi-channel support and how primary vs secondary channels are used. /// FIXME: explain how apps use channels for security. /// explain how remote settings and remote gpio are managed as an example -public struct ChannelSettings { +public struct ChannelSettings: Sendable { // 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. /// /// Deprecated in favor of LoraConfig.channel_num + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var channelNum: UInt32 = 0 /// @@ -102,10 +105,6 @@ public struct ChannelSettings { /// Clears the value of `moduleSettings`. Subsequent reads from it will return its default value. public mutating func clearModuleSettings() {self._moduleSettings = nil} - /// - /// Whether or not we should receive notifactions / alerts through this channel - public var mute: Bool = false - public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -115,7 +114,7 @@ public struct ChannelSettings { /// /// This message is specifically for modules to store per-channel configuration data. -public struct ModuleSettings { +public struct ModuleSettings: Sendable { // 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. @@ -125,9 +124,9 @@ public struct ModuleSettings { public var positionPrecision: UInt32 = 0 /// - /// Controls whether or not the phone / clients should mute the current channel + /// Controls whether or not the client / device should mute the current channel /// Useful for noisy public channels you don't necessarily want to disable - public var isClientMuted: Bool = false + public var isMuted: Bool = false public var unknownFields = SwiftProtobuf.UnknownStorage() @@ -136,7 +135,7 @@ public struct ModuleSettings { /// /// A pair of a channel number, mode and the (sharable) settings for that channel -public struct Channel { +public struct Channel: Sendable { // 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. @@ -174,7 +173,7 @@ public struct Channel { /// cross band routing as needed. /// If a device has only a single radio (the common case) only one channel can be PRIMARY at a time /// (but any number of SECONDARY channels can't be sent received on that common frequency) - public enum Role: SwiftProtobuf.Enum { + public enum Role: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -213,6 +212,13 @@ public struct Channel { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Channel.Role] = [ + .disabled, + .primary, + .secondary, + ] + } public init() {} @@ -220,42 +226,13 @@ public struct Channel { fileprivate var _settings: ChannelSettings? = nil } -#if swift(>=4.2) - -extension Channel.Role: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Channel.Role] = [ - .disabled, - .primary, - .secondary, - ] -} - -#endif // swift(>=4.2) - -#if swift(>=5.5) && canImport(_Concurrency) -extension ChannelSettings: @unchecked Sendable {} -extension ModuleSettings: @unchecked Sendable {} -extension Channel: @unchecked Sendable {} -extension Channel.Role: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ChannelSettings" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "channel_num"), - 2: .same(proto: "psk"), - 3: .same(proto: "name"), - 4: .same(proto: "id"), - 5: .standard(proto: "uplink_enabled"), - 6: .standard(proto: "downlink_enabled"), - 7: .standard(proto: "module_settings"), - 8: .same(proto: "mute"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}channel_num\0\u{1}psk\0\u{1}name\0\u{1}id\0\u{3}uplink_enabled\0\u{3}downlink_enabled\0\u{3}module_settings\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -270,7 +247,6 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen case 5: try { try decoder.decodeSingularBoolField(value: &self.uplinkEnabled) }() case 6: try { try decoder.decodeSingularBoolField(value: &self.downlinkEnabled) }() case 7: try { try decoder.decodeSingularMessageField(value: &self._moduleSettings) }() - case 8: try { try decoder.decodeSingularBoolField(value: &self.mute) }() default: break } } @@ -302,9 +278,6 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen try { if let v = self._moduleSettings { try visitor.visitSingularMessageField(value: v, fieldNumber: 7) } }() - if self.mute != false { - try visitor.visitSingularBoolField(value: self.mute, fieldNumber: 8) - } try unknownFields.traverse(visitor: &visitor) } @@ -316,7 +289,6 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen if lhs.uplinkEnabled != rhs.uplinkEnabled {return false} if lhs.downlinkEnabled != rhs.downlinkEnabled {return false} if lhs._moduleSettings != rhs._moduleSettings {return false} - if lhs.mute != rhs.mute {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -324,10 +296,7 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen extension ModuleSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ModuleSettings" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "position_precision"), - 2: .standard(proto: "is_client_muted"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}position_precision\0\u{3}is_muted\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -336,7 +305,7 @@ extension ModuleSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { case 1: try { try decoder.decodeSingularUInt32Field(value: &self.positionPrecision) }() - case 2: try { try decoder.decodeSingularBoolField(value: &self.isClientMuted) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.isMuted) }() default: break } } @@ -346,15 +315,15 @@ extension ModuleSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement if self.positionPrecision != 0 { try visitor.visitSingularUInt32Field(value: self.positionPrecision, fieldNumber: 1) } - if self.isClientMuted != false { - try visitor.visitSingularBoolField(value: self.isClientMuted, fieldNumber: 2) + if self.isMuted != false { + try visitor.visitSingularBoolField(value: self.isMuted, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) } public static func ==(lhs: ModuleSettings, rhs: ModuleSettings) -> Bool { if lhs.positionPrecision != rhs.positionPrecision {return false} - if lhs.isClientMuted != rhs.isClientMuted {return false} + if lhs.isMuted != rhs.isMuted {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -362,11 +331,7 @@ extension ModuleSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement extension Channel: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Channel" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "index"), - 2: .same(proto: "settings"), - 3: .same(proto: "role"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}index\0\u{1}settings\0\u{1}role\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -409,9 +374,5 @@ extension Channel: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa } extension Channel.Role: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DISABLED"), - 1: .same(proto: "PRIMARY"), - 2: .same(proto: "SECONDARY"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DISABLED\0\u{1}PRIMARY\0\u{1}SECONDARY\0") } diff --git a/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift index f89a8e3c..9afbdf9c 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/clientonly.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -23,7 +23,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// This abstraction is used to contain any configuration for provisioning a node on any client. /// It is useful for importing and exporting configurations. -public struct DeviceProfile { +public struct DeviceProfile: Sendable { // 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. @@ -130,26 +130,13 @@ public struct DeviceProfile { fileprivate var _cannedMessages: String? = nil } -#if swift(>=5.5) && canImport(_Concurrency) -extension DeviceProfile: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension DeviceProfile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".DeviceProfile" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "long_name"), - 2: .standard(proto: "short_name"), - 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 static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}long_name\0\u{3}short_name\0\u{3}channel_url\0\u{1}config\0\u{3}module_config\0\u{3}fixed_position\0\u{1}ringtone\0\u{3}canned_messages\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift index 03862795..28074a6b 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/config.proto @@ -20,7 +21,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct Config { +public struct Config: Sendable { // 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. @@ -113,7 +114,7 @@ public struct Config { /// /// Payload Variant - public enum OneOf_PayloadVariant: Equatable { + public enum OneOf_PayloadVariant: Equatable, Sendable { case device(Config.DeviceConfig) case position(Config.PositionConfig) case power(Config.PowerConfig) @@ -125,61 +126,11 @@ public struct Config { case sessionkey(Config.SessionkeyConfig) case deviceUi(DeviceUIConfig) - #if !swift(>=4.1) - public static func ==(lhs: Config.OneOf_PayloadVariant, rhs: Config.OneOf_PayloadVariant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.device, .device): return { - guard case .device(let l) = lhs, case .device(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.position, .position): return { - guard case .position(let l) = lhs, case .position(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.power, .power): return { - guard case .power(let l) = lhs, case .power(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.network, .network): return { - guard case .network(let l) = lhs, case .network(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.display, .display): return { - guard case .display(let l) = lhs, case .display(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.lora, .lora): return { - guard case .lora(let l) = lhs, case .lora(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.bluetooth, .bluetooth): return { - guard case .bluetooth(let l) = lhs, case .bluetooth(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.security, .security): return { - guard case .security(let l) = lhs, case .security(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.sessionkey, .sessionkey): return { - guard case .sessionkey(let l) = lhs, case .sessionkey(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.deviceUi, .deviceUi): return { - guard case .deviceUi(let l) = lhs, case .deviceUi(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } /// /// Configuration - public struct DeviceConfig { + public struct DeviceConfig: Sendable { // 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. @@ -191,6 +142,8 @@ public struct Config { /// /// Disabling this will disable the SerialConsole by not initilizing the StreamAPI /// Moved to SecurityConfig + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var serialEnabled: Bool = false /// @@ -220,6 +173,8 @@ public struct Config { /// If true, device is considered to be "managed" by a mesh administrator /// Clients should then limit available configuration and administrative options inside the user interface /// Moved to SecurityConfig + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var isManaged: Bool = false /// @@ -243,7 +198,7 @@ public struct Config { /// /// Defines the device's role on the Mesh network - public enum Role: SwiftProtobuf.Enum { + public enum Role: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -261,6 +216,8 @@ public struct Config { /// The wifi radio and the oled screen will be put to sleep. /// This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh. case router // = 2 + + /// NOTE: This enum value was marked as deprecated in the .proto file case routerClient // = 3 /// @@ -268,6 +225,8 @@ public struct Config { /// Technical Details: Mesh packets will simply be rebroadcasted over this node. Nodes configured with this role will not originate NodeInfo, Position, Telemetry /// or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate. /// Deprecated in v2.7.11 because it creates "holes" in the mesh rebroadcast chain. + /// + /// NOTE: This enum value was marked as deprecated in the .proto file case repeater // = 4 /// @@ -371,11 +330,28 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DeviceConfig.Role] = [ + .client, + .clientMute, + .router, + .routerClient, + .repeater, + .tracker, + .sensor, + .tak, + .clientHidden, + .lostAndFound, + .takTracker, + .routerLate, + .clientBase, + ] + } /// /// Defines the device's behavior for how messages are rebroadcast - public enum RebroadcastMode: SwiftProtobuf.Enum { + public enum RebroadcastMode: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -436,11 +412,21 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DeviceConfig.RebroadcastMode] = [ + .all, + .allSkipDecoding, + .localOnly, + .knownOnly, + .none, + .corePortnumsOnly, + ] + } /// /// Defines buzzer behavior for audio feedback - public enum BuzzerMode: SwiftProtobuf.Enum { + public enum BuzzerMode: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -497,6 +483,15 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DeviceConfig.BuzzerMode] = [ + .allEnabled, + .disabled, + .notificationsOnly, + .systemOnly, + .directMsgOnly, + ] + } public init() {} @@ -504,7 +499,7 @@ public struct Config { /// /// Position Config - public struct PositionConfig { + public struct PositionConfig: Sendable { // 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. @@ -526,6 +521,8 @@ public struct Config { /// /// Is GPS enabled for this node? + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var gpsEnabled: Bool = false /// @@ -536,6 +533,8 @@ public struct Config { /// /// Deprecated in favor of using smart / regular broadcast intervals as implicit attempt time + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var gpsAttemptTime: UInt32 = 0 /// @@ -576,7 +575,7 @@ public struct Config { /// are always included (also time if GPS-synced) /// NOTE: the more fields are included, the larger the message will be - /// leading to longer airtime and a higher risk of packet loss - public enum PositionFlags: SwiftProtobuf.Enum { + public enum PositionFlags: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -666,9 +665,24 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.PositionConfig.PositionFlags] = [ + .unset, + .altitude, + .altitudeMsl, + .geoidalSeparation, + .dop, + .hvdop, + .satinview, + .seqNo, + .timestamp, + .heading, + .speed, + ] + } - public enum GpsMode: SwiftProtobuf.Enum { + public enum GpsMode: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -706,6 +720,13 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.PositionConfig.GpsMode] = [ + .disabled, + .enabled, + .notPresent, + ] + } public init() {} @@ -714,7 +735,7 @@ public struct Config { /// /// Power Config\ /// See [Power Config](/docs/settings/config/power) for additional power config details. - public struct PowerConfig { + public struct PowerConfig: Sendable { // 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. @@ -774,7 +795,7 @@ public struct Config { /// /// Network Config - public struct NetworkConfig { + public struct NetworkConfig: Sendable { // 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. @@ -829,7 +850,7 @@ public struct Config { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum AddressMode: SwiftProtobuf.Enum { + public enum AddressMode: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -861,11 +882,17 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.NetworkConfig.AddressMode] = [ + .dhcp, + .static, + ] + } /// /// Available flags auxiliary network protocols - public enum ProtocolFlags: SwiftProtobuf.Enum { + public enum ProtocolFlags: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -897,9 +924,15 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.NetworkConfig.ProtocolFlags] = [ + .noBroadcast, + .udpBroadcast, + ] + } - public struct IpV4Config { + public struct IpV4Config: Sendable { // 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. @@ -932,7 +965,7 @@ public struct Config { /// /// Display Config - public struct DisplayConfig { + public struct DisplayConfig: Sendable { // 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. @@ -945,6 +978,8 @@ public struct Config { /// /// Deprecated in 2.7.4: Unused /// How the GPS coordinates are formatted on the OLED screen. + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var gpsFormat: Config.DisplayConfig.DeprecatedGpsCoordinateFormat = .unused /// @@ -955,6 +990,8 @@ public struct Config { /// /// If this is set, the displayed compass will always point north. if unset, the old behaviour /// (top of display is heading direction) is used. + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var compassNorthTop: Bool = false /// @@ -999,7 +1036,7 @@ public struct Config { /// /// Deprecated in 2.7.4: Unused - public enum DeprecatedGpsCoordinateFormat: SwiftProtobuf.Enum { + public enum DeprecatedGpsCoordinateFormat: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int case unused // = 0 case UNRECOGNIZED(Int) @@ -1022,11 +1059,16 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.DeprecatedGpsCoordinateFormat] = [ + .unused, + ] + } /// /// Unit display preference - public enum DisplayUnits: SwiftProtobuf.Enum { + public enum DisplayUnits: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1058,11 +1100,17 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.DisplayUnits] = [ + .metric, + .imperial, + ] + } /// /// Override OLED outo detect with this if it fails. - public enum OledType: SwiftProtobuf.Enum { + public enum OledType: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1112,9 +1160,18 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.OledType] = [ + .oledAuto, + .oledSsd1306, + .oledSh1106, + .oledSh1107, + .oledSh1107128128, + ] + } - public enum DisplayMode: SwiftProtobuf.Enum { + public enum DisplayMode: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1158,9 +1215,17 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.DisplayMode] = [ + .default, + .twocolor, + .inverted, + .color, + ] + } - public enum CompassOrientation: SwiftProtobuf.Enum { + public enum CompassOrientation: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1228,6 +1293,18 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.CompassOrientation] = [ + .degrees0, + .degrees90, + .degrees180, + .degrees270, + .degrees0Inverted, + .degrees90Inverted, + .degrees180Inverted, + .degrees270Inverted, + ] + } public init() {} @@ -1235,7 +1312,7 @@ public struct Config { /// /// Lora Config - public struct LoRaConfig { + public struct LoRaConfig: @unchecked Sendable { // 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. @@ -1399,7 +1476,7 @@ public struct Config { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum RegionCode: SwiftProtobuf.Enum { + public enum RegionCode: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1581,12 +1658,43 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.LoRaConfig.RegionCode] = [ + .unset, + .us, + .eu433, + .eu868, + .cn, + .jp, + .anz, + .kr, + .tw, + .ru, + .in, + .nz865, + .th, + .lora24, + .ua433, + .ua868, + .my433, + .my919, + .sg923, + .ph433, + .ph868, + .ph915, + .anz433, + .kz433, + .kz863, + .np865, + .br902, + ] + } /// /// Standard predefined channel settings /// Note: these mappings must match ModemPreset Choice in the device code. - public enum ModemPreset: SwiftProtobuf.Enum { + public enum ModemPreset: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1595,11 +1703,16 @@ public struct Config { /// /// Long Range - Slow + /// Deprecated in 2.7: Unpopular slow preset. + /// + /// NOTE: This enum value was marked as deprecated in the .proto file case longSlow // = 1 /// /// Very Long Range - Slow /// Deprecated in 2.5: Works only with txco and is unusably slow + /// + /// NOTE: This enum value was marked as deprecated in the .proto file case veryLongSlow // = 2 /// @@ -1627,6 +1740,11 @@ public struct Config { /// This is the fastest preset and the only one with 500kHz bandwidth. /// It is not legal to use in all regions due to this wider bandwidth. case shortTurbo // = 8 + + /// + /// Long Range - Turbo + /// This preset performs similarly to LongFast, but with 500Khz bandwidth. + case longTurbo // = 9 case UNRECOGNIZED(Int) public init() { @@ -1644,6 +1762,7 @@ public struct Config { case 6: self = .shortFast case 7: self = .longModerate case 8: self = .shortTurbo + case 9: self = .longTurbo default: self = .UNRECOGNIZED(rawValue) } } @@ -1659,10 +1778,25 @@ public struct Config { case .shortFast: return 6 case .longModerate: return 7 case .shortTurbo: return 8 + case .longTurbo: return 9 case .UNRECOGNIZED(let i): return i } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.LoRaConfig.ModemPreset] = [ + .longFast, + .longSlow, + .veryLongSlow, + .mediumSlow, + .mediumFast, + .shortSlow, + .shortFast, + .longModerate, + .shortTurbo, + .longTurbo, + ] + } public init() {} @@ -1670,7 +1804,7 @@ public struct Config { fileprivate var _storage = _StorageClass.defaultInstance } - public struct BluetoothConfig { + public struct BluetoothConfig: Sendable { // 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. @@ -1689,7 +1823,7 @@ public struct Config { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum PairingMode: SwiftProtobuf.Enum { + public enum PairingMode: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1727,12 +1861,19 @@ public struct Config { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.BluetoothConfig.PairingMode] = [ + .randomPin, + .fixedPin, + .noPin, + ] + } public init() {} } - public struct SecurityConfig { + public struct SecurityConfig: Sendable { // 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. @@ -1776,7 +1917,7 @@ public struct Config { /// /// Blank config request, strictly for getting the session key - public struct SessionkeyConfig { + public struct SessionkeyConfig: Sendable { // 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. @@ -1789,249 +1930,13 @@ public struct Config { public init() {} } -#if swift(>=4.2) - -extension Config.DeviceConfig.Role: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DeviceConfig.Role] = [ - .client, - .clientMute, - .router, - .routerClient, - .repeater, - .tracker, - .sensor, - .tak, - .clientHidden, - .lostAndFound, - .takTracker, - .routerLate, - .clientBase, - ] -} - -extension Config.DeviceConfig.RebroadcastMode: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DeviceConfig.RebroadcastMode] = [ - .all, - .allSkipDecoding, - .localOnly, - .knownOnly, - .none, - .corePortnumsOnly, - ] -} - -extension Config.DeviceConfig.BuzzerMode: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DeviceConfig.BuzzerMode] = [ - .allEnabled, - .disabled, - .notificationsOnly, - .systemOnly, - .directMsgOnly, - ] -} - -extension Config.PositionConfig.PositionFlags: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.PositionConfig.PositionFlags] = [ - .unset, - .altitude, - .altitudeMsl, - .geoidalSeparation, - .dop, - .hvdop, - .satinview, - .seqNo, - .timestamp, - .heading, - .speed, - ] -} - -extension Config.PositionConfig.GpsMode: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.PositionConfig.GpsMode] = [ - .disabled, - .enabled, - .notPresent, - ] -} - -extension Config.NetworkConfig.AddressMode: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.NetworkConfig.AddressMode] = [ - .dhcp, - .static, - ] -} - -extension Config.NetworkConfig.ProtocolFlags: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.NetworkConfig.ProtocolFlags] = [ - .noBroadcast, - .udpBroadcast, - ] -} - -extension Config.DisplayConfig.DeprecatedGpsCoordinateFormat: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.DeprecatedGpsCoordinateFormat] = [ - .unused, - ] -} - -extension Config.DisplayConfig.DisplayUnits: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.DisplayUnits] = [ - .metric, - .imperial, - ] -} - -extension Config.DisplayConfig.OledType: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.OledType] = [ - .oledAuto, - .oledSsd1306, - .oledSh1106, - .oledSh1107, - .oledSh1107128128, - ] -} - -extension Config.DisplayConfig.DisplayMode: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.DisplayMode] = [ - .default, - .twocolor, - .inverted, - .color, - ] -} - -extension Config.DisplayConfig.CompassOrientation: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.CompassOrientation] = [ - .degrees0, - .degrees90, - .degrees180, - .degrees270, - .degrees0Inverted, - .degrees90Inverted, - .degrees180Inverted, - .degrees270Inverted, - ] -} - -extension Config.LoRaConfig.RegionCode: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.LoRaConfig.RegionCode] = [ - .unset, - .us, - .eu433, - .eu868, - .cn, - .jp, - .anz, - .kr, - .tw, - .ru, - .in, - .nz865, - .th, - .lora24, - .ua433, - .ua868, - .my433, - .my919, - .sg923, - .ph433, - .ph868, - .ph915, - .anz433, - .kz433, - .kz863, - .np865, - .br902, - ] -} - -extension Config.LoRaConfig.ModemPreset: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.LoRaConfig.ModemPreset] = [ - .longFast, - .longSlow, - .veryLongSlow, - .mediumSlow, - .mediumFast, - .shortSlow, - .shortFast, - .longModerate, - .shortTurbo, - ] -} - -extension Config.BluetoothConfig.PairingMode: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.BluetoothConfig.PairingMode] = [ - .randomPin, - .fixedPin, - .noPin, - ] -} - -#endif // swift(>=4.2) - -#if swift(>=5.5) && canImport(_Concurrency) -extension Config: @unchecked Sendable {} -extension Config.OneOf_PayloadVariant: @unchecked Sendable {} -extension Config.DeviceConfig: @unchecked Sendable {} -extension Config.DeviceConfig.Role: @unchecked Sendable {} -extension Config.DeviceConfig.RebroadcastMode: @unchecked Sendable {} -extension Config.DeviceConfig.BuzzerMode: @unchecked Sendable {} -extension Config.PositionConfig: @unchecked Sendable {} -extension Config.PositionConfig.PositionFlags: @unchecked Sendable {} -extension Config.PositionConfig.GpsMode: @unchecked Sendable {} -extension Config.PowerConfig: @unchecked Sendable {} -extension Config.NetworkConfig: @unchecked Sendable {} -extension Config.NetworkConfig.AddressMode: @unchecked Sendable {} -extension Config.NetworkConfig.ProtocolFlags: @unchecked Sendable {} -extension Config.NetworkConfig.IpV4Config: @unchecked Sendable {} -extension Config.DisplayConfig: @unchecked Sendable {} -extension Config.DisplayConfig.DeprecatedGpsCoordinateFormat: @unchecked Sendable {} -extension Config.DisplayConfig.DisplayUnits: @unchecked Sendable {} -extension Config.DisplayConfig.OledType: @unchecked Sendable {} -extension Config.DisplayConfig.DisplayMode: @unchecked Sendable {} -extension Config.DisplayConfig.CompassOrientation: @unchecked Sendable {} -extension Config.LoRaConfig: @unchecked Sendable {} -extension Config.LoRaConfig.RegionCode: @unchecked Sendable {} -extension Config.LoRaConfig.ModemPreset: @unchecked Sendable {} -extension Config.BluetoothConfig: @unchecked Sendable {} -extension Config.BluetoothConfig.PairingMode: @unchecked Sendable {} -extension Config.SecurityConfig: @unchecked Sendable {} -extension Config.SessionkeyConfig: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Config" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "device"), - 2: .same(proto: "position"), - 3: .same(proto: "power"), - 4: .same(proto: "network"), - 5: .same(proto: "display"), - 6: .same(proto: "lora"), - 7: .same(proto: "bluetooth"), - 8: .same(proto: "security"), - 9: .same(proto: "sessionkey"), - 10: .standard(proto: "device_ui"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}device\0\u{1}position\0\u{1}power\0\u{1}network\0\u{1}display\0\u{1}lora\0\u{1}bluetooth\0\u{1}security\0\u{1}sessionkey\0\u{3}device_ui\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2234,20 +2139,7 @@ extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = Config.protoMessageName + ".DeviceConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "role"), - 2: .standard(proto: "serial_enabled"), - 4: .standard(proto: "button_gpio"), - 5: .standard(proto: "buzzer_gpio"), - 6: .standard(proto: "rebroadcast_mode"), - 7: .standard(proto: "node_info_broadcast_secs"), - 8: .standard(proto: "double_tap_as_button_press"), - 9: .standard(proto: "is_managed"), - 10: .standard(proto: "disable_triple_click"), - 11: .same(proto: "tzdef"), - 12: .standard(proto: "led_heartbeat_disabled"), - 13: .standard(proto: "buzzer_mode"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}role\0\u{3}serial_enabled\0\u{4}\u{2}button_gpio\0\u{3}buzzer_gpio\0\u{3}rebroadcast_mode\0\u{3}node_info_broadcast_secs\0\u{3}double_tap_as_button_press\0\u{3}is_managed\0\u{3}disable_triple_click\0\u{1}tzdef\0\u{3}led_heartbeat_disabled\0\u{3}buzzer_mode\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2331,61 +2223,20 @@ extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl } extension Config.DeviceConfig.Role: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "CLIENT"), - 1: .same(proto: "CLIENT_MUTE"), - 2: .same(proto: "ROUTER"), - 3: .same(proto: "ROUTER_CLIENT"), - 4: .same(proto: "REPEATER"), - 5: .same(proto: "TRACKER"), - 6: .same(proto: "SENSOR"), - 7: .same(proto: "TAK"), - 8: .same(proto: "CLIENT_HIDDEN"), - 9: .same(proto: "LOST_AND_FOUND"), - 10: .same(proto: "TAK_TRACKER"), - 11: .same(proto: "ROUTER_LATE"), - 12: .same(proto: "CLIENT_BASE"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0CLIENT\0\u{1}CLIENT_MUTE\0\u{1}ROUTER\0\u{1}ROUTER_CLIENT\0\u{1}REPEATER\0\u{1}TRACKER\0\u{1}SENSOR\0\u{1}TAK\0\u{1}CLIENT_HIDDEN\0\u{1}LOST_AND_FOUND\0\u{1}TAK_TRACKER\0\u{1}ROUTER_LATE\0\u{1}CLIENT_BASE\0") } extension Config.DeviceConfig.RebroadcastMode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "ALL"), - 1: .same(proto: "ALL_SKIP_DECODING"), - 2: .same(proto: "LOCAL_ONLY"), - 3: .same(proto: "KNOWN_ONLY"), - 4: .same(proto: "NONE"), - 5: .same(proto: "CORE_PORTNUMS_ONLY"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0ALL\0\u{1}ALL_SKIP_DECODING\0\u{1}LOCAL_ONLY\0\u{1}KNOWN_ONLY\0\u{1}NONE\0\u{1}CORE_PORTNUMS_ONLY\0") } extension Config.DeviceConfig.BuzzerMode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "ALL_ENABLED"), - 1: .same(proto: "DISABLED"), - 2: .same(proto: "NOTIFICATIONS_ONLY"), - 3: .same(proto: "SYSTEM_ONLY"), - 4: .same(proto: "DIRECT_MSG_ONLY"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0ALL_ENABLED\0\u{1}DISABLED\0\u{1}NOTIFICATIONS_ONLY\0\u{1}SYSTEM_ONLY\0\u{1}DIRECT_MSG_ONLY\0") } extension Config.PositionConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = Config.protoMessageName + ".PositionConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "position_broadcast_secs"), - 2: .standard(proto: "position_broadcast_smart_enabled"), - 3: .standard(proto: "fixed_position"), - 4: .standard(proto: "gps_enabled"), - 5: .standard(proto: "gps_update_interval"), - 6: .standard(proto: "gps_attempt_time"), - 7: .standard(proto: "position_flags"), - 8: .standard(proto: "rx_gpio"), - 9: .standard(proto: "tx_gpio"), - 10: .standard(proto: "broadcast_smart_minimum_distance"), - 11: .standard(proto: "broadcast_smart_minimum_interval_secs"), - 12: .standard(proto: "gps_en_gpio"), - 13: .standard(proto: "gps_mode"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}position_broadcast_secs\0\u{3}position_broadcast_smart_enabled\0\u{3}fixed_position\0\u{3}gps_enabled\0\u{3}gps_update_interval\0\u{3}gps_attempt_time\0\u{3}position_flags\0\u{3}rx_gpio\0\u{3}tx_gpio\0\u{3}broadcast_smart_minimum_distance\0\u{3}broadcast_smart_minimum_interval_secs\0\u{3}gps_en_gpio\0\u{3}gps_mode\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2474,42 +2325,16 @@ extension Config.PositionConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageIm } extension Config.PositionConfig.PositionFlags: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNSET"), - 1: .same(proto: "ALTITUDE"), - 2: .same(proto: "ALTITUDE_MSL"), - 4: .same(proto: "GEOIDAL_SEPARATION"), - 8: .same(proto: "DOP"), - 16: .same(proto: "HVDOP"), - 32: .same(proto: "SATINVIEW"), - 64: .same(proto: "SEQ_NO"), - 128: .same(proto: "TIMESTAMP"), - 256: .same(proto: "HEADING"), - 512: .same(proto: "SPEED"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNSET\0\u{1}ALTITUDE\0\u{1}ALTITUDE_MSL\0\u{2}\u{2}GEOIDAL_SEPARATION\0\u{2}\u{4}DOP\0\u{2}\u{8}HVDOP\0\u{2}\u{10}SATINVIEW\0\u{2} SEQ_NO\0\u{2}@\u{1}TIMESTAMP\0\u{2}@\u{2}HEADING\0\u{2}@\u{4}SPEED\0") } extension Config.PositionConfig.GpsMode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DISABLED"), - 1: .same(proto: "ENABLED"), - 2: .same(proto: "NOT_PRESENT"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DISABLED\0\u{1}ENABLED\0\u{1}NOT_PRESENT\0") } extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = Config.protoMessageName + ".PowerConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "is_power_saving"), - 2: .standard(proto: "on_battery_shutdown_after_secs"), - 3: .standard(proto: "adc_multiplier_override"), - 4: .standard(proto: "wait_bluetooth_secs"), - 6: .standard(proto: "sds_secs"), - 7: .standard(proto: "ls_secs"), - 8: .standard(proto: "min_wake_secs"), - 9: .standard(proto: "device_battery_ina_address"), - 32: .standard(proto: "powermon_enables"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}is_power_saving\0\u{3}on_battery_shutdown_after_secs\0\u{3}adc_multiplier_override\0\u{3}wait_bluetooth_secs\0\u{4}\u{2}sds_secs\0\u{3}ls_secs\0\u{3}min_wake_secs\0\u{3}device_battery_ina_address\0\u{4}\u{17}powermon_enables\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2538,7 +2363,7 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.onBatteryShutdownAfterSecs != 0 { try visitor.visitSingularUInt32Field(value: self.onBatteryShutdownAfterSecs, fieldNumber: 2) } - if self.adcMultiplierOverride != 0 { + if self.adcMultiplierOverride.bitPattern != 0 { try visitor.visitSingularFloatField(value: self.adcMultiplierOverride, fieldNumber: 3) } if self.waitBluetoothSecs != 0 { @@ -2579,18 +2404,7 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple extension Config.NetworkConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = Config.protoMessageName + ".NetworkConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "wifi_enabled"), - 3: .standard(proto: "wifi_ssid"), - 4: .standard(proto: "wifi_psk"), - 5: .standard(proto: "ntp_server"), - 6: .standard(proto: "eth_enabled"), - 7: .standard(proto: "address_mode"), - 8: .standard(proto: "ipv4_config"), - 9: .standard(proto: "rsyslog_server"), - 10: .standard(proto: "enabled_protocols"), - 11: .standard(proto: "ipv6_enabled"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}wifi_enabled\0\u{4}\u{2}wifi_ssid\0\u{3}wifi_psk\0\u{3}ntp_server\0\u{3}eth_enabled\0\u{3}address_mode\0\u{3}ipv4_config\0\u{3}rsyslog_server\0\u{3}enabled_protocols\0\u{3}ipv6_enabled\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2668,27 +2482,16 @@ extension Config.NetworkConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImp } extension Config.NetworkConfig.AddressMode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DHCP"), - 1: .same(proto: "STATIC"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DHCP\0\u{1}STATIC\0") } extension Config.NetworkConfig.ProtocolFlags: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "NO_BROADCAST"), - 1: .same(proto: "UDP_BROADCAST"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0NO_BROADCAST\0\u{1}UDP_BROADCAST\0") } extension Config.NetworkConfig.IpV4Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = Config.NetworkConfig.protoMessageName + ".IpV4Config" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "ip"), - 2: .same(proto: "gateway"), - 3: .same(proto: "subnet"), - 4: .same(proto: "dns"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}ip\0\u{1}gateway\0\u{1}subnet\0\u{1}dns\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2733,21 +2536,7 @@ extension Config.NetworkConfig.IpV4Config: SwiftProtobuf.Message, SwiftProtobuf. extension Config.DisplayConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = Config.protoMessageName + ".DisplayConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "screen_on_secs"), - 2: .standard(proto: "gps_format"), - 3: .standard(proto: "auto_screen_carousel_secs"), - 4: .standard(proto: "compass_north_top"), - 5: .standard(proto: "flip_screen"), - 6: .same(proto: "units"), - 7: .same(proto: "oled"), - 8: .same(proto: "displaymode"), - 9: .standard(proto: "heading_bold"), - 10: .standard(proto: "wake_on_tap_or_motion"), - 11: .standard(proto: "compass_orientation"), - 12: .standard(proto: "use_12h_clock"), - 13: .standard(proto: "use_long_node_name"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}screen_on_secs\0\u{3}gps_format\0\u{3}auto_screen_carousel_secs\0\u{3}compass_north_top\0\u{3}flip_screen\0\u{1}units\0\u{1}oled\0\u{1}displaymode\0\u{3}heading_bold\0\u{3}wake_on_tap_or_motion\0\u{3}compass_orientation\0\u{3}use_12h_clock\0\u{3}use_long_node_name\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2836,72 +2625,28 @@ extension Config.DisplayConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImp } extension Config.DisplayConfig.DeprecatedGpsCoordinateFormat: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNUSED"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNUSED\0") } extension Config.DisplayConfig.DisplayUnits: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "METRIC"), - 1: .same(proto: "IMPERIAL"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0METRIC\0\u{1}IMPERIAL\0") } extension Config.DisplayConfig.OledType: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "OLED_AUTO"), - 1: .same(proto: "OLED_SSD1306"), - 2: .same(proto: "OLED_SH1106"), - 3: .same(proto: "OLED_SH1107"), - 4: .same(proto: "OLED_SH1107_128_128"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0OLED_AUTO\0\u{1}OLED_SSD1306\0\u{1}OLED_SH1106\0\u{1}OLED_SH1107\0\u{1}OLED_SH1107_128_128\0") } extension Config.DisplayConfig.DisplayMode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DEFAULT"), - 1: .same(proto: "TWOCOLOR"), - 2: .same(proto: "INVERTED"), - 3: .same(proto: "COLOR"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DEFAULT\0\u{1}TWOCOLOR\0\u{1}INVERTED\0\u{1}COLOR\0") } extension Config.DisplayConfig.CompassOrientation: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DEGREES_0"), - 1: .same(proto: "DEGREES_90"), - 2: .same(proto: "DEGREES_180"), - 3: .same(proto: "DEGREES_270"), - 4: .same(proto: "DEGREES_0_INVERTED"), - 5: .same(proto: "DEGREES_90_INVERTED"), - 6: .same(proto: "DEGREES_180_INVERTED"), - 7: .same(proto: "DEGREES_270_INVERTED"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DEGREES_0\0\u{1}DEGREES_90\0\u{1}DEGREES_180\0\u{1}DEGREES_270\0\u{1}DEGREES_0_INVERTED\0\u{1}DEGREES_90_INVERTED\0\u{1}DEGREES_180_INVERTED\0\u{1}DEGREES_270_INVERTED\0") } extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = Config.protoMessageName + ".LoRaConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "use_preset"), - 2: .standard(proto: "modem_preset"), - 3: .same(proto: "bandwidth"), - 4: .standard(proto: "spread_factor"), - 5: .standard(proto: "coding_rate"), - 6: .standard(proto: "frequency_offset"), - 7: .same(proto: "region"), - 8: .standard(proto: "hop_limit"), - 9: .standard(proto: "tx_enabled"), - 10: .standard(proto: "tx_power"), - 11: .standard(proto: "channel_num"), - 12: .standard(proto: "override_duty_cycle"), - 13: .standard(proto: "sx126x_rx_boosted_gain"), - 14: .standard(proto: "override_frequency"), - 15: .standard(proto: "pa_fan_disabled"), - 103: .standard(proto: "ignore_incoming"), - 104: .standard(proto: "ignore_mqtt"), - 105: .standard(proto: "config_ok_to_mqtt"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}use_preset\0\u{3}modem_preset\0\u{1}bandwidth\0\u{3}spread_factor\0\u{3}coding_rate\0\u{3}frequency_offset\0\u{1}region\0\u{3}hop_limit\0\u{3}tx_enabled\0\u{3}tx_power\0\u{3}channel_num\0\u{3}override_duty_cycle\0\u{3}sx126x_rx_boosted_gain\0\u{3}override_frequency\0\u{3}pa_fan_disabled\0\u{4}X\u{1}ignore_incoming\0\u{3}ignore_mqtt\0\u{3}config_ok_to_mqtt\0") fileprivate class _StorageClass { var _usePreset: Bool = false @@ -2923,15 +2668,11 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem var _ignoreMqtt: Bool = false var _configOkToMqtt: Bool = false - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} @@ -3013,7 +2754,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem if _storage._codingRate != 0 { try visitor.visitSingularUInt32Field(value: _storage._codingRate, fieldNumber: 5) } - if _storage._frequencyOffset != 0 { + if _storage._frequencyOffset.bitPattern != 0 { try visitor.visitSingularFloatField(value: _storage._frequencyOffset, fieldNumber: 6) } if _storage._region != .unset { @@ -3037,7 +2778,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem if _storage._sx126XRxBoostedGain != false { try visitor.visitSingularBoolField(value: _storage._sx126XRxBoostedGain, fieldNumber: 13) } - if _storage._overrideFrequency != 0 { + if _storage._overrideFrequency.bitPattern != 0 { try visitor.visitSingularFloatField(value: _storage._overrideFrequency, fieldNumber: 14) } if _storage._paFanDisabled != false { @@ -3089,58 +2830,16 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem } extension Config.LoRaConfig.RegionCode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNSET"), - 1: .same(proto: "US"), - 2: .same(proto: "EU_433"), - 3: .same(proto: "EU_868"), - 4: .same(proto: "CN"), - 5: .same(proto: "JP"), - 6: .same(proto: "ANZ"), - 7: .same(proto: "KR"), - 8: .same(proto: "TW"), - 9: .same(proto: "RU"), - 10: .same(proto: "IN"), - 11: .same(proto: "NZ_865"), - 12: .same(proto: "TH"), - 13: .same(proto: "LORA_24"), - 14: .same(proto: "UA_433"), - 15: .same(proto: "UA_868"), - 16: .same(proto: "MY_433"), - 17: .same(proto: "MY_919"), - 18: .same(proto: "SG_923"), - 19: .same(proto: "PH_433"), - 20: .same(proto: "PH_868"), - 21: .same(proto: "PH_915"), - 22: .same(proto: "ANZ_433"), - 23: .same(proto: "KZ_433"), - 24: .same(proto: "KZ_863"), - 25: .same(proto: "NP_865"), - 26: .same(proto: "BR_902"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNSET\0\u{1}US\0\u{1}EU_433\0\u{1}EU_868\0\u{1}CN\0\u{1}JP\0\u{1}ANZ\0\u{1}KR\0\u{1}TW\0\u{1}RU\0\u{1}IN\0\u{1}NZ_865\0\u{1}TH\0\u{1}LORA_24\0\u{1}UA_433\0\u{1}UA_868\0\u{1}MY_433\0\u{1}MY_919\0\u{1}SG_923\0\u{1}PH_433\0\u{1}PH_868\0\u{1}PH_915\0\u{1}ANZ_433\0\u{1}KZ_433\0\u{1}KZ_863\0\u{1}NP_865\0\u{1}BR_902\0") } extension Config.LoRaConfig.ModemPreset: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "LONG_FAST"), - 1: .same(proto: "LONG_SLOW"), - 2: .same(proto: "VERY_LONG_SLOW"), - 3: .same(proto: "MEDIUM_SLOW"), - 4: .same(proto: "MEDIUM_FAST"), - 5: .same(proto: "SHORT_SLOW"), - 6: .same(proto: "SHORT_FAST"), - 7: .same(proto: "LONG_MODERATE"), - 8: .same(proto: "SHORT_TURBO"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0LONG_FAST\0\u{1}LONG_SLOW\0\u{1}VERY_LONG_SLOW\0\u{1}MEDIUM_SLOW\0\u{1}MEDIUM_FAST\0\u{1}SHORT_SLOW\0\u{1}SHORT_FAST\0\u{1}LONG_MODERATE\0\u{1}SHORT_TURBO\0\u{1}LONG_TURBO\0") } extension Config.BluetoothConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = Config.protoMessageName + ".BluetoothConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "enabled"), - 2: .same(proto: "mode"), - 3: .standard(proto: "fixed_pin"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}enabled\0\u{1}mode\0\u{3}fixed_pin\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3179,24 +2878,12 @@ extension Config.BluetoothConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageI } extension Config.BluetoothConfig.PairingMode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "RANDOM_PIN"), - 1: .same(proto: "FIXED_PIN"), - 2: .same(proto: "NO_PIN"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0RANDOM_PIN\0\u{1}FIXED_PIN\0\u{1}NO_PIN\0") } extension Config.SecurityConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = Config.protoMessageName + ".SecurityConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "public_key"), - 2: .standard(proto: "private_key"), - 3: .standard(proto: "admin_key"), - 4: .standard(proto: "is_managed"), - 5: .standard(proto: "serial_enabled"), - 6: .standard(proto: "debug_log_api_enabled"), - 8: .standard(proto: "admin_channel_enabled"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}public_key\0\u{3}private_key\0\u{3}admin_key\0\u{3}is_managed\0\u{3}serial_enabled\0\u{3}debug_log_api_enabled\0\u{4}\u{2}admin_channel_enabled\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3259,8 +2946,8 @@ extension Config.SessionkeyConfig: SwiftProtobuf.Message, SwiftProtobuf._Message public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } + // Load everything into unknown fields + while try decoder.nextFieldNumber() != nil {} } public func traverse(visitor: inout V) throws { diff --git a/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift index a2ec180e..d1f1d208 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/connection_status.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct DeviceConnectionStatus { +public struct DeviceConnectionStatus: Sendable { // 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. @@ -81,7 +81,7 @@ public struct DeviceConnectionStatus { /// /// WiFi connection status -public struct WifiConnectionStatus { +public struct WifiConnectionStatus: Sendable { // 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. @@ -114,7 +114,7 @@ public struct WifiConnectionStatus { /// /// Ethernet connection status -public struct EthernetConnectionStatus { +public struct EthernetConnectionStatus: Sendable { // 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. @@ -139,7 +139,7 @@ public struct EthernetConnectionStatus { /// /// Ethernet or WiFi connection status -public struct NetworkConnectionStatus { +public struct NetworkConnectionStatus: Sendable { // 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. @@ -167,7 +167,7 @@ public struct NetworkConnectionStatus { /// /// Bluetooth connection status -public struct BluetoothConnectionStatus { +public struct BluetoothConnectionStatus: Sendable { // 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. @@ -191,7 +191,7 @@ public struct BluetoothConnectionStatus { /// /// Serial connection status -public struct SerialConnectionStatus { +public struct SerialConnectionStatus: Sendable { // 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. @@ -209,27 +209,13 @@ public struct SerialConnectionStatus { public init() {} } -#if swift(>=5.5) && canImport(_Concurrency) -extension DeviceConnectionStatus: @unchecked Sendable {} -extension WifiConnectionStatus: @unchecked Sendable {} -extension EthernetConnectionStatus: @unchecked Sendable {} -extension NetworkConnectionStatus: @unchecked Sendable {} -extension BluetoothConnectionStatus: @unchecked Sendable {} -extension SerialConnectionStatus: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension DeviceConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".DeviceConnectionStatus" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "wifi"), - 2: .same(proto: "ethernet"), - 3: .same(proto: "bluetooth"), - 4: .same(proto: "serial"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}wifi\0\u{1}ethernet\0\u{1}bluetooth\0\u{1}serial\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -278,11 +264,7 @@ extension DeviceConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageI extension WifiConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".WifiConnectionStatus" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "status"), - 2: .same(proto: "ssid"), - 3: .same(proto: "rssi"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}status\0\u{1}ssid\0\u{1}rssi\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -326,9 +308,7 @@ extension WifiConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImp extension EthernetConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".EthernetConnectionStatus" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "status"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}status\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -362,12 +342,7 @@ extension EthernetConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Messag extension NetworkConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".NetworkConnectionStatus" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "ip_address"), - 2: .standard(proto: "is_connected"), - 3: .standard(proto: "is_mqtt_connected"), - 4: .standard(proto: "is_syslog_connected"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}ip_address\0\u{3}is_connected\0\u{3}is_mqtt_connected\0\u{3}is_syslog_connected\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -412,11 +387,7 @@ extension NetworkConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Message extension BluetoothConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".BluetoothConnectionStatus" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "pin"), - 2: .same(proto: "rssi"), - 3: .standard(proto: "is_connected"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}pin\0\u{1}rssi\0\u{3}is_connected\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -456,10 +427,7 @@ extension BluetoothConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Messa extension SerialConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".SerialConnectionStatus" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "baud"), - 2: .standard(proto: "is_connected"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}baud\0\u{3}is_connected\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift index 4f049e79..327e356d 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/device_ui.proto @@ -20,7 +21,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum CompassMode: SwiftProtobuf.Enum { +public enum CompassMode: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -58,22 +59,16 @@ public enum CompassMode: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension CompassMode: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [CompassMode] = [ .dynamic, .fixedRing, .freezeHeading, ] + } -#endif // swift(>=4.2) - -public enum Theme: SwiftProtobuf.Enum { +public enum Theme: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -111,24 +106,18 @@ public enum Theme: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension Theme: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Theme] = [ .dark, .light, .red, ] -} -#endif // swift(>=4.2) +} /// /// Localization -public enum Language: SwiftProtobuf.Enum { +public enum Language: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -280,11 +269,6 @@ public enum Language: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension Language: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Language] = [ .english, @@ -310,11 +294,10 @@ extension Language: CaseIterable { .simplifiedChinese, .traditionalChinese, ] + } -#endif // swift(>=4.2) - -public struct DeviceUIConfig { +public struct DeviceUIConfig: @unchecked Sendable { // 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. @@ -462,7 +445,7 @@ public struct DeviceUIConfig { /// /// How the GPS coordinates are displayed on the OLED screen. - public enum GpsCoordinateFormat: SwiftProtobuf.Enum { + public enum GpsCoordinateFormat: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -532,6 +515,17 @@ public struct DeviceUIConfig { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [DeviceUIConfig.GpsCoordinateFormat] = [ + .dec, + .dms, + .utm, + .mgrs, + .olc, + .osgr, + .mls, + ] + } public init() {} @@ -539,24 +533,7 @@ public struct DeviceUIConfig { fileprivate var _storage = _StorageClass.defaultInstance } -#if swift(>=4.2) - -extension DeviceUIConfig.GpsCoordinateFormat: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [DeviceUIConfig.GpsCoordinateFormat] = [ - .dec, - .dms, - .utm, - .mgrs, - .olc, - .osgr, - .mls, - ] -} - -#endif // swift(>=4.2) - -public struct NodeFilter { +public struct NodeFilter: Sendable { // 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. @@ -594,7 +571,7 @@ public struct NodeFilter { public init() {} } -public struct NodeHighlight { +public struct NodeHighlight: Sendable { // 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. @@ -624,7 +601,7 @@ public struct NodeHighlight { public init() {} } -public struct GeoPoint { +public struct GeoPoint: Sendable { // 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. @@ -646,7 +623,7 @@ public struct GeoPoint { public init() {} } -public struct Map { +public struct Map: Sendable { // 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. @@ -677,88 +654,25 @@ public struct Map { fileprivate var _home: GeoPoint? = nil } -#if swift(>=5.5) && canImport(_Concurrency) -extension CompassMode: @unchecked Sendable {} -extension Theme: @unchecked Sendable {} -extension Language: @unchecked Sendable {} -extension DeviceUIConfig: @unchecked Sendable {} -extension DeviceUIConfig.GpsCoordinateFormat: @unchecked Sendable {} -extension NodeFilter: @unchecked Sendable {} -extension NodeHighlight: @unchecked Sendable {} -extension GeoPoint: @unchecked Sendable {} -extension Map: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension CompassMode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DYNAMIC"), - 1: .same(proto: "FIXED_RING"), - 2: .same(proto: "FREEZE_HEADING"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DYNAMIC\0\u{1}FIXED_RING\0\u{1}FREEZE_HEADING\0") } extension Theme: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DARK"), - 1: .same(proto: "LIGHT"), - 2: .same(proto: "RED"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DARK\0\u{1}LIGHT\0\u{1}RED\0") } extension Language: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "ENGLISH"), - 1: .same(proto: "FRENCH"), - 2: .same(proto: "GERMAN"), - 3: .same(proto: "ITALIAN"), - 4: .same(proto: "PORTUGUESE"), - 5: .same(proto: "SPANISH"), - 6: .same(proto: "SWEDISH"), - 7: .same(proto: "FINNISH"), - 8: .same(proto: "POLISH"), - 9: .same(proto: "TURKISH"), - 10: .same(proto: "SERBIAN"), - 11: .same(proto: "RUSSIAN"), - 12: .same(proto: "DUTCH"), - 13: .same(proto: "GREEK"), - 14: .same(proto: "NORWEGIAN"), - 15: .same(proto: "SLOVENIAN"), - 16: .same(proto: "UKRAINIAN"), - 17: .same(proto: "BULGARIAN"), - 18: .same(proto: "CZECH"), - 19: .same(proto: "DANISH"), - 30: .same(proto: "SIMPLIFIED_CHINESE"), - 31: .same(proto: "TRADITIONAL_CHINESE"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0ENGLISH\0\u{1}FRENCH\0\u{1}GERMAN\0\u{1}ITALIAN\0\u{1}PORTUGUESE\0\u{1}SPANISH\0\u{1}SWEDISH\0\u{1}FINNISH\0\u{1}POLISH\0\u{1}TURKISH\0\u{1}SERBIAN\0\u{1}RUSSIAN\0\u{1}DUTCH\0\u{1}GREEK\0\u{1}NORWEGIAN\0\u{1}SLOVENIAN\0\u{1}UKRAINIAN\0\u{1}BULGARIAN\0\u{1}CZECH\0\u{1}DANISH\0\u{2}\u{b}SIMPLIFIED_CHINESE\0\u{1}TRADITIONAL_CHINESE\0") } extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".DeviceUIConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "version"), - 2: .standard(proto: "screen_brightness"), - 3: .standard(proto: "screen_timeout"), - 4: .standard(proto: "screen_lock"), - 5: .standard(proto: "settings_lock"), - 6: .standard(proto: "pin_code"), - 7: .same(proto: "theme"), - 8: .standard(proto: "alert_enabled"), - 9: .standard(proto: "banner_enabled"), - 10: .standard(proto: "ring_tone_id"), - 11: .same(proto: "language"), - 12: .standard(proto: "node_filter"), - 13: .standard(proto: "node_highlight"), - 14: .standard(proto: "calibration_data"), - 15: .standard(proto: "map_data"), - 16: .standard(proto: "compass_mode"), - 17: .standard(proto: "screen_rgb_color"), - 18: .standard(proto: "is_clockface_analog"), - 19: .standard(proto: "gps_format"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}version\0\u{3}screen_brightness\0\u{3}screen_timeout\0\u{3}screen_lock\0\u{3}settings_lock\0\u{3}pin_code\0\u{1}theme\0\u{3}alert_enabled\0\u{3}banner_enabled\0\u{3}ring_tone_id\0\u{1}language\0\u{3}node_filter\0\u{3}node_highlight\0\u{3}calibration_data\0\u{3}map_data\0\u{3}compass_mode\0\u{3}screen_rgb_color\0\u{3}is_clockface_analog\0\u{3}gps_format\0") fileprivate class _StorageClass { var _version: UInt32 = 0 @@ -781,15 +695,11 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement var _isClockfaceAnalog: Bool = false var _gpsFormat: DeviceUIConfig.GpsCoordinateFormat = .dec - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} @@ -957,28 +867,12 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement } extension DeviceUIConfig.GpsCoordinateFormat: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DEC"), - 1: .same(proto: "DMS"), - 2: .same(proto: "UTM"), - 3: .same(proto: "MGRS"), - 4: .same(proto: "OLC"), - 5: .same(proto: "OSGR"), - 6: .same(proto: "MLS"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DEC\0\u{1}DMS\0\u{1}UTM\0\u{1}MGRS\0\u{1}OLC\0\u{1}OSGR\0\u{1}MLS\0") } extension NodeFilter: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".NodeFilter" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "unknown_switch"), - 2: .standard(proto: "offline_switch"), - 3: .standard(proto: "public_key_switch"), - 4: .standard(proto: "hops_away"), - 5: .standard(proto: "position_switch"), - 6: .standard(proto: "node_name"), - 7: .same(proto: "channel"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}unknown_switch\0\u{3}offline_switch\0\u{3}public_key_switch\0\u{3}hops_away\0\u{3}position_switch\0\u{3}node_name\0\u{1}channel\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -1038,13 +932,7 @@ extension NodeFilter: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio extension NodeHighlight: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".NodeHighlight" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "chat_switch"), - 2: .standard(proto: "position_switch"), - 3: .standard(proto: "telemetry_switch"), - 4: .standard(proto: "iaq_switch"), - 5: .standard(proto: "node_name"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}chat_switch\0\u{3}position_switch\0\u{3}telemetry_switch\0\u{3}iaq_switch\0\u{3}node_name\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -1094,11 +982,7 @@ extension NodeHighlight: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa extension GeoPoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".GeoPoint" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "zoom"), - 2: .same(proto: "latitude"), - 3: .same(proto: "longitude"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}zoom\0\u{1}latitude\0\u{1}longitude\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -1138,11 +1022,7 @@ extension GeoPoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB extension Map: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Map" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "home"), - 2: .same(proto: "style"), - 3: .standard(proto: "follow_gps"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}home\0\u{1}style\0\u{3}follow_gps\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift index 9c8d5ad8..281f18d8 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/deviceonly.proto @@ -22,7 +23,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Position with static location information only for NodeDBLite -public struct PositionLite { +public struct PositionLite: Sendable { // 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. @@ -57,13 +58,15 @@ public struct PositionLite { public init() {} } -public struct UserLite { +public struct UserLite: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. /// /// This is the addr of the radio. + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var macaddr: Data = Data() /// @@ -115,7 +118,7 @@ public struct UserLite { fileprivate var _isUnmessagable: Bool? = nil } -public struct NodeInfoLite { +public struct NodeInfoLite: @unchecked Sendable { // 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. @@ -245,7 +248,7 @@ public struct NodeInfoLite { /// FIXME, since we write this each time we enter deep sleep (and have infinite /// flash) it would be better to use some sort of append only data structure for /// the receive queue and use the preferences store for the other stuff -public struct DeviceState { +public struct DeviceState: @unchecked Sendable { // 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. @@ -305,6 +308,8 @@ public struct DeviceState { /// Used only during development. /// Indicates developer is testing and changes should never be saved to flash. /// Deprecated in 2.3.1 + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var noSave: Bool { get {return _storage._noSave} set {_uniqueStorage()._noSave = newValue} @@ -313,6 +318,8 @@ public struct DeviceState { /// /// Previously used to manage GPS factory resets. /// Deprecated in 2.5.23 + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var didGpsReset: Bool { get {return _storage._didGpsReset} set {_uniqueStorage()._didGpsReset = newValue} @@ -345,7 +352,7 @@ public struct DeviceState { fileprivate var _storage = _StorageClass.defaultInstance } -public struct NodeDatabase { +public struct NodeDatabase: Sendable { // 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. @@ -367,7 +374,7 @@ public struct NodeDatabase { /// /// The on-disk saved channels -public struct ChannelFile { +public struct ChannelFile: Sendable { // 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. @@ -389,7 +396,7 @@ public struct ChannelFile { /// /// The on-disk backup of the node's preferences -public struct BackupPreferences { +public struct BackupPreferences: Sendable { // 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. @@ -456,29 +463,13 @@ public struct BackupPreferences { fileprivate var _owner: User? = nil } -#if swift(>=5.5) && canImport(_Concurrency) -extension PositionLite: @unchecked Sendable {} -extension UserLite: @unchecked Sendable {} -extension NodeInfoLite: @unchecked Sendable {} -extension DeviceState: @unchecked Sendable {} -extension NodeDatabase: @unchecked Sendable {} -extension ChannelFile: @unchecked Sendable {} -extension BackupPreferences: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension PositionLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".PositionLite" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "latitude_i"), - 2: .standard(proto: "longitude_i"), - 3: .same(proto: "altitude"), - 4: .same(proto: "time"), - 5: .standard(proto: "location_source"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}latitude_i\0\u{3}longitude_i\0\u{1}altitude\0\u{1}time\0\u{3}location_source\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -528,16 +519,7 @@ extension PositionLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat extension UserLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".UserLite" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "macaddr"), - 2: .standard(proto: "long_name"), - 3: .standard(proto: "short_name"), - 4: .standard(proto: "hw_model"), - 5: .standard(proto: "is_licensed"), - 6: .same(proto: "role"), - 7: .standard(proto: "public_key"), - 9: .standard(proto: "is_unmessagable"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}macaddr\0\u{3}long_name\0\u{3}short_name\0\u{3}hw_model\0\u{3}is_licensed\0\u{1}role\0\u{3}public_key\0\u{4}\u{2}is_unmessagable\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -606,21 +588,7 @@ extension UserLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".NodeInfoLite" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "num"), - 2: .same(proto: "user"), - 3: .same(proto: "position"), - 4: .same(proto: "snr"), - 5: .standard(proto: "last_heard"), - 6: .standard(proto: "device_metrics"), - 7: .same(proto: "channel"), - 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"), - 13: .same(proto: "bitfield"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}num\0\u{1}user\0\u{1}position\0\u{1}snr\0\u{3}last_heard\0\u{3}device_metrics\0\u{1}channel\0\u{3}via_mqtt\0\u{3}hops_away\0\u{3}is_favorite\0\u{3}is_ignored\0\u{3}next_hop\0\u{1}bitfield\0") fileprivate class _StorageClass { var _num: UInt32 = 0 @@ -637,15 +605,11 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat var _nextHop: UInt32 = 0 var _bitfield: UInt32 = 0 - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} @@ -715,7 +679,7 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat try { if let v = _storage._position { try visitor.visitSingularMessageField(value: v, fieldNumber: 3) } }() - if _storage._snr != 0 { + if _storage._snr.bitPattern != 0 { try visitor.visitSingularFloatField(value: _storage._snr, fieldNumber: 4) } if _storage._lastHeard != 0 { @@ -778,17 +742,7 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".DeviceState" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 2: .standard(proto: "my_node"), - 3: .same(proto: "owner"), - 5: .standard(proto: "receive_queue"), - 8: .same(proto: "version"), - 7: .standard(proto: "rx_text_message"), - 9: .standard(proto: "no_save"), - 11: .standard(proto: "did_gps_reset"), - 12: .standard(proto: "rx_waypoint"), - 13: .standard(proto: "node_remote_hardware_pins"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{4}\u{2}my_node\0\u{1}owner\0\u{4}\u{2}receive_queue\0\u{4}\u{2}rx_text_message\0\u{1}version\0\u{3}no_save\0\u{4}\u{2}did_gps_reset\0\u{3}rx_waypoint\0\u{3}node_remote_hardware_pins\0") fileprivate class _StorageClass { var _myNode: MyNodeInfo? = nil @@ -801,15 +755,11 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati var _rxWaypoint: MeshPacket? = nil var _nodeRemoteHardwarePins: [NodeRemoteHardwarePin] = [] - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} @@ -918,10 +868,7 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati extension NodeDatabase: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".NodeDatabase" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "version"), - 2: .same(proto: "nodes"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}version\0\u{1}nodes\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -956,10 +903,7 @@ extension NodeDatabase: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat extension ChannelFile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ChannelFile" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "channels"), - 2: .same(proto: "version"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}channels\0\u{1}version\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -994,14 +938,7 @@ extension ChannelFile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati extension BackupPreferences: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".BackupPreferences" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "version"), - 2: .same(proto: "timestamp"), - 3: .same(proto: "config"), - 4: .standard(proto: "module_config"), - 5: .same(proto: "channels"), - 6: .same(proto: "owner"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}version\0\u{1}timestamp\0\u{1}config\0\u{3}module_config\0\u{1}channels\0\u{1}owner\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift index 92b72c15..3e28112d 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/interdevice.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum MessageType: SwiftProtobuf.Enum { +public enum MessageType: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int case ack // = 0 @@ -82,11 +82,6 @@ public enum MessageType: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension MessageType: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [MessageType] = [ .ack, @@ -102,11 +97,10 @@ extension MessageType: CaseIterable { .aht20Humidity, .tvocIndex, ] + } -#endif // swift(>=4.2) - -public struct SensorData { +public struct SensorData: Sendable { // 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. @@ -136,34 +130,16 @@ public struct SensorData { public var unknownFields = SwiftProtobuf.UnknownStorage() /// The sensor data, either as a float or an uint32 - public enum OneOf_Data: Equatable { + public enum OneOf_Data: Equatable, Sendable { case floatValue(Float) case uint32Value(UInt32) - #if !swift(>=4.1) - public static func ==(lhs: SensorData.OneOf_Data, rhs: SensorData.OneOf_Data) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.floatValue, .floatValue): return { - guard case .floatValue(let l) = lhs, case .floatValue(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.uint32Value, .uint32Value): return { - guard case .uint32Value(let l) = lhs, case .uint32Value(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } public init() {} } -public struct InterdeviceMessage { +public struct InterdeviceMessage: Sendable { // 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. @@ -190,69 +166,26 @@ public struct InterdeviceMessage { public var unknownFields = SwiftProtobuf.UnknownStorage() /// The message data - public enum OneOf_Data: Equatable { + public enum OneOf_Data: Equatable, Sendable { case nmea(String) case sensor(SensorData) - #if !swift(>=4.1) - public static func ==(lhs: InterdeviceMessage.OneOf_Data, rhs: InterdeviceMessage.OneOf_Data) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.nmea, .nmea): return { - guard case .nmea(let l) = lhs, case .nmea(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.sensor, .sensor): return { - guard case .sensor(let l) = lhs, case .sensor(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } public init() {} } -#if swift(>=5.5) && canImport(_Concurrency) -extension MessageType: @unchecked Sendable {} -extension SensorData: @unchecked Sendable {} -extension SensorData.OneOf_Data: @unchecked Sendable {} -extension InterdeviceMessage: @unchecked Sendable {} -extension InterdeviceMessage.OneOf_Data: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension MessageType: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "ACK"), - 160: .same(proto: "COLLECT_INTERVAL"), - 161: .same(proto: "BEEP_ON"), - 162: .same(proto: "BEEP_OFF"), - 163: .same(proto: "SHUTDOWN"), - 164: .same(proto: "POWER_ON"), - 176: .same(proto: "SCD41_TEMP"), - 177: .same(proto: "SCD41_HUMIDITY"), - 178: .same(proto: "SCD41_CO2"), - 179: .same(proto: "AHT20_TEMP"), - 180: .same(proto: "AHT20_HUMIDITY"), - 181: .same(proto: "TVOC_INDEX"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0ACK\0\u{2}`\u{2}COLLECT_INTERVAL\0\u{1}BEEP_ON\0\u{1}BEEP_OFF\0\u{1}SHUTDOWN\0\u{1}POWER_ON\0\u{2}\u{c}SCD41_TEMP\0\u{1}SCD41_HUMIDITY\0\u{1}SCD41_CO2\0\u{1}AHT20_TEMP\0\u{1}AHT20_HUMIDITY\0\u{1}TVOC_INDEX\0") } extension SensorData: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".SensorData" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "type"), - 2: .standard(proto: "float_value"), - 3: .standard(proto: "uint32_value"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}type\0\u{3}float_value\0\u{3}uint32_value\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -314,10 +247,7 @@ extension SensorData: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio extension InterdeviceMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".InterdeviceMessage" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "nmea"), - 2: .same(proto: "sensor"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}nmea\0\u{1}sensor\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift index 0af27466..9ba9dd88 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/localonly.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct LocalConfig { +public struct LocalConfig: @unchecked Sendable { // 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. @@ -129,7 +129,7 @@ public struct LocalConfig { fileprivate var _storage = _StorageClass.defaultInstance } -public struct LocalModuleConfig { +public struct LocalModuleConfig: @unchecked Sendable { // 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. @@ -293,28 +293,13 @@ public struct LocalModuleConfig { fileprivate var _storage = _StorageClass.defaultInstance } -#if swift(>=5.5) && canImport(_Concurrency) -extension LocalConfig: @unchecked Sendable {} -extension LocalModuleConfig: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".LocalConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "device"), - 2: .same(proto: "position"), - 3: .same(proto: "power"), - 4: .same(proto: "network"), - 5: .same(proto: "display"), - 6: .same(proto: "lora"), - 7: .same(proto: "bluetooth"), - 8: .same(proto: "version"), - 9: .same(proto: "security"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}device\0\u{1}position\0\u{1}power\0\u{1}network\0\u{1}display\0\u{1}lora\0\u{1}bluetooth\0\u{1}version\0\u{1}security\0") fileprivate class _StorageClass { var _device: Config.DeviceConfig? = nil @@ -327,15 +312,11 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati var _version: UInt32 = 0 var _security: Config.SecurityConfig? = nil - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} @@ -444,22 +425,7 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati extension LocalModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".LocalModuleConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "mqtt"), - 2: .same(proto: "serial"), - 3: .standard(proto: "external_notification"), - 4: .standard(proto: "store_forward"), - 5: .standard(proto: "range_test"), - 6: .same(proto: "telemetry"), - 7: .standard(proto: "canned_message"), - 9: .same(proto: "audio"), - 10: .standard(proto: "remote_hardware"), - 11: .standard(proto: "neighbor_info"), - 12: .standard(proto: "ambient_lighting"), - 13: .standard(proto: "detection_sensor"), - 14: .same(proto: "paxcounter"), - 8: .same(proto: "version"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}mqtt\0\u{1}serial\0\u{3}external_notification\0\u{3}store_forward\0\u{3}range_test\0\u{1}telemetry\0\u{3}canned_message\0\u{1}version\0\u{1}audio\0\u{3}remote_hardware\0\u{3}neighbor_info\0\u{3}ambient_lighting\0\u{3}detection_sensor\0\u{1}paxcounter\0") fileprivate class _StorageClass { var _mqtt: ModuleConfig.MQTTConfig? = nil @@ -477,15 +443,11 @@ extension LocalModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem var _paxcounter: ModuleConfig.PaxcounterConfig? = nil var _version: UInt32 = 0 - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} diff --git a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift index c32dfb49..477e2457 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/mesh.proto @@ -25,7 +26,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// bin/build-all.sh script. /// Because they will be used to find firmware filenames in the android app for OTA updates. /// To match the old style filenames, _ is converted to -, p is converted to . -public enum HardwareModel: SwiftProtobuf.Enum { +public enum HardwareModel: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -422,8 +423,8 @@ public enum HardwareModel: SwiftProtobuf.Enum { case heltecSensorHub // = 92 /// - /// Reserved Fried Chicken ID for future use - case reservedFriedChicken // = 93 + /// Muzi Works Muzi-Base device + case muziBase // = 93 /// /// Heltec Magnetic Power Bank with Meshtastic compatible @@ -510,6 +511,30 @@ public enum HardwareModel: SwiftProtobuf.Enum { /// LilyGo T-Watch Ultra case tWatchUltra // = 114 + /// + /// Elecrow ThinkNode M3 + case thinknodeM3 // = 115 + + /// + /// RAK WISMESH_TAP_V2 with ESP32-S3 CPU + case wismeshTapV2 // = 116 + + /// + /// RAK3401 + case rak3401 // = 117 + + /// + /// RAK6421 Hat+ + case rak6421 // = 118 + + /// + /// Elecrow ThinkNode M4 + case thinknodeM4 // = 119 + + /// + /// Elecrow ThinkNode M6 + case thinknodeM6 // = 120 + /// /// ------------------------------------------------------------------------------------------------------------------------------------------ /// 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. @@ -616,7 +641,7 @@ public enum HardwareModel: SwiftProtobuf.Enum { case 90: self = .thinknodeM2 case 91: self = .tEthElite case 92: self = .heltecSensorHub - case 93: self = .reservedFriedChicken + case 93: self = .muziBase case 94: self = .heltecMeshPocket case 95: self = .seeedSolarNode case 96: self = .nomadstarMeteorPro @@ -638,6 +663,12 @@ public enum HardwareModel: SwiftProtobuf.Enum { case 112: self = .m5StackCardputerAdv case 113: self = .heltecWirelessTrackerV2 case 114: self = .tWatchUltra + case 115: self = .thinknodeM3 + case 116: self = .wismeshTapV2 + case 117: self = .rak3401 + case 118: self = .rak6421 + case 119: self = .thinknodeM4 + case 120: self = .thinknodeM6 case 255: self = .privateHw default: self = .UNRECOGNIZED(rawValue) } @@ -738,7 +769,7 @@ public enum HardwareModel: SwiftProtobuf.Enum { case .thinknodeM2: return 90 case .tEthElite: return 91 case .heltecSensorHub: return 92 - case .reservedFriedChicken: return 93 + case .muziBase: return 93 case .heltecMeshPocket: return 94 case .seeedSolarNode: return 95 case .nomadstarMeteorPro: return 96 @@ -760,16 +791,17 @@ public enum HardwareModel: SwiftProtobuf.Enum { case .m5StackCardputerAdv: return 112 case .heltecWirelessTrackerV2: return 113 case .tWatchUltra: return 114 + case .thinknodeM3: return 115 + case .wismeshTapV2: return 116 + case .rak3401: return 117 + case .rak6421: return 118 + case .thinknodeM4: return 119 + case .thinknodeM6: return 120 case .privateHw: return 255 case .UNRECOGNIZED(let i): return i } } -} - -#if swift(>=4.2) - -extension HardwareModel: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [HardwareModel] = [ .unset, @@ -865,7 +897,7 @@ extension HardwareModel: CaseIterable { .thinknodeM2, .tEthElite, .heltecSensorHub, - .reservedFriedChicken, + .muziBase, .heltecMeshPocket, .seeedSolarNode, .nomadstarMeteorPro, @@ -887,15 +919,20 @@ extension HardwareModel: CaseIterable { .m5StackCardputerAdv, .heltecWirelessTrackerV2, .tWatchUltra, + .thinknodeM3, + .wismeshTapV2, + .rak3401, + .rak6421, + .thinknodeM4, + .thinknodeM6, .privateHw, ] -} -#endif // swift(>=4.2) +} /// /// Shared constants between device and phone -public enum Constants: SwiftProtobuf.Enum { +public enum Constants: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -930,26 +967,20 @@ public enum Constants: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension Constants: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Constants] = [ .zero, .dataPayloadLen, ] -} -#endif // swift(>=4.2) +} /// /// Error codes for critical errors /// The device might report these fault codes on the screen. /// If you encounter a fault code, please post on the meshtastic.discourse.group /// and we'll try to help. -public enum CriticalErrorCode: SwiftProtobuf.Enum { +public enum CriticalErrorCode: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1058,11 +1089,6 @@ public enum CriticalErrorCode: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension CriticalErrorCode: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [CriticalErrorCode] = [ .none, @@ -1080,14 +1106,13 @@ extension CriticalErrorCode: CaseIterable { .flashCorruptionRecoverable, .flashCorruptionUnrecoverable, ] -} -#endif // swift(>=4.2) +} /// /// Enum to indicate to clients whether this firmware is a special firmware build, like an event. /// The first 16 values are reserved for non-event special firmwares, like the Smart Citizen use case. -public enum FirmwareEdition: SwiftProtobuf.Enum { +public enum FirmwareEdition: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1149,11 +1174,6 @@ public enum FirmwareEdition: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension FirmwareEdition: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [FirmwareEdition] = [ .vanilla, @@ -1164,15 +1184,14 @@ extension FirmwareEdition: CaseIterable { .hamvention, .diyEdition, ] -} -#endif // swift(>=4.2) +} /// /// Enum for modules excluded from a device's configuration. /// Each value represents a ModuleConfigType that can be toggled as excluded /// by setting its corresponding bit in the `excluded_modules` bitmask field. -public enum ExcludedModules: SwiftProtobuf.Enum { +public enum ExcludedModules: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1288,11 +1307,6 @@ public enum ExcludedModules: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension ExcludedModules: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [ExcludedModules] = [ .excludedNone, @@ -1312,13 +1326,12 @@ extension ExcludedModules: CaseIterable { .bluetoothConfig, .networkConfig, ] -} -#endif // swift(>=4.2) +} /// /// A GPS Position -public struct Position { +public struct Position: @unchecked Sendable { // 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. @@ -1535,7 +1548,7 @@ public struct Position { /// /// How the location was acquired: manual, onboard GPS, external (EUD) GPS - public enum LocSource: SwiftProtobuf.Enum { + public enum LocSource: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1579,12 +1592,20 @@ public struct Position { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Position.LocSource] = [ + .locUnset, + .locManual, + .locInternal, + .locExternal, + ] + } /// /// How the altitude was acquired: manual, GPS int/ext, etc /// Default: same as location_source if present - public enum AltSource: SwiftProtobuf.Enum { + public enum AltSource: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1634,6 +1655,15 @@ public struct Position { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Position.AltSource] = [ + .altUnset, + .altManual, + .altInternal, + .altExternal, + .altBarometric, + ] + } public init() {} @@ -1641,31 +1671,6 @@ public struct Position { fileprivate var _storage = _StorageClass.defaultInstance } -#if swift(>=4.2) - -extension Position.LocSource: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Position.LocSource] = [ - .locUnset, - .locManual, - .locInternal, - .locExternal, - ] -} - -extension Position.AltSource: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Position.AltSource] = [ - .altUnset, - .altManual, - .altInternal, - .altExternal, - .altBarometric, - ] -} - -#endif // swift(>=4.2) - /// /// Broadcast when a newly powered mesh node wants to find a node num it can use /// Sent from the phone over bluetooth to set the user id for the owner of this node. @@ -1687,7 +1692,7 @@ extension Position.AltSource: CaseIterable { /// A few nodenums are reserved and will never be requested: /// 0xff - broadcast /// 0 through 3 - for future use -public struct User { +public struct User: Sendable { // 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. @@ -1712,6 +1717,8 @@ public struct User { /// Deprecated in Meshtastic 2.1.x /// This is the addr of the radio. /// Not populated by the phone, but added by the esp32 when broadcasting + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var macaddr: Data = Data() /// @@ -1756,7 +1763,7 @@ public struct User { /// /// A message used in a traceroute -public struct RouteDiscovery { +public struct RouteDiscovery: Sendable { // 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. @@ -1784,7 +1791,7 @@ public struct RouteDiscovery { /// /// A Routing control Data packet handled by the routing module -public struct Routing { +public struct Routing: Sendable { // 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. @@ -1824,7 +1831,7 @@ public struct Routing { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_Variant: Equatable { + public enum OneOf_Variant: Equatable, Sendable { /// /// A route request going from the requester case routeRequest(RouteDiscovery) @@ -1836,34 +1843,12 @@ public struct Routing { /// in addition to ack.fail_id to provide details on the type of failure). case errorReason(Routing.Error) - #if !swift(>=4.1) - public static func ==(lhs: Routing.OneOf_Variant, rhs: Routing.OneOf_Variant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.routeRequest, .routeRequest): return { - guard case .routeRequest(let l) = lhs, case .routeRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.routeReply, .routeReply): return { - guard case .routeReply(let l) = lhs, case .routeReply(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.errorReason, .errorReason): return { - guard case .errorReason(let l) = lhs, case .errorReason(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } /// /// A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide /// details on the type of failure). - public enum Error: SwiftProtobuf.Enum { + public enum Error: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1988,43 +1973,37 @@ public struct Routing { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Routing.Error] = [ + .none, + .noRoute, + .gotNak, + .timeout, + .noInterface, + .maxRetransmit, + .noChannel, + .tooLarge, + .noResponse, + .dutyCycleLimit, + .badRequest, + .notAuthorized, + .pkiFailed, + .pkiUnknownPubkey, + .adminBadSessionKey, + .adminPublicKeyUnauthorized, + .rateLimitExceeded, + ] + } public init() {} } -#if swift(>=4.2) - -extension Routing.Error: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Routing.Error] = [ - .none, - .noRoute, - .gotNak, - .timeout, - .noInterface, - .maxRetransmit, - .noChannel, - .tooLarge, - .noResponse, - .dutyCycleLimit, - .badRequest, - .notAuthorized, - .pkiFailed, - .pkiUnknownPubkey, - .adminBadSessionKey, - .adminPublicKeyUnauthorized, - .rateLimitExceeded, - ] -} - -#endif // swift(>=4.2) - /// /// (Formerly called SubPacket) /// The payload portion fo a packet, this is the actual bytes that are sent /// inside a radio packet (because from/to are broken out by the comms library) -public struct DataMessage { +public struct DataMessage: Sendable { // 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. @@ -2091,7 +2070,7 @@ public struct DataMessage { /// /// The actual over-the-mesh message doing KeyVerification -public struct KeyVerification { +public struct KeyVerification: Sendable { // 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. @@ -2114,9 +2093,127 @@ public struct KeyVerification { public init() {} } +/// +/// The actual over-the-mesh message doing store and forward++ +public struct StoreForwardPlusPlus: Sendable { + // 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. + + /// + /// Which message type is this + public var sfppMessageType: StoreForwardPlusPlus.SFPP_message_type = .canonAnnounce + + /// + /// The hash of the specific message + public var messageHash: Data = Data() + + /// + /// The hash of a link on a chain + public var commitHash: Data = Data() + + /// + /// the root hash of a chain + public var rootHash: Data = Data() + + /// + /// The encrypted bytes from a message + public var message: Data = Data() + + /// + /// Message ID of the contained message + public var encapsulatedID: UInt32 = 0 + + /// + /// Destination of the contained message + public var encapsulatedTo: UInt32 = 0 + + /// + /// Sender of the contained message + public var encapsulatedFrom: UInt32 = 0 + + /// + /// The receive time of the message in question + public var encapsulatedRxtime: UInt32 = 0 + + public var unknownFields = SwiftProtobuf.UnknownStorage() + + /// + /// Enum of message types + public enum SFPP_message_type: SwiftProtobuf.Enum, Swift.CaseIterable { + public typealias RawValue = Int + + /// + /// Send an announcement of the canonical tip of a chain + case canonAnnounce // = 0 + + /// + /// Query whether a specific link is on the chain + case chainQuery // = 1 + + /// + /// Request the next link in the chain + case linkRequest // = 3 + + /// + /// Provide a link to add to the chain + case linkProvide // = 4 + + /// + /// If we must fragment, send the first half + case linkProvideFirsthalf // = 5 + + /// + /// If we must fragment, send the second half + case linkProvideSecondhalf // = 6 + case UNRECOGNIZED(Int) + + public init() { + self = .canonAnnounce + } + + public init?(rawValue: Int) { + switch rawValue { + case 0: self = .canonAnnounce + case 1: self = .chainQuery + case 3: self = .linkRequest + case 4: self = .linkProvide + case 5: self = .linkProvideFirsthalf + case 6: self = .linkProvideSecondhalf + default: self = .UNRECOGNIZED(rawValue) + } + } + + public var rawValue: Int { + switch self { + case .canonAnnounce: return 0 + case .chainQuery: return 1 + case .linkRequest: return 3 + case .linkProvide: return 4 + case .linkProvideFirsthalf: return 5 + case .linkProvideSecondhalf: return 6 + case .UNRECOGNIZED(let i): return i + } + } + + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [StoreForwardPlusPlus.SFPP_message_type] = [ + .canonAnnounce, + .chainQuery, + .linkRequest, + .linkProvide, + .linkProvideFirsthalf, + .linkProvideSecondhalf, + ] + + } + + public init() {} +} + /// /// Waypoint message, used to share arbitrary locations across the mesh -public struct Waypoint { +public struct Waypoint: Sendable { // 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. @@ -2178,7 +2275,7 @@ public struct Waypoint { /// /// This message will be proxied over the PhoneAPI for the client to deliver to the MQTT server -public struct MqttClientProxyMessage { +public struct MqttClientProxyMessage: Sendable { // 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. @@ -2219,7 +2316,7 @@ public struct MqttClientProxyMessage { /// /// The actual service envelope payload or text for mqtt pub / sub - public enum OneOf_PayloadVariant: Equatable { + public enum OneOf_PayloadVariant: Equatable, Sendable { /// /// Bytes case data(Data) @@ -2227,24 +2324,6 @@ public struct MqttClientProxyMessage { /// Text case text(String) - #if !swift(>=4.1) - public static func ==(lhs: MqttClientProxyMessage.OneOf_PayloadVariant, rhs: MqttClientProxyMessage.OneOf_PayloadVariant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.data, .data): return { - guard case .data(let l) = lhs, case .data(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.text, .text): return { - guard case .text(let l) = lhs, case .text(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } public init() {} @@ -2254,7 +2333,7 @@ public struct MqttClientProxyMessage { /// A packet envelope sent/received over the mesh /// only payload_variant is sent in the payload portion of the LORA packet. /// The other fields are either not sent at all, or sent in the special 16 byte LORA header. -public struct MeshPacket { +public struct MeshPacket: @unchecked Sendable { // 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. @@ -2270,6 +2349,10 @@ public struct MeshPacket { /// /// The (immediate) destination for this packet + /// If the value is 4,294,967,295 (maximum value of an unsigned 32bit integer), this indicates that the packet was + /// not destined for a specific node, but for a channel as indicated by the value of `channel` below. + /// If the value is another, this indicates that the packet was destined for a specific + /// node (i.e. a kind of "Direct Message" to this node) and not broadcast on a channel. public var to: UInt32 { get {return _storage._to} set {_uniqueStorage()._to = newValue} @@ -2388,6 +2471,8 @@ public struct MeshPacket { /// /// Describe if this message is delayed + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var delayed: MeshPacket.Delayed { get {return _storage._delayed} set {_uniqueStorage()._delayed = newValue} @@ -2456,7 +2541,7 @@ public struct MeshPacket { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_PayloadVariant: Equatable { + public enum OneOf_PayloadVariant: Equatable, Sendable { /// /// TODO: REPLACE case decoded(DataMessage) @@ -2464,24 +2549,6 @@ public struct MeshPacket { /// TODO: REPLACE case encrypted(Data) - #if !swift(>=4.1) - public static func ==(lhs: MeshPacket.OneOf_PayloadVariant, rhs: MeshPacket.OneOf_PayloadVariant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.decoded, .decoded): return { - guard case .decoded(let l) = lhs, case .decoded(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.encrypted, .encrypted): return { - guard case .encrypted(let l) = lhs, case .encrypted(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } /// @@ -2503,7 +2570,7 @@ public struct MeshPacket { /// So I bit the bullet and implemented a new (internal - not sent over the air) /// field in MeshPacket called 'priority'. /// And the transmission queue in the router object is now a priority queue. - public enum Priority: SwiftProtobuf.Enum { + public enum Priority: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -2587,11 +2654,25 @@ public struct MeshPacket { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [MeshPacket.Priority] = [ + .unset, + .min, + .background, + .default, + .reliable, + .response, + .high, + .alert, + .ack, + .max, + ] + } /// /// Identify if this is a delayed packet - public enum Delayed: SwiftProtobuf.Enum { + public enum Delayed: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -2629,11 +2710,18 @@ public struct MeshPacket { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [MeshPacket.Delayed] = [ + .noDelay, + .broadcast, + .direct, + ] + } /// /// Enum to identify which transport mechanism this packet arrived over - public enum TransportMechanism: SwiftProtobuf.Enum { + public enum TransportMechanism: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -2701,6 +2789,18 @@ public struct MeshPacket { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [MeshPacket.TransportMechanism] = [ + .transportInternal, + .transportLora, + .transportLoraAlt1, + .transportLoraAlt2, + .transportLoraAlt3, + .transportMqtt, + .transportMulticastUdp, + .transportApi, + ] + } public init() {} @@ -2708,49 +2808,6 @@ public struct MeshPacket { fileprivate var _storage = _StorageClass.defaultInstance } -#if swift(>=4.2) - -extension MeshPacket.Priority: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [MeshPacket.Priority] = [ - .unset, - .min, - .background, - .default, - .reliable, - .response, - .high, - .alert, - .ack, - .max, - ] -} - -extension MeshPacket.Delayed: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [MeshPacket.Delayed] = [ - .noDelay, - .broadcast, - .direct, - ] -} - -extension MeshPacket.TransportMechanism: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [MeshPacket.TransportMechanism] = [ - .transportInternal, - .transportLora, - .transportLoraAlt1, - .transportLoraAlt2, - .transportLoraAlt3, - .transportMqtt, - .transportMulticastUdp, - .transportApi, - ] -} - -#endif // swift(>=4.2) - /// /// The bluetooth to device link: /// Old BTLE protocol docs from TODO, merge in above and make real docs... @@ -2768,7 +2825,7 @@ extension MeshPacket.TransportMechanism: CaseIterable { /// level etc) SET_CONFIG (switches device to a new set of radio params and /// preshared key, drops all existing nodes, force our node to rejoin this new group) /// Full information about a node on the mesh -public struct NodeInfo { +public struct NodeInfo: @unchecked Sendable { // 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. @@ -2890,7 +2947,7 @@ public struct NodeInfo { /// Unique local debugging info for this node /// Note: we don't include position or the user info, because that will come in the /// Sent to the phone in response to WantNodes. -public struct MyNodeInfo { +public struct MyNodeInfo: Sendable { // 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. @@ -2938,7 +2995,7 @@ public struct MyNodeInfo { /// on the message it is assumed to be a continuation of the previously sent message. /// This allows the device code to use fixed maxlen 64 byte strings for messages, /// and then extend as needed by emitting multiple records. -public struct LogRecord { +public struct LogRecord: Sendable { // 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. @@ -2963,7 +3020,7 @@ public struct LogRecord { /// /// Log levels, chosen to match python logging conventions. - public enum Level: SwiftProtobuf.Enum { + public enum Level: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -3025,29 +3082,23 @@ public struct LogRecord { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [LogRecord.Level] = [ + .unset, + .critical, + .error, + .warning, + .info, + .debug, + .trace, + ] + } public init() {} } -#if swift(>=4.2) - -extension LogRecord.Level: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [LogRecord.Level] = [ - .unset, - .critical, - .error, - .warning, - .info, - .debug, - .trace, - ] -} - -#endif // swift(>=4.2) - -public struct QueueStatus { +public struct QueueStatus: Sendable { // 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. @@ -3074,7 +3125,7 @@ public struct QueueStatus { /// It will support READ and NOTIFY. When a new packet arrives the device will BLE notify? /// It will sit in that descriptor until consumed by the phone, /// at which point the next item in the FIFO will be populated. -public struct FromRadio { +public struct FromRadio: Sendable { // 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. @@ -3260,7 +3311,7 @@ public struct FromRadio { /// /// Log levels, chosen to match python logging conventions. - public enum OneOf_PayloadVariant: Equatable { + public enum OneOf_PayloadVariant: Equatable, Sendable { /// /// Log levels, chosen to match python logging conventions. case packet(MeshPacket) @@ -3318,80 +3369,6 @@ public struct FromRadio { /// Persistent data for device-ui case deviceuiConfig(DeviceUIConfig) - #if !swift(>=4.1) - public static func ==(lhs: FromRadio.OneOf_PayloadVariant, rhs: FromRadio.OneOf_PayloadVariant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.packet, .packet): return { - guard case .packet(let l) = lhs, case .packet(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.myInfo, .myInfo): return { - guard case .myInfo(let l) = lhs, case .myInfo(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.nodeInfo, .nodeInfo): return { - guard case .nodeInfo(let l) = lhs, case .nodeInfo(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.config, .config): return { - guard case .config(let l) = lhs, case .config(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.logRecord, .logRecord): return { - guard case .logRecord(let l) = lhs, case .logRecord(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.configCompleteID, .configCompleteID): return { - guard case .configCompleteID(let l) = lhs, case .configCompleteID(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.rebooted, .rebooted): return { - guard case .rebooted(let l) = lhs, case .rebooted(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.moduleConfig, .moduleConfig): return { - guard case .moduleConfig(let l) = lhs, case .moduleConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.channel, .channel): return { - guard case .channel(let l) = lhs, case .channel(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.queueStatus, .queueStatus): return { - guard case .queueStatus(let l) = lhs, case .queueStatus(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.xmodemPacket, .xmodemPacket): return { - guard case .xmodemPacket(let l) = lhs, case .xmodemPacket(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.metadata, .metadata): return { - guard case .metadata(let l) = lhs, case .metadata(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.mqttClientProxyMessage, .mqttClientProxyMessage): return { - guard case .mqttClientProxyMessage(let l) = lhs, case .mqttClientProxyMessage(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.fileInfo, .fileInfo): return { - guard case .fileInfo(let l) = lhs, case .fileInfo(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.clientNotification, .clientNotification): return { - guard case .clientNotification(let l) = lhs, case .clientNotification(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.deviceuiConfig, .deviceuiConfig): return { - guard case .deviceuiConfig(let l) = lhs, case .deviceuiConfig(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } public init() {} @@ -3402,7 +3379,7 @@ public struct FromRadio { /// To be used for important messages that should to be displayed to the user /// in the form of push notifications or validation messages when saving /// invalid configuration. -public struct ClientNotification { +public struct ClientNotification: Sendable { // 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. @@ -3474,43 +3451,13 @@ public struct ClientNotification { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_PayloadVariant: Equatable { + public enum OneOf_PayloadVariant: Equatable, Sendable { case keyVerificationNumberInform(KeyVerificationNumberInform) case keyVerificationNumberRequest(KeyVerificationNumberRequest) case keyVerificationFinal(KeyVerificationFinal) case duplicatedPublicKey(DuplicatedPublicKey) case lowEntropyKey(LowEntropyKey) - #if !swift(>=4.1) - public static func ==(lhs: ClientNotification.OneOf_PayloadVariant, rhs: ClientNotification.OneOf_PayloadVariant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.keyVerificationNumberInform, .keyVerificationNumberInform): return { - guard case .keyVerificationNumberInform(let l) = lhs, case .keyVerificationNumberInform(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.keyVerificationNumberRequest, .keyVerificationNumberRequest): return { - guard case .keyVerificationNumberRequest(let l) = lhs, case .keyVerificationNumberRequest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.keyVerificationFinal, .keyVerificationFinal): return { - guard case .keyVerificationFinal(let l) = lhs, case .keyVerificationFinal(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.duplicatedPublicKey, .duplicatedPublicKey): return { - guard case .duplicatedPublicKey(let l) = lhs, case .duplicatedPublicKey(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.lowEntropyKey, .lowEntropyKey): return { - guard case .lowEntropyKey(let l) = lhs, case .lowEntropyKey(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } public init() {} @@ -3518,7 +3465,7 @@ public struct ClientNotification { fileprivate var _replyID: UInt32? = nil } -public struct KeyVerificationNumberInform { +public struct KeyVerificationNumberInform: Sendable { // 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. @@ -3534,7 +3481,7 @@ public struct KeyVerificationNumberInform { public init() {} } -public struct KeyVerificationNumberRequest { +public struct KeyVerificationNumberRequest: Sendable { // 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. @@ -3548,7 +3495,7 @@ public struct KeyVerificationNumberRequest { public init() {} } -public struct KeyVerificationFinal { +public struct KeyVerificationFinal: Sendable { // 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. @@ -3566,7 +3513,7 @@ public struct KeyVerificationFinal { public init() {} } -public struct DuplicatedPublicKey { +public struct DuplicatedPublicKey: Sendable { // 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. @@ -3576,7 +3523,7 @@ public struct DuplicatedPublicKey { public init() {} } -public struct LowEntropyKey { +public struct LowEntropyKey: Sendable { // 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. @@ -3588,7 +3535,7 @@ public struct LowEntropyKey { /// /// Individual File info for the device -public struct FileInfo { +public struct FileInfo: Sendable { // 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. @@ -3609,7 +3556,7 @@ public struct FileInfo { /// /// Packets/commands to the radio will be written (reliably) to the toRadio characteristic. /// Once the write completes the phone can assume it is handled. -public struct ToRadio { +public struct ToRadio: Sendable { // 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. @@ -3689,7 +3636,7 @@ public struct ToRadio { /// /// Log levels, chosen to match python logging conventions. - public enum OneOf_PayloadVariant: Equatable { + public enum OneOf_PayloadVariant: Equatable, Sendable { /// /// Send this packet on the mesh case packet(MeshPacket) @@ -3716,40 +3663,6 @@ public struct ToRadio { /// Heartbeat message (used to keep the device connection awake on serial) case heartbeat(Heartbeat) - #if !swift(>=4.1) - public static func ==(lhs: ToRadio.OneOf_PayloadVariant, rhs: ToRadio.OneOf_PayloadVariant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.packet, .packet): return { - guard case .packet(let l) = lhs, case .packet(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.wantConfigID, .wantConfigID): return { - guard case .wantConfigID(let l) = lhs, case .wantConfigID(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.disconnect, .disconnect): return { - guard case .disconnect(let l) = lhs, case .disconnect(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.xmodemPacket, .xmodemPacket): return { - guard case .xmodemPacket(let l) = lhs, case .xmodemPacket(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.mqttClientProxyMessage, .mqttClientProxyMessage): return { - guard case .mqttClientProxyMessage(let l) = lhs, case .mqttClientProxyMessage(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.heartbeat, .heartbeat): return { - guard case .heartbeat(let l) = lhs, case .heartbeat(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } public init() {} @@ -3757,7 +3670,7 @@ public struct ToRadio { /// /// Compressed message payload -public struct Compressed { +public struct Compressed: Sendable { // 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. @@ -3777,7 +3690,7 @@ public struct Compressed { /// /// Full info on edges for a single node -public struct NeighborInfo { +public struct NeighborInfo: Sendable { // 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. @@ -3805,7 +3718,7 @@ public struct NeighborInfo { /// /// A single edge in the mesh -public struct Neighbor { +public struct Neighbor: Sendable { // 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. @@ -3835,7 +3748,7 @@ public struct Neighbor { /// /// Device metadata response -public struct DeviceMetadata { +public struct DeviceMetadata: Sendable { // 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. @@ -3897,7 +3810,7 @@ public struct DeviceMetadata { /// /// A heartbeat message is sent to the node from the client to keep the connection alive. /// This is currently only needed to keep serial connections alive, but can be used by any PhoneAPI. -public struct Heartbeat { +public struct Heartbeat: Sendable { // 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. @@ -3913,7 +3826,7 @@ public struct Heartbeat { /// /// RemoteHardwarePins associated with a node -public struct NodeRemoteHardwarePin { +public struct NodeRemoteHardwarePin: Sendable { // 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. @@ -3940,7 +3853,7 @@ public struct NodeRemoteHardwarePin { fileprivate var _pin: RemoteHardwarePin? = nil } -public struct ChunkedPayload { +public struct ChunkedPayload: Sendable { // 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. @@ -3968,7 +3881,7 @@ public struct ChunkedPayload { /// /// Wrapper message for broken repeated oneof support -public struct resend_chunks { +public struct resend_chunks: Sendable { // 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. @@ -3982,7 +3895,7 @@ public struct resend_chunks { /// /// Responses to a ChunkedPayload request -public struct ChunkedPayloadResponse { +public struct ChunkedPayloadResponse: Sendable { // 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. @@ -4025,7 +3938,7 @@ public struct ChunkedPayloadResponse { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_PayloadVariant: Equatable { + public enum OneOf_PayloadVariant: Equatable, Sendable { /// /// Request to transfer chunked payload case requestTransfer(Bool) @@ -4036,297 +3949,38 @@ public struct ChunkedPayloadResponse { /// Request missing indexes in the chunked payload case resendChunks(resend_chunks) - #if !swift(>=4.1) - public static func ==(lhs: ChunkedPayloadResponse.OneOf_PayloadVariant, rhs: ChunkedPayloadResponse.OneOf_PayloadVariant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.requestTransfer, .requestTransfer): return { - guard case .requestTransfer(let l) = lhs, case .requestTransfer(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.acceptTransfer, .acceptTransfer): return { - guard case .acceptTransfer(let l) = lhs, case .acceptTransfer(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.resendChunks, .resendChunks): return { - guard case .resendChunks(let l) = lhs, case .resendChunks(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } public init() {} } -#if swift(>=5.5) && canImport(_Concurrency) -extension HardwareModel: @unchecked Sendable {} -extension Constants: @unchecked Sendable {} -extension CriticalErrorCode: @unchecked Sendable {} -extension FirmwareEdition: @unchecked Sendable {} -extension ExcludedModules: @unchecked Sendable {} -extension Position: @unchecked Sendable {} -extension Position.LocSource: @unchecked Sendable {} -extension Position.AltSource: @unchecked Sendable {} -extension User: @unchecked Sendable {} -extension RouteDiscovery: @unchecked Sendable {} -extension Routing: @unchecked Sendable {} -extension Routing.OneOf_Variant: @unchecked Sendable {} -extension Routing.Error: @unchecked Sendable {} -extension DataMessage: @unchecked Sendable {} -extension KeyVerification: @unchecked Sendable {} -extension Waypoint: @unchecked Sendable {} -extension MqttClientProxyMessage: @unchecked Sendable {} -extension MqttClientProxyMessage.OneOf_PayloadVariant: @unchecked Sendable {} -extension MeshPacket: @unchecked Sendable {} -extension MeshPacket.OneOf_PayloadVariant: @unchecked Sendable {} -extension MeshPacket.Priority: @unchecked Sendable {} -extension MeshPacket.Delayed: @unchecked Sendable {} -extension MeshPacket.TransportMechanism: @unchecked Sendable {} -extension NodeInfo: @unchecked Sendable {} -extension MyNodeInfo: @unchecked Sendable {} -extension LogRecord: @unchecked Sendable {} -extension LogRecord.Level: @unchecked Sendable {} -extension QueueStatus: @unchecked Sendable {} -extension FromRadio: @unchecked Sendable {} -extension FromRadio.OneOf_PayloadVariant: @unchecked Sendable {} -extension ClientNotification: @unchecked Sendable {} -extension ClientNotification.OneOf_PayloadVariant: @unchecked Sendable {} -extension KeyVerificationNumberInform: @unchecked Sendable {} -extension KeyVerificationNumberRequest: @unchecked Sendable {} -extension KeyVerificationFinal: @unchecked Sendable {} -extension DuplicatedPublicKey: @unchecked Sendable {} -extension LowEntropyKey: @unchecked Sendable {} -extension FileInfo: @unchecked Sendable {} -extension ToRadio: @unchecked Sendable {} -extension ToRadio.OneOf_PayloadVariant: @unchecked Sendable {} -extension Compressed: @unchecked Sendable {} -extension NeighborInfo: @unchecked Sendable {} -extension Neighbor: @unchecked Sendable {} -extension DeviceMetadata: @unchecked Sendable {} -extension Heartbeat: @unchecked Sendable {} -extension NodeRemoteHardwarePin: @unchecked Sendable {} -extension ChunkedPayload: @unchecked Sendable {} -extension resend_chunks: @unchecked Sendable {} -extension ChunkedPayloadResponse: @unchecked Sendable {} -extension ChunkedPayloadResponse.OneOf_PayloadVariant: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension HardwareModel: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNSET"), - 1: .same(proto: "TLORA_V2"), - 2: .same(proto: "TLORA_V1"), - 3: .same(proto: "TLORA_V2_1_1P6"), - 4: .same(proto: "TBEAM"), - 5: .same(proto: "HELTEC_V2_0"), - 6: .same(proto: "TBEAM_V0P7"), - 7: .same(proto: "T_ECHO"), - 8: .same(proto: "TLORA_V1_1P3"), - 9: .same(proto: "RAK4631"), - 10: .same(proto: "HELTEC_V2_1"), - 11: .same(proto: "HELTEC_V1"), - 12: .same(proto: "LILYGO_TBEAM_S3_CORE"), - 13: .same(proto: "RAK11200"), - 14: .same(proto: "NANO_G1"), - 15: .same(proto: "TLORA_V2_1_1P8"), - 16: .same(proto: "TLORA_T3_S3"), - 17: .same(proto: "NANO_G1_EXPLORER"), - 18: .same(proto: "NANO_G2_ULTRA"), - 19: .same(proto: "LORA_TYPE"), - 20: .same(proto: "WIPHONE"), - 21: .same(proto: "WIO_WM1110"), - 22: .same(proto: "RAK2560"), - 23: .same(proto: "HELTEC_HRU_3601"), - 24: .same(proto: "HELTEC_WIRELESS_BRIDGE"), - 25: .same(proto: "STATION_G1"), - 26: .same(proto: "RAK11310"), - 27: .same(proto: "SENSELORA_RP2040"), - 28: .same(proto: "SENSELORA_S3"), - 29: .same(proto: "CANARYONE"), - 30: .same(proto: "RP2040_LORA"), - 31: .same(proto: "STATION_G2"), - 32: .same(proto: "LORA_RELAY_V1"), - 33: .same(proto: "NRF52840DK"), - 34: .same(proto: "PPR"), - 35: .same(proto: "GENIEBLOCKS"), - 36: .same(proto: "NRF52_UNKNOWN"), - 37: .same(proto: "PORTDUINO"), - 38: .same(proto: "ANDROID_SIM"), - 39: .same(proto: "DIY_V1"), - 40: .same(proto: "NRF52840_PCA10059"), - 41: .same(proto: "DR_DEV"), - 42: .same(proto: "M5STACK"), - 43: .same(proto: "HELTEC_V3"), - 44: .same(proto: "HELTEC_WSL_V3"), - 45: .same(proto: "BETAFPV_2400_TX"), - 46: .same(proto: "BETAFPV_900_NANO_TX"), - 47: .same(proto: "RPI_PICO"), - 48: .same(proto: "HELTEC_WIRELESS_TRACKER"), - 49: .same(proto: "HELTEC_WIRELESS_PAPER"), - 50: .same(proto: "T_DECK"), - 51: .same(proto: "T_WATCH_S3"), - 52: .same(proto: "PICOMPUTER_S3"), - 53: .same(proto: "HELTEC_HT62"), - 54: .same(proto: "EBYTE_ESP32_S3"), - 55: .same(proto: "ESP32_S3_PICO"), - 56: .same(proto: "CHATTER_2"), - 57: .same(proto: "HELTEC_WIRELESS_PAPER_V1_0"), - 58: .same(proto: "HELTEC_WIRELESS_TRACKER_V1_0"), - 59: .same(proto: "UNPHONE"), - 60: .same(proto: "TD_LORAC"), - 61: .same(proto: "CDEBYTE_EORA_S3"), - 62: .same(proto: "TWC_MESH_V4"), - 63: .same(proto: "NRF52_PROMICRO_DIY"), - 64: .same(proto: "RADIOMASTER_900_BANDIT_NANO"), - 65: .same(proto: "HELTEC_CAPSULE_SENSOR_V3"), - 66: .same(proto: "HELTEC_VISION_MASTER_T190"), - 67: .same(proto: "HELTEC_VISION_MASTER_E213"), - 68: .same(proto: "HELTEC_VISION_MASTER_E290"), - 69: .same(proto: "HELTEC_MESH_NODE_T114"), - 70: .same(proto: "SENSECAP_INDICATOR"), - 71: .same(proto: "TRACKER_T1000_E"), - 72: .same(proto: "RAK3172"), - 73: .same(proto: "WIO_E5"), - 74: .same(proto: "RADIOMASTER_900_BANDIT"), - 75: .same(proto: "ME25LS01_4Y10TD"), - 76: .same(proto: "RP2040_FEATHER_RFM95"), - 77: .same(proto: "M5STACK_COREBASIC"), - 78: .same(proto: "M5STACK_CORE2"), - 79: .same(proto: "RPI_PICO2"), - 80: .same(proto: "M5STACK_CORES3"), - 81: .same(proto: "SEEED_XIAO_S3"), - 82: .same(proto: "MS24SF1"), - 83: .same(proto: "TLORA_C6"), - 84: .same(proto: "WISMESH_TAP"), - 85: .same(proto: "ROUTASTIC"), - 86: .same(proto: "MESH_TAB"), - 87: .same(proto: "MESHLINK"), - 88: .same(proto: "XIAO_NRF52_KIT"), - 89: .same(proto: "THINKNODE_M1"), - 90: .same(proto: "THINKNODE_M2"), - 91: .same(proto: "T_ETH_ELITE"), - 92: .same(proto: "HELTEC_SENSOR_HUB"), - 93: .same(proto: "RESERVED_FRIED_CHICKEN"), - 94: .same(proto: "HELTEC_MESH_POCKET"), - 95: .same(proto: "SEEED_SOLAR_NODE"), - 96: .same(proto: "NOMADSTAR_METEOR_PRO"), - 97: .same(proto: "CROWPANEL"), - 98: .same(proto: "LINK_32"), - 99: .same(proto: "SEEED_WIO_TRACKER_L1"), - 100: .same(proto: "SEEED_WIO_TRACKER_L1_EINK"), - 101: .same(proto: "MUZI_R1_NEO"), - 102: .same(proto: "T_DECK_PRO"), - 103: .same(proto: "T_LORA_PAGER"), - 104: .same(proto: "M5STACK_RESERVED"), - 105: .same(proto: "WISMESH_TAG"), - 106: .same(proto: "RAK3312"), - 107: .same(proto: "THINKNODE_M5"), - 108: .same(proto: "HELTEC_MESH_SOLAR"), - 109: .same(proto: "T_ECHO_LITE"), - 110: .same(proto: "HELTEC_V4"), - 111: .same(proto: "M5STACK_C6L"), - 112: .same(proto: "M5STACK_CARDPUTER_ADV"), - 113: .same(proto: "HELTEC_WIRELESS_TRACKER_V2"), - 114: .same(proto: "T_WATCH_ULTRA"), - 255: .same(proto: "PRIVATE_HW"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNSET\0\u{1}TLORA_V2\0\u{1}TLORA_V1\0\u{1}TLORA_V2_1_1P6\0\u{1}TBEAM\0\u{1}HELTEC_V2_0\0\u{1}TBEAM_V0P7\0\u{1}T_ECHO\0\u{1}TLORA_V1_1P3\0\u{1}RAK4631\0\u{1}HELTEC_V2_1\0\u{1}HELTEC_V1\0\u{1}LILYGO_TBEAM_S3_CORE\0\u{1}RAK11200\0\u{1}NANO_G1\0\u{1}TLORA_V2_1_1P8\0\u{1}TLORA_T3_S3\0\u{1}NANO_G1_EXPLORER\0\u{1}NANO_G2_ULTRA\0\u{1}LORA_TYPE\0\u{1}WIPHONE\0\u{1}WIO_WM1110\0\u{1}RAK2560\0\u{1}HELTEC_HRU_3601\0\u{1}HELTEC_WIRELESS_BRIDGE\0\u{1}STATION_G1\0\u{1}RAK11310\0\u{1}SENSELORA_RP2040\0\u{1}SENSELORA_S3\0\u{1}CANARYONE\0\u{1}RP2040_LORA\0\u{1}STATION_G2\0\u{1}LORA_RELAY_V1\0\u{1}NRF52840DK\0\u{1}PPR\0\u{1}GENIEBLOCKS\0\u{1}NRF52_UNKNOWN\0\u{1}PORTDUINO\0\u{1}ANDROID_SIM\0\u{1}DIY_V1\0\u{1}NRF52840_PCA10059\0\u{1}DR_DEV\0\u{1}M5STACK\0\u{1}HELTEC_V3\0\u{1}HELTEC_WSL_V3\0\u{1}BETAFPV_2400_TX\0\u{1}BETAFPV_900_NANO_TX\0\u{1}RPI_PICO\0\u{1}HELTEC_WIRELESS_TRACKER\0\u{1}HELTEC_WIRELESS_PAPER\0\u{1}T_DECK\0\u{1}T_WATCH_S3\0\u{1}PICOMPUTER_S3\0\u{1}HELTEC_HT62\0\u{1}EBYTE_ESP32_S3\0\u{1}ESP32_S3_PICO\0\u{1}CHATTER_2\0\u{1}HELTEC_WIRELESS_PAPER_V1_0\0\u{1}HELTEC_WIRELESS_TRACKER_V1_0\0\u{1}UNPHONE\0\u{1}TD_LORAC\0\u{1}CDEBYTE_EORA_S3\0\u{1}TWC_MESH_V4\0\u{1}NRF52_PROMICRO_DIY\0\u{1}RADIOMASTER_900_BANDIT_NANO\0\u{1}HELTEC_CAPSULE_SENSOR_V3\0\u{1}HELTEC_VISION_MASTER_T190\0\u{1}HELTEC_VISION_MASTER_E213\0\u{1}HELTEC_VISION_MASTER_E290\0\u{1}HELTEC_MESH_NODE_T114\0\u{1}SENSECAP_INDICATOR\0\u{1}TRACKER_T1000_E\0\u{1}RAK3172\0\u{1}WIO_E5\0\u{1}RADIOMASTER_900_BANDIT\0\u{1}ME25LS01_4Y10TD\0\u{1}RP2040_FEATHER_RFM95\0\u{1}M5STACK_COREBASIC\0\u{1}M5STACK_CORE2\0\u{1}RPI_PICO2\0\u{1}M5STACK_CORES3\0\u{1}SEEED_XIAO_S3\0\u{1}MS24SF1\0\u{1}TLORA_C6\0\u{1}WISMESH_TAP\0\u{1}ROUTASTIC\0\u{1}MESH_TAB\0\u{1}MESHLINK\0\u{1}XIAO_NRF52_KIT\0\u{1}THINKNODE_M1\0\u{1}THINKNODE_M2\0\u{1}T_ETH_ELITE\0\u{1}HELTEC_SENSOR_HUB\0\u{1}MUZI_BASE\0\u{1}HELTEC_MESH_POCKET\0\u{1}SEEED_SOLAR_NODE\0\u{1}NOMADSTAR_METEOR_PRO\0\u{1}CROWPANEL\0\u{1}LINK_32\0\u{1}SEEED_WIO_TRACKER_L1\0\u{1}SEEED_WIO_TRACKER_L1_EINK\0\u{1}MUZI_R1_NEO\0\u{1}T_DECK_PRO\0\u{1}T_LORA_PAGER\0\u{1}M5STACK_RESERVED\0\u{1}WISMESH_TAG\0\u{1}RAK3312\0\u{1}THINKNODE_M5\0\u{1}HELTEC_MESH_SOLAR\0\u{1}T_ECHO_LITE\0\u{1}HELTEC_V4\0\u{1}M5STACK_C6L\0\u{1}M5STACK_CARDPUTER_ADV\0\u{1}HELTEC_WIRELESS_TRACKER_V2\0\u{1}T_WATCH_ULTRA\0\u{1}THINKNODE_M3\0\u{1}WISMESH_TAP_V2\0\u{1}RAK3401\0\u{1}RAK6421\0\u{1}THINKNODE_M4\0\u{1}THINKNODE_M6\0\u{2}G\u{2}PRIVATE_HW\0") } extension Constants: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "ZERO"), - 233: .same(proto: "DATA_PAYLOAD_LEN"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0ZERO\0\u{2}i\u{3}DATA_PAYLOAD_LEN\0") } extension CriticalErrorCode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "NONE"), - 1: .same(proto: "TX_WATCHDOG"), - 2: .same(proto: "SLEEP_ENTER_WAIT"), - 3: .same(proto: "NO_RADIO"), - 4: .same(proto: "UNSPECIFIED"), - 5: .same(proto: "UBLOX_UNIT_FAILED"), - 6: .same(proto: "NO_AXP192"), - 7: .same(proto: "INVALID_RADIO_SETTING"), - 8: .same(proto: "TRANSMIT_FAILED"), - 9: .same(proto: "BROWNOUT"), - 10: .same(proto: "SX1262_FAILURE"), - 11: .same(proto: "RADIO_SPI_BUG"), - 12: .same(proto: "FLASH_CORRUPTION_RECOVERABLE"), - 13: .same(proto: "FLASH_CORRUPTION_UNRECOVERABLE"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0NONE\0\u{1}TX_WATCHDOG\0\u{1}SLEEP_ENTER_WAIT\0\u{1}NO_RADIO\0\u{1}UNSPECIFIED\0\u{1}UBLOX_UNIT_FAILED\0\u{1}NO_AXP192\0\u{1}INVALID_RADIO_SETTING\0\u{1}TRANSMIT_FAILED\0\u{1}BROWNOUT\0\u{1}SX1262_FAILURE\0\u{1}RADIO_SPI_BUG\0\u{1}FLASH_CORRUPTION_RECOVERABLE\0\u{1}FLASH_CORRUPTION_UNRECOVERABLE\0") } extension FirmwareEdition: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "VANILLA"), - 1: .same(proto: "SMART_CITIZEN"), - 16: .same(proto: "OPEN_SAUCE"), - 17: .same(proto: "DEFCON"), - 18: .same(proto: "BURNING_MAN"), - 19: .same(proto: "HAMVENTION"), - 127: .same(proto: "DIY_EDITION"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0VANILLA\0\u{1}SMART_CITIZEN\0\u{2}\u{f}OPEN_SAUCE\0\u{1}DEFCON\0\u{1}BURNING_MAN\0\u{1}HAMVENTION\0\u{2}l\u{1}DIY_EDITION\0") } extension ExcludedModules: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "EXCLUDED_NONE"), - 1: .same(proto: "MQTT_CONFIG"), - 2: .same(proto: "SERIAL_CONFIG"), - 4: .same(proto: "EXTNOTIF_CONFIG"), - 8: .same(proto: "STOREFORWARD_CONFIG"), - 16: .same(proto: "RANGETEST_CONFIG"), - 32: .same(proto: "TELEMETRY_CONFIG"), - 64: .same(proto: "CANNEDMSG_CONFIG"), - 128: .same(proto: "AUDIO_CONFIG"), - 256: .same(proto: "REMOTEHARDWARE_CONFIG"), - 512: .same(proto: "NEIGHBORINFO_CONFIG"), - 1024: .same(proto: "AMBIENTLIGHTING_CONFIG"), - 2048: .same(proto: "DETECTIONSENSOR_CONFIG"), - 4096: .same(proto: "PAXCOUNTER_CONFIG"), - 8192: .same(proto: "BLUETOOTH_CONFIG"), - 16384: .same(proto: "NETWORK_CONFIG"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0EXCLUDED_NONE\0\u{1}MQTT_CONFIG\0\u{1}SERIAL_CONFIG\0\u{2}\u{2}EXTNOTIF_CONFIG\0\u{2}\u{4}STOREFORWARD_CONFIG\0\u{2}\u{8}RANGETEST_CONFIG\0\u{2}\u{10}TELEMETRY_CONFIG\0\u{2} CANNEDMSG_CONFIG\0\u{2}@\u{1}AUDIO_CONFIG\0\u{2}@\u{2}REMOTEHARDWARE_CONFIG\0\u{2}@\u{4}NEIGHBORINFO_CONFIG\0\u{2}@\u{8}AMBIENTLIGHTING_CONFIG\0\u{2}@\u{10}DETECTIONSENSOR_CONFIG\0\u{2}@ PAXCOUNTER_CONFIG\0\u{2}@@\u{1}BLUETOOTH_CONFIG\0\u{2}@@\u{2}NETWORK_CONFIG\0") } extension Position: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Position" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "latitude_i"), - 2: .standard(proto: "longitude_i"), - 3: .same(proto: "altitude"), - 4: .same(proto: "time"), - 5: .standard(proto: "location_source"), - 6: .standard(proto: "altitude_source"), - 7: .same(proto: "timestamp"), - 8: .standard(proto: "timestamp_millis_adjust"), - 9: .standard(proto: "altitude_hae"), - 10: .standard(proto: "altitude_geoidal_separation"), - 11: .same(proto: "PDOP"), - 12: .same(proto: "HDOP"), - 13: .same(proto: "VDOP"), - 14: .standard(proto: "gps_accuracy"), - 15: .standard(proto: "ground_speed"), - 16: .standard(proto: "ground_track"), - 17: .standard(proto: "fix_quality"), - 18: .standard(proto: "fix_type"), - 19: .standard(proto: "sats_in_view"), - 20: .standard(proto: "sensor_id"), - 21: .standard(proto: "next_update"), - 22: .standard(proto: "seq_number"), - 23: .standard(proto: "precision_bits"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}latitude_i\0\u{3}longitude_i\0\u{1}altitude\0\u{1}time\0\u{3}location_source\0\u{3}altitude_source\0\u{1}timestamp\0\u{3}timestamp_millis_adjust\0\u{3}altitude_hae\0\u{3}altitude_geoidal_separation\0\u{1}PDOP\0\u{1}HDOP\0\u{1}VDOP\0\u{3}gps_accuracy\0\u{3}ground_speed\0\u{3}ground_track\0\u{3}fix_quality\0\u{3}fix_type\0\u{3}sats_in_view\0\u{3}sensor_id\0\u{3}next_update\0\u{3}seq_number\0\u{3}precision_bits\0") fileprivate class _StorageClass { var _latitudeI: Int32? = nil @@ -4353,15 +4007,11 @@ extension Position: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB var _seqNumber: UInt32 = 0 var _precisionBits: UInt32 = 0 - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} @@ -4553,37 +4203,16 @@ extension Position: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB } extension Position.LocSource: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "LOC_UNSET"), - 1: .same(proto: "LOC_MANUAL"), - 2: .same(proto: "LOC_INTERNAL"), - 3: .same(proto: "LOC_EXTERNAL"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0LOC_UNSET\0\u{1}LOC_MANUAL\0\u{1}LOC_INTERNAL\0\u{1}LOC_EXTERNAL\0") } extension Position.AltSource: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "ALT_UNSET"), - 1: .same(proto: "ALT_MANUAL"), - 2: .same(proto: "ALT_INTERNAL"), - 3: .same(proto: "ALT_EXTERNAL"), - 4: .same(proto: "ALT_BAROMETRIC"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0ALT_UNSET\0\u{1}ALT_MANUAL\0\u{1}ALT_INTERNAL\0\u{1}ALT_EXTERNAL\0\u{1}ALT_BAROMETRIC\0") } extension User: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".User" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "id"), - 2: .standard(proto: "long_name"), - 3: .standard(proto: "short_name"), - 4: .same(proto: "macaddr"), - 5: .standard(proto: "hw_model"), - 6: .standard(proto: "is_licensed"), - 7: .same(proto: "role"), - 8: .standard(proto: "public_key"), - 9: .standard(proto: "is_unmessagable"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}id\0\u{3}long_name\0\u{3}short_name\0\u{1}macaddr\0\u{3}hw_model\0\u{3}is_licensed\0\u{1}role\0\u{3}public_key\0\u{3}is_unmessagable\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4657,12 +4286,7 @@ extension User: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, extension RouteDiscovery: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".RouteDiscovery" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "route"), - 2: .standard(proto: "snr_towards"), - 3: .standard(proto: "route_back"), - 4: .standard(proto: "snr_back"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}route\0\u{3}snr_towards\0\u{3}route_back\0\u{3}snr_back\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4707,11 +4331,7 @@ extension RouteDiscovery: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement extension Routing: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Routing" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "route_request"), - 2: .standard(proto: "route_reply"), - 3: .standard(proto: "error_reason"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}route_request\0\u{3}route_reply\0\u{3}error_reason\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4789,40 +4409,12 @@ extension Routing: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa } extension Routing.Error: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "NONE"), - 1: .same(proto: "NO_ROUTE"), - 2: .same(proto: "GOT_NAK"), - 3: .same(proto: "TIMEOUT"), - 4: .same(proto: "NO_INTERFACE"), - 5: .same(proto: "MAX_RETRANSMIT"), - 6: .same(proto: "NO_CHANNEL"), - 7: .same(proto: "TOO_LARGE"), - 8: .same(proto: "NO_RESPONSE"), - 9: .same(proto: "DUTY_CYCLE_LIMIT"), - 32: .same(proto: "BAD_REQUEST"), - 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"), - 38: .same(proto: "RATE_LIMIT_EXCEEDED"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0NONE\0\u{1}NO_ROUTE\0\u{1}GOT_NAK\0\u{1}TIMEOUT\0\u{1}NO_INTERFACE\0\u{1}MAX_RETRANSMIT\0\u{1}NO_CHANNEL\0\u{1}TOO_LARGE\0\u{1}NO_RESPONSE\0\u{1}DUTY_CYCLE_LIMIT\0\u{2}\u{17}BAD_REQUEST\0\u{1}NOT_AUTHORIZED\0\u{1}PKI_FAILED\0\u{1}PKI_UNKNOWN_PUBKEY\0\u{1}ADMIN_BAD_SESSION_KEY\0\u{1}ADMIN_PUBLIC_KEY_UNAUTHORIZED\0\u{1}RATE_LIMIT_EXCEEDED\0") } extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Data" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "portnum"), - 2: .same(proto: "payload"), - 3: .standard(proto: "want_response"), - 4: .same(proto: "dest"), - 5: .same(proto: "source"), - 6: .standard(proto: "request_id"), - 7: .standard(proto: "reply_id"), - 8: .same(proto: "emoji"), - 9: .same(proto: "bitfield"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}portnum\0\u{1}payload\0\u{3}want_response\0\u{1}dest\0\u{1}source\0\u{3}request_id\0\u{3}reply_id\0\u{1}emoji\0\u{1}bitfield\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4896,11 +4488,7 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati extension KeyVerification: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".KeyVerification" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "nonce"), - 2: .same(proto: "hash1"), - 3: .same(proto: "hash2"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}nonce\0\u{1}hash1\0\u{1}hash2\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4938,18 +4526,83 @@ extension KeyVerification: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen } } +extension StoreForwardPlusPlus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + public static let protoMessageName: String = _protobuf_package + ".StoreForwardPlusPlus" + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}sfpp_message_type\0\u{3}message_hash\0\u{3}commit_hash\0\u{3}root_hash\0\u{1}message\0\u{3}encapsulated_id\0\u{3}encapsulated_to\0\u{3}encapsulated_from\0\u{3}encapsulated_rxtime\0") + + public mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self.sfppMessageType) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.messageHash) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self.commitHash) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self.rootHash) }() + case 5: try { try decoder.decodeSingularBytesField(value: &self.message) }() + case 6: try { try decoder.decodeSingularUInt32Field(value: &self.encapsulatedID) }() + case 7: try { try decoder.decodeSingularUInt32Field(value: &self.encapsulatedTo) }() + case 8: try { try decoder.decodeSingularUInt32Field(value: &self.encapsulatedFrom) }() + case 9: try { try decoder.decodeSingularUInt32Field(value: &self.encapsulatedRxtime) }() + default: break + } + } + } + + public func traverse(visitor: inout V) throws { + if self.sfppMessageType != .canonAnnounce { + try visitor.visitSingularEnumField(value: self.sfppMessageType, fieldNumber: 1) + } + if !self.messageHash.isEmpty { + try visitor.visitSingularBytesField(value: self.messageHash, fieldNumber: 2) + } + if !self.commitHash.isEmpty { + try visitor.visitSingularBytesField(value: self.commitHash, fieldNumber: 3) + } + if !self.rootHash.isEmpty { + try visitor.visitSingularBytesField(value: self.rootHash, fieldNumber: 4) + } + if !self.message.isEmpty { + try visitor.visitSingularBytesField(value: self.message, fieldNumber: 5) + } + if self.encapsulatedID != 0 { + try visitor.visitSingularUInt32Field(value: self.encapsulatedID, fieldNumber: 6) + } + if self.encapsulatedTo != 0 { + try visitor.visitSingularUInt32Field(value: self.encapsulatedTo, fieldNumber: 7) + } + if self.encapsulatedFrom != 0 { + try visitor.visitSingularUInt32Field(value: self.encapsulatedFrom, fieldNumber: 8) + } + if self.encapsulatedRxtime != 0 { + try visitor.visitSingularUInt32Field(value: self.encapsulatedRxtime, fieldNumber: 9) + } + try unknownFields.traverse(visitor: &visitor) + } + + public static func ==(lhs: StoreForwardPlusPlus, rhs: StoreForwardPlusPlus) -> Bool { + if lhs.sfppMessageType != rhs.sfppMessageType {return false} + if lhs.messageHash != rhs.messageHash {return false} + if lhs.commitHash != rhs.commitHash {return false} + if lhs.rootHash != rhs.rootHash {return false} + if lhs.message != rhs.message {return false} + if lhs.encapsulatedID != rhs.encapsulatedID {return false} + if lhs.encapsulatedTo != rhs.encapsulatedTo {return false} + if lhs.encapsulatedFrom != rhs.encapsulatedFrom {return false} + if lhs.encapsulatedRxtime != rhs.encapsulatedRxtime {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension StoreForwardPlusPlus.SFPP_message_type: SwiftProtobuf._ProtoNameProviding { + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0CANON_ANNOUNCE\0\u{1}CHAIN_QUERY\0\u{2}\u{2}LINK_REQUEST\0\u{1}LINK_PROVIDE\0\u{1}LINK_PROVIDE_FIRSTHALF\0\u{1}LINK_PROVIDE_SECONDHALF\0") +} + extension Waypoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Waypoint" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "id"), - 2: .standard(proto: "latitude_i"), - 3: .standard(proto: "longitude_i"), - 4: .same(proto: "expire"), - 5: .standard(proto: "locked_to"), - 6: .same(proto: "name"), - 7: .same(proto: "description"), - 8: .same(proto: "icon"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}id\0\u{3}latitude_i\0\u{3}longitude_i\0\u{1}expire\0\u{3}locked_to\0\u{1}name\0\u{1}description\0\u{1}icon\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -5018,12 +4671,7 @@ extension Waypoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB extension MqttClientProxyMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".MqttClientProxyMessage" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "topic"), - 2: .same(proto: "data"), - 3: .same(proto: "text"), - 4: .same(proto: "retained"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}topic\0\u{1}data\0\u{1}text\0\u{1}retained\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -5090,29 +4738,7 @@ extension MqttClientProxyMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageI extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".MeshPacket" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "from"), - 2: .same(proto: "to"), - 3: .same(proto: "channel"), - 4: .same(proto: "decoded"), - 5: .same(proto: "encrypted"), - 6: .same(proto: "id"), - 7: .standard(proto: "rx_time"), - 8: .standard(proto: "rx_snr"), - 9: .standard(proto: "hop_limit"), - 10: .standard(proto: "want_ack"), - 11: .same(proto: "priority"), - 12: .standard(proto: "rx_rssi"), - 13: .same(proto: "delayed"), - 14: .standard(proto: "via_mqtt"), - 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"), - 20: .standard(proto: "tx_after"), - 21: .standard(proto: "transport_mechanism"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}from\0\u{1}to\0\u{1}channel\0\u{1}decoded\0\u{1}encrypted\0\u{1}id\0\u{3}rx_time\0\u{3}rx_snr\0\u{3}hop_limit\0\u{3}want_ack\0\u{1}priority\0\u{3}rx_rssi\0\u{1}delayed\0\u{3}via_mqtt\0\u{3}hop_start\0\u{3}public_key\0\u{3}pki_encrypted\0\u{3}next_hop\0\u{3}relay_node\0\u{3}tx_after\0\u{3}transport_mechanism\0") fileprivate class _StorageClass { var _from: UInt32 = 0 @@ -5136,15 +4762,11 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio var _txAfter: UInt32 = 0 var _transportMechanism: MeshPacket.TransportMechanism = .transportInternal - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} @@ -5265,7 +4887,7 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if _storage._rxTime != 0 { try visitor.visitSingularFixed32Field(value: _storage._rxTime, fieldNumber: 7) } - if _storage._rxSnr != 0 { + if _storage._rxSnr.bitPattern != 0 { try visitor.visitSingularFloatField(value: _storage._rxSnr, fieldNumber: 8) } if _storage._hopLimit != 0 { @@ -5346,57 +4968,20 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio } extension MeshPacket.Priority: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNSET"), - 1: .same(proto: "MIN"), - 10: .same(proto: "BACKGROUND"), - 64: .same(proto: "DEFAULT"), - 70: .same(proto: "RELIABLE"), - 80: .same(proto: "RESPONSE"), - 100: .same(proto: "HIGH"), - 110: .same(proto: "ALERT"), - 120: .same(proto: "ACK"), - 127: .same(proto: "MAX"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNSET\0\u{1}MIN\0\u{2}\u{9}BACKGROUND\0\u{2}6DEFAULT\0\u{2}\u{6}RELIABLE\0\u{2}\u{a}RESPONSE\0\u{2}\u{14}HIGH\0\u{2}\u{a}ALERT\0\u{2}\u{a}ACK\0\u{2}\u{7}MAX\0") } extension MeshPacket.Delayed: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "NO_DELAY"), - 1: .same(proto: "DELAYED_BROADCAST"), - 2: .same(proto: "DELAYED_DIRECT"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0NO_DELAY\0\u{1}DELAYED_BROADCAST\0\u{1}DELAYED_DIRECT\0") } extension MeshPacket.TransportMechanism: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "TRANSPORT_INTERNAL"), - 1: .same(proto: "TRANSPORT_LORA"), - 2: .same(proto: "TRANSPORT_LORA_ALT1"), - 3: .same(proto: "TRANSPORT_LORA_ALT2"), - 4: .same(proto: "TRANSPORT_LORA_ALT3"), - 5: .same(proto: "TRANSPORT_MQTT"), - 6: .same(proto: "TRANSPORT_MULTICAST_UDP"), - 7: .same(proto: "TRANSPORT_API"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0TRANSPORT_INTERNAL\0\u{1}TRANSPORT_LORA\0\u{1}TRANSPORT_LORA_ALT1\0\u{1}TRANSPORT_LORA_ALT2\0\u{1}TRANSPORT_LORA_ALT3\0\u{1}TRANSPORT_MQTT\0\u{1}TRANSPORT_MULTICAST_UDP\0\u{1}TRANSPORT_API\0") } extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".NodeInfo" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "num"), - 2: .same(proto: "user"), - 3: .same(proto: "position"), - 4: .same(proto: "snr"), - 5: .standard(proto: "last_heard"), - 6: .standard(proto: "device_metrics"), - 7: .same(proto: "channel"), - 8: .standard(proto: "via_mqtt"), - 9: .standard(proto: "hops_away"), - 10: .standard(proto: "is_favorite"), - 11: .standard(proto: "is_ignored"), - 12: .standard(proto: "is_key_manually_verified"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}num\0\u{1}user\0\u{1}position\0\u{1}snr\0\u{3}last_heard\0\u{3}device_metrics\0\u{1}channel\0\u{3}via_mqtt\0\u{3}hops_away\0\u{3}is_favorite\0\u{3}is_ignored\0\u{3}is_key_manually_verified\0") fileprivate class _StorageClass { var _num: UInt32 = 0 @@ -5412,15 +4997,11 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB var _isIgnored: Bool = false var _isKeyManuallyVerified: Bool = false - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} @@ -5488,7 +5069,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB try { if let v = _storage._position { try visitor.visitSingularMessageField(value: v, fieldNumber: 3) } }() - if _storage._snr != 0 { + if _storage._snr.bitPattern != 0 { try visitor.visitSingularFloatField(value: _storage._snr, fieldNumber: 4) } if _storage._lastHeard != 0 { @@ -5547,15 +5128,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".MyNodeInfo" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "my_node_num"), - 8: .standard(proto: "reboot_count"), - 11: .standard(proto: "min_app_version"), - 12: .standard(proto: "device_id"), - 13: .standard(proto: "pio_env"), - 14: .standard(proto: "firmware_edition"), - 15: .standard(proto: "nodedb_count"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}my_node_num\0\u{4}\u{7}reboot_count\0\u{4}\u{3}min_app_version\0\u{3}device_id\0\u{3}pio_env\0\u{3}firmware_edition\0\u{3}nodedb_count\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -5615,12 +5188,7 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio extension LogRecord: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".LogRecord" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "message"), - 2: .same(proto: "time"), - 3: .same(proto: "source"), - 4: .same(proto: "level"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}message\0\u{1}time\0\u{1}source\0\u{1}level\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -5664,25 +5232,12 @@ extension LogRecord: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation } extension LogRecord.Level: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNSET"), - 5: .same(proto: "TRACE"), - 10: .same(proto: "DEBUG"), - 20: .same(proto: "INFO"), - 30: .same(proto: "WARNING"), - 40: .same(proto: "ERROR"), - 50: .same(proto: "CRITICAL"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNSET\0\u{2}\u{5}TRACE\0\u{2}\u{5}DEBUG\0\u{2}\u{a}INFO\0\u{2}\u{a}WARNING\0\u{2}\u{a}ERROR\0\u{2}\u{a}CRITICAL\0") } extension QueueStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".QueueStatus" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "res"), - 2: .same(proto: "free"), - 3: .same(proto: "maxlen"), - 4: .standard(proto: "mesh_packet_id"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}res\0\u{1}free\0\u{1}maxlen\0\u{3}mesh_packet_id\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -5727,25 +5282,7 @@ extension QueueStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".FromRadio" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "id"), - 2: .same(proto: "packet"), - 3: .standard(proto: "my_info"), - 4: .standard(proto: "node_info"), - 5: .same(proto: "config"), - 6: .standard(proto: "log_record"), - 7: .standard(proto: "config_complete_id"), - 8: .same(proto: "rebooted"), - 9: .same(proto: "moduleConfig"), - 10: .same(proto: "channel"), - 11: .same(proto: "queueStatus"), - 12: .same(proto: "xmodemPacket"), - 13: .same(proto: "metadata"), - 14: .same(proto: "mqttClientProxyMessage"), - 15: .same(proto: "fileInfo"), - 16: .same(proto: "clientNotification"), - 17: .same(proto: "deviceuiConfig"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}id\0\u{1}packet\0\u{3}my_info\0\u{3}node_info\0\u{1}config\0\u{3}log_record\0\u{3}config_complete_id\0\u{1}rebooted\0\u{1}moduleConfig\0\u{1}channel\0\u{1}queueStatus\0\u{1}xmodemPacket\0\u{1}metadata\0\u{1}mqttClientProxyMessage\0\u{1}fileInfo\0\u{1}clientNotification\0\u{1}deviceuiConfig\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6045,17 +5582,7 @@ extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation extension ClientNotification: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ClientNotification" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "reply_id"), - 2: .same(proto: "time"), - 3: .same(proto: "level"), - 4: .same(proto: "message"), - 11: .standard(proto: "key_verification_number_inform"), - 12: .standard(proto: "key_verification_number_request"), - 13: .standard(proto: "key_verification_final"), - 14: .standard(proto: "duplicated_public_key"), - 15: .standard(proto: "low_entropy_key"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}reply_id\0\u{1}time\0\u{1}level\0\u{1}message\0\u{4}\u{7}key_verification_number_inform\0\u{3}key_verification_number_request\0\u{3}key_verification_final\0\u{3}duplicated_public_key\0\u{3}low_entropy_key\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6193,11 +5720,7 @@ extension ClientNotification: SwiftProtobuf.Message, SwiftProtobuf._MessageImple extension KeyVerificationNumberInform: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".KeyVerificationNumberInform" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "nonce"), - 2: .standard(proto: "remote_longname"), - 3: .standard(proto: "security_number"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}nonce\0\u{3}remote_longname\0\u{3}security_number\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6237,10 +5760,7 @@ extension KeyVerificationNumberInform: SwiftProtobuf.Message, SwiftProtobuf._Mes extension KeyVerificationNumberRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".KeyVerificationNumberRequest" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "nonce"), - 2: .standard(proto: "remote_longname"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}nonce\0\u{3}remote_longname\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6275,12 +5795,7 @@ extension KeyVerificationNumberRequest: SwiftProtobuf.Message, SwiftProtobuf._Me extension KeyVerificationFinal: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".KeyVerificationFinal" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "nonce"), - 2: .standard(proto: "remote_longname"), - 3: .same(proto: "isSender"), - 4: .standard(proto: "verification_characters"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}nonce\0\u{3}remote_longname\0\u{1}isSender\0\u{3}verification_characters\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6328,8 +5843,8 @@ extension DuplicatedPublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } + // Load everything into unknown fields + while try decoder.nextFieldNumber() != nil {} } public func traverse(visitor: inout V) throws { @@ -6347,8 +5862,8 @@ extension LowEntropyKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } + // Load everything into unknown fields + while try decoder.nextFieldNumber() != nil {} } public func traverse(visitor: inout V) throws { @@ -6363,10 +5878,7 @@ extension LowEntropyKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa extension FileInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".FileInfo" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "file_name"), - 2: .standard(proto: "size_bytes"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}file_name\0\u{3}size_bytes\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6401,14 +5913,7 @@ extension FileInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB extension ToRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ToRadio" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "packet"), - 3: .standard(proto: "want_config_id"), - 4: .same(proto: "disconnect"), - 5: .same(proto: "xmodemPacket"), - 6: .same(proto: "mqttClientProxyMessage"), - 7: .same(proto: "heartbeat"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}packet\0\u{4}\u{2}want_config_id\0\u{1}disconnect\0\u{1}xmodemPacket\0\u{1}mqttClientProxyMessage\0\u{1}heartbeat\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6533,10 +6038,7 @@ extension ToRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa extension Compressed: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Compressed" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "portnum"), - 2: .same(proto: "data"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}portnum\0\u{1}data\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6571,12 +6073,7 @@ extension Compressed: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio extension NeighborInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".NeighborInfo" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "node_id"), - 2: .standard(proto: "last_sent_by_id"), - 3: .standard(proto: "node_broadcast_interval_secs"), - 4: .same(proto: "neighbors"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}node_id\0\u{3}last_sent_by_id\0\u{3}node_broadcast_interval_secs\0\u{1}neighbors\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6621,12 +6118,7 @@ extension NeighborInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat extension Neighbor: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Neighbor" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "node_id"), - 2: .same(proto: "snr"), - 3: .standard(proto: "last_rx_time"), - 4: .standard(proto: "node_broadcast_interval_secs"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}node_id\0\u{1}snr\0\u{3}last_rx_time\0\u{3}node_broadcast_interval_secs\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6647,7 +6139,7 @@ extension Neighbor: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB if self.nodeID != 0 { try visitor.visitSingularUInt32Field(value: self.nodeID, fieldNumber: 1) } - if self.snr != 0 { + if self.snr.bitPattern != 0 { try visitor.visitSingularFloatField(value: self.snr, fieldNumber: 2) } if self.lastRxTime != 0 { @@ -6671,20 +6163,7 @@ extension Neighbor: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB extension DeviceMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".DeviceMetadata" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "firmware_version"), - 2: .standard(proto: "device_state_version"), - 3: .same(proto: "canShutdown"), - 4: .same(proto: "hasWifi"), - 5: .same(proto: "hasBluetooth"), - 6: .same(proto: "hasEthernet"), - 7: .same(proto: "role"), - 8: .standard(proto: "position_flags"), - 9: .standard(proto: "hw_model"), - 10: .same(proto: "hasRemoteHardware"), - 11: .same(proto: "hasPKC"), - 12: .standard(proto: "excluded_modules"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}firmware_version\0\u{3}device_state_version\0\u{1}canShutdown\0\u{1}hasWifi\0\u{1}hasBluetooth\0\u{1}hasEthernet\0\u{1}role\0\u{3}position_flags\0\u{3}hw_model\0\u{1}hasRemoteHardware\0\u{1}hasPKC\0\u{3}excluded_modules\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6769,9 +6248,7 @@ extension DeviceMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement extension Heartbeat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Heartbeat" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "nonce"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}nonce\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6801,10 +6278,7 @@ extension Heartbeat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation extension NodeRemoteHardwarePin: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".NodeRemoteHardwarePin" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "node_num"), - 2: .same(proto: "pin"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}node_num\0\u{1}pin\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6843,12 +6317,7 @@ extension NodeRemoteHardwarePin: SwiftProtobuf.Message, SwiftProtobuf._MessageIm extension ChunkedPayload: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ChunkedPayload" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "payload_id"), - 2: .standard(proto: "chunk_count"), - 3: .standard(proto: "chunk_index"), - 4: .standard(proto: "payload_chunk"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}payload_id\0\u{3}chunk_count\0\u{3}chunk_index\0\u{3}payload_chunk\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6893,9 +6362,7 @@ extension ChunkedPayload: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement extension resend_chunks: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".resend_chunks" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "chunks"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}chunks\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6925,12 +6392,7 @@ extension resend_chunks: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa extension ChunkedPayloadResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ChunkedPayloadResponse" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "payload_id"), - 2: .standard(proto: "request_transfer"), - 3: .standard(proto: "accept_transfer"), - 4: .standard(proto: "resend_chunks"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}payload_id\0\u{3}request_transfer\0\u{3}accept_transfer\0\u{3}resend_chunks\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift index 5bf37457..1bff36a2 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/module_config.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum RemoteHardwarePinType: SwiftProtobuf.Enum { +public enum RemoteHardwarePinType: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -58,24 +58,18 @@ public enum RemoteHardwarePinType: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension RemoteHardwarePinType: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [RemoteHardwarePinType] = [ .unknown, .digitalRead, .digitalWrite, ] -} -#endif // swift(>=4.2) +} /// /// Module Config -public struct ModuleConfig { +public struct ModuleConfig: Sendable { // 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. @@ -218,7 +212,7 @@ public struct ModuleConfig { /// /// TODO: REPLACE - public enum OneOf_PayloadVariant: Equatable { + public enum OneOf_PayloadVariant: Equatable, Sendable { /// /// TODO: REPLACE case mqtt(ModuleConfig.MQTTConfig) @@ -259,73 +253,11 @@ public struct ModuleConfig { /// TODO: REPLACE case paxcounter(ModuleConfig.PaxcounterConfig) - #if !swift(>=4.1) - public static func ==(lhs: ModuleConfig.OneOf_PayloadVariant, rhs: ModuleConfig.OneOf_PayloadVariant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.mqtt, .mqtt): return { - guard case .mqtt(let l) = lhs, case .mqtt(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.serial, .serial): return { - guard case .serial(let l) = lhs, case .serial(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.externalNotification, .externalNotification): return { - guard case .externalNotification(let l) = lhs, case .externalNotification(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.storeForward, .storeForward): return { - guard case .storeForward(let l) = lhs, case .storeForward(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.rangeTest, .rangeTest): return { - guard case .rangeTest(let l) = lhs, case .rangeTest(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.telemetry, .telemetry): return { - guard case .telemetry(let l) = lhs, case .telemetry(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.cannedMessage, .cannedMessage): return { - guard case .cannedMessage(let l) = lhs, case .cannedMessage(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.audio, .audio): return { - guard case .audio(let l) = lhs, case .audio(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.remoteHardware, .remoteHardware): return { - guard case .remoteHardware(let l) = lhs, case .remoteHardware(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.neighborInfo, .neighborInfo): return { - guard case .neighborInfo(let l) = lhs, case .neighborInfo(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.ambientLighting, .ambientLighting): return { - guard case .ambientLighting(let l) = lhs, case .ambientLighting(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.detectionSensor, .detectionSensor): return { - guard case .detectionSensor(let l) = lhs, case .detectionSensor(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.paxcounter, .paxcounter): return { - guard case .paxcounter(let l) = lhs, case .paxcounter(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } /// /// MQTT Client Config - public struct MQTTConfig { + public struct MQTTConfig: Sendable { // 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. @@ -400,7 +332,7 @@ public struct ModuleConfig { /// /// Settings for reporting unencrypted information about our node to a map via MQTT - public struct MapReportSettings { + public struct MapReportSettings: Sendable { // 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. @@ -424,7 +356,7 @@ public struct ModuleConfig { /// /// RemoteHardwareModule Config - public struct RemoteHardwareConfig { + public struct RemoteHardwareConfig: Sendable { // 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. @@ -448,7 +380,7 @@ public struct ModuleConfig { /// /// NeighborInfoModule Config - public struct NeighborInfoConfig { + public struct NeighborInfoConfig: Sendable { // 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. @@ -474,7 +406,7 @@ public struct ModuleConfig { /// /// Detection Sensor Module Config - public struct DetectionSensorConfig { + public struct DetectionSensorConfig: Sendable { // 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. @@ -521,7 +453,7 @@ public struct ModuleConfig { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum TriggerType: SwiftProtobuf.Enum { + public enum TriggerType: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// Event is triggered if pin is low @@ -573,6 +505,16 @@ public struct ModuleConfig { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.DetectionSensorConfig.TriggerType] = [ + .logicLow, + .logicHigh, + .fallingEdge, + .risingEdge, + .eitherEdgeActiveLow, + .eitherEdgeActiveHigh, + ] + } public init() {} @@ -580,7 +522,7 @@ public struct ModuleConfig { /// /// Audio Config for codec2 voice - public struct AudioConfig { + public struct AudioConfig: Sendable { // 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. @@ -617,7 +559,7 @@ public struct ModuleConfig { /// /// Baudrate for codec2 voice - public enum Audio_Baud: SwiftProtobuf.Enum { + public enum Audio_Baud: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int case codec2Default // = 0 case codec23200 // = 1 @@ -664,6 +606,19 @@ public struct ModuleConfig { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.AudioConfig.Audio_Baud] = [ + .codec2Default, + .codec23200, + .codec22400, + .codec21600, + .codec21400, + .codec21300, + .codec21200, + .codec2700, + .codec2700B, + ] + } public init() {} @@ -671,7 +626,7 @@ public struct ModuleConfig { /// /// Config for the Paxcounter Module - public struct PaxcounterConfig { + public struct PaxcounterConfig: Sendable { // 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. @@ -697,7 +652,7 @@ public struct ModuleConfig { /// /// Serial Config - public struct SerialConfig { + public struct SerialConfig: Sendable { // 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. @@ -740,7 +695,7 @@ public struct ModuleConfig { /// /// TODO: REPLACE - public enum Serial_Baud: SwiftProtobuf.Enum { + public enum Serial_Baud: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int case baudDefault // = 0 case baud110 // = 1 @@ -808,11 +763,31 @@ public struct ModuleConfig { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.SerialConfig.Serial_Baud] = [ + .baudDefault, + .baud110, + .baud300, + .baud600, + .baud1200, + .baud2400, + .baud4800, + .baud9600, + .baud19200, + .baud38400, + .baud57600, + .baud115200, + .baud230400, + .baud460800, + .baud576000, + .baud921600, + ] + } /// /// TODO: REPLACE - public enum Serial_Mode: SwiftProtobuf.Enum { + public enum Serial_Mode: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int case `default` // = 0 case simple // = 1 @@ -869,6 +844,19 @@ public struct ModuleConfig { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.SerialConfig.Serial_Mode] = [ + .default, + .simple, + .proto, + .textmsg, + .nmea, + .caltopo, + .ws85, + .veDirect, + .msConfig, + ] + } public init() {} @@ -876,7 +864,7 @@ public struct ModuleConfig { /// /// External Notifications Config - public struct ExternalNotificationConfig { + public struct ExternalNotificationConfig: Sendable { // 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. @@ -959,7 +947,7 @@ public struct ModuleConfig { /// /// Store and Forward Module Config - public struct StoreForwardConfig { + public struct StoreForwardConfig: Sendable { // 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. @@ -995,7 +983,7 @@ public struct ModuleConfig { /// /// Preferences for the RangeTestModule - public struct RangeTestConfig { + public struct RangeTestConfig: Sendable { // 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. @@ -1025,7 +1013,7 @@ public struct ModuleConfig { /// /// Configuration for both device and environment metrics - public struct TelemetryConfig { + public struct TelemetryConfig: Sendable { // 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. @@ -1099,7 +1087,7 @@ public struct ModuleConfig { /// /// Canned Messages Module Config - public struct CannedMessageConfig { + public struct CannedMessageConfig: Sendable { // 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. @@ -1138,11 +1126,15 @@ public struct ModuleConfig { /// /// Enable/disable CannedMessageModule. + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var enabled: Bool = false /// /// Input event origin accepted by the canned message module. /// Can be e.g. "rotEnc1", "upDownEnc1", "scanAndSelect", "cardkb", "serialkb", or keyword "_any" + /// + /// NOTE: This field was marked as deprecated in the .proto file. public var allowInputSource: String = String() /// @@ -1154,7 +1146,7 @@ public struct ModuleConfig { /// /// TODO: REPLACE - public enum InputEventChar: SwiftProtobuf.Enum { + public enum InputEventChar: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -1222,6 +1214,18 @@ public struct ModuleConfig { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.CannedMessageConfig.InputEventChar] = [ + .none, + .up, + .down, + .left, + .right, + .select, + .back, + .cancel, + ] + } public init() {} @@ -1230,7 +1234,7 @@ public struct ModuleConfig { /// ///Ambient Lighting Module - Settings for control of onboard LEDs to allow users to adjust the brightness levels and respective color levels. ///Initially created for the RAK14001 RGB LED module. - public struct AmbientLightingConfig { + public struct AmbientLightingConfig: Sendable { // 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. @@ -1263,91 +1267,9 @@ public struct ModuleConfig { public init() {} } -#if swift(>=4.2) - -extension ModuleConfig.DetectionSensorConfig.TriggerType: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.DetectionSensorConfig.TriggerType] = [ - .logicLow, - .logicHigh, - .fallingEdge, - .risingEdge, - .eitherEdgeActiveLow, - .eitherEdgeActiveHigh, - ] -} - -extension ModuleConfig.AudioConfig.Audio_Baud: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.AudioConfig.Audio_Baud] = [ - .codec2Default, - .codec23200, - .codec22400, - .codec21600, - .codec21400, - .codec21300, - .codec21200, - .codec2700, - .codec2700B, - ] -} - -extension ModuleConfig.SerialConfig.Serial_Baud: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.SerialConfig.Serial_Baud] = [ - .baudDefault, - .baud110, - .baud300, - .baud600, - .baud1200, - .baud2400, - .baud4800, - .baud9600, - .baud19200, - .baud38400, - .baud57600, - .baud115200, - .baud230400, - .baud460800, - .baud576000, - .baud921600, - ] -} - -extension ModuleConfig.SerialConfig.Serial_Mode: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.SerialConfig.Serial_Mode] = [ - .default, - .simple, - .proto, - .textmsg, - .nmea, - .caltopo, - .ws85, - .veDirect, - .msConfig, - ] -} - -extension ModuleConfig.CannedMessageConfig.InputEventChar: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.CannedMessageConfig.InputEventChar] = [ - .none, - .up, - .down, - .left, - .right, - .select, - .back, - .cancel, - ] -} - -#endif // swift(>=4.2) - /// /// A GPIO pin definition for remote hardware module -public struct RemoteHardwarePin { +public struct RemoteHardwarePin: Sendable { // 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. @@ -1369,61 +1291,17 @@ public struct RemoteHardwarePin { public init() {} } -#if swift(>=5.5) && canImport(_Concurrency) -extension RemoteHardwarePinType: @unchecked Sendable {} -extension ModuleConfig: @unchecked Sendable {} -extension ModuleConfig.OneOf_PayloadVariant: @unchecked Sendable {} -extension ModuleConfig.MQTTConfig: @unchecked Sendable {} -extension ModuleConfig.MapReportSettings: @unchecked Sendable {} -extension ModuleConfig.RemoteHardwareConfig: @unchecked Sendable {} -extension ModuleConfig.NeighborInfoConfig: @unchecked Sendable {} -extension ModuleConfig.DetectionSensorConfig: @unchecked Sendable {} -extension ModuleConfig.DetectionSensorConfig.TriggerType: @unchecked Sendable {} -extension ModuleConfig.AudioConfig: @unchecked Sendable {} -extension ModuleConfig.AudioConfig.Audio_Baud: @unchecked Sendable {} -extension ModuleConfig.PaxcounterConfig: @unchecked Sendable {} -extension ModuleConfig.SerialConfig: @unchecked Sendable {} -extension ModuleConfig.SerialConfig.Serial_Baud: @unchecked Sendable {} -extension ModuleConfig.SerialConfig.Serial_Mode: @unchecked Sendable {} -extension ModuleConfig.ExternalNotificationConfig: @unchecked Sendable {} -extension ModuleConfig.StoreForwardConfig: @unchecked Sendable {} -extension ModuleConfig.RangeTestConfig: @unchecked Sendable {} -extension ModuleConfig.TelemetryConfig: @unchecked Sendable {} -extension ModuleConfig.CannedMessageConfig: @unchecked Sendable {} -extension ModuleConfig.CannedMessageConfig.InputEventChar: @unchecked Sendable {} -extension ModuleConfig.AmbientLightingConfig: @unchecked Sendable {} -extension RemoteHardwarePin: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension RemoteHardwarePinType: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN"), - 1: .same(proto: "DIGITAL_READ"), - 2: .same(proto: "DIGITAL_WRITE"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNKNOWN\0\u{1}DIGITAL_READ\0\u{1}DIGITAL_WRITE\0") } extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ModuleConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "mqtt"), - 2: .same(proto: "serial"), - 3: .standard(proto: "external_notification"), - 4: .standard(proto: "store_forward"), - 5: .standard(proto: "range_test"), - 6: .same(proto: "telemetry"), - 7: .standard(proto: "canned_message"), - 8: .same(proto: "audio"), - 9: .standard(proto: "remote_hardware"), - 10: .standard(proto: "neighbor_info"), - 11: .standard(proto: "ambient_lighting"), - 12: .standard(proto: "detection_sensor"), - 13: .same(proto: "paxcounter"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}mqtt\0\u{1}serial\0\u{3}external_notification\0\u{3}store_forward\0\u{3}range_test\0\u{1}telemetry\0\u{3}canned_message\0\u{1}audio\0\u{3}remote_hardware\0\u{3}neighbor_info\0\u{3}ambient_lighting\0\u{3}detection_sensor\0\u{1}paxcounter\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -1677,19 +1555,7 @@ extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat extension ModuleConfig.MQTTConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".MQTTConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "enabled"), - 2: .same(proto: "address"), - 3: .same(proto: "username"), - 4: .same(proto: "password"), - 5: .standard(proto: "encryption_enabled"), - 6: .standard(proto: "json_enabled"), - 7: .standard(proto: "tls_enabled"), - 8: .same(proto: "root"), - 9: .standard(proto: "proxy_to_client_enabled"), - 10: .standard(proto: "map_reporting_enabled"), - 11: .standard(proto: "map_report_settings"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}enabled\0\u{1}address\0\u{1}username\0\u{1}password\0\u{3}encryption_enabled\0\u{3}json_enabled\0\u{3}tls_enabled\0\u{1}root\0\u{3}proxy_to_client_enabled\0\u{3}map_reporting_enabled\0\u{3}map_report_settings\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -1773,11 +1639,7 @@ extension ModuleConfig.MQTTConfig: SwiftProtobuf.Message, SwiftProtobuf._Message extension ModuleConfig.MapReportSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".MapReportSettings" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "publish_interval_secs"), - 2: .standard(proto: "position_precision"), - 3: .standard(proto: "should_report_location"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}publish_interval_secs\0\u{3}position_precision\0\u{3}should_report_location\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -1817,11 +1679,7 @@ extension ModuleConfig.MapReportSettings: SwiftProtobuf.Message, SwiftProtobuf._ extension ModuleConfig.RemoteHardwareConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".RemoteHardwareConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "enabled"), - 2: .standard(proto: "allow_undefined_pin_access"), - 3: .standard(proto: "available_pins"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}enabled\0\u{3}allow_undefined_pin_access\0\u{3}available_pins\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -1861,11 +1719,7 @@ extension ModuleConfig.RemoteHardwareConfig: SwiftProtobuf.Message, SwiftProtobu extension ModuleConfig.NeighborInfoConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".NeighborInfoConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "enabled"), - 2: .standard(proto: "update_interval"), - 3: .standard(proto: "transmit_over_lora"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}enabled\0\u{3}update_interval\0\u{3}transmit_over_lora\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -1905,16 +1759,7 @@ extension ModuleConfig.NeighborInfoConfig: SwiftProtobuf.Message, SwiftProtobuf. extension ModuleConfig.DetectionSensorConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".DetectionSensorConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "enabled"), - 2: .standard(proto: "minimum_broadcast_secs"), - 3: .standard(proto: "state_broadcast_secs"), - 4: .standard(proto: "send_bell"), - 5: .same(proto: "name"), - 6: .standard(proto: "monitor_pin"), - 7: .standard(proto: "detection_trigger_type"), - 8: .standard(proto: "use_pullup"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}enabled\0\u{3}minimum_broadcast_secs\0\u{3}state_broadcast_secs\0\u{3}send_bell\0\u{1}name\0\u{3}monitor_pin\0\u{3}detection_trigger_type\0\u{3}use_pullup\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -1978,27 +1823,12 @@ extension ModuleConfig.DetectionSensorConfig: SwiftProtobuf.Message, SwiftProtob } extension ModuleConfig.DetectionSensorConfig.TriggerType: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "LOGIC_LOW"), - 1: .same(proto: "LOGIC_HIGH"), - 2: .same(proto: "FALLING_EDGE"), - 3: .same(proto: "RISING_EDGE"), - 4: .same(proto: "EITHER_EDGE_ACTIVE_LOW"), - 5: .same(proto: "EITHER_EDGE_ACTIVE_HIGH"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0LOGIC_LOW\0\u{1}LOGIC_HIGH\0\u{1}FALLING_EDGE\0\u{1}RISING_EDGE\0\u{1}EITHER_EDGE_ACTIVE_LOW\0\u{1}EITHER_EDGE_ACTIVE_HIGH\0") } extension ModuleConfig.AudioConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".AudioConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "codec2_enabled"), - 2: .standard(proto: "ptt_pin"), - 3: .same(proto: "bitrate"), - 4: .standard(proto: "i2s_ws"), - 5: .standard(proto: "i2s_sd"), - 6: .standard(proto: "i2s_din"), - 7: .standard(proto: "i2s_sck"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}codec2_enabled\0\u{3}ptt_pin\0\u{1}bitrate\0\u{3}i2s_ws\0\u{3}i2s_sd\0\u{3}i2s_din\0\u{3}i2s_sck\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2057,27 +1887,12 @@ extension ModuleConfig.AudioConfig: SwiftProtobuf.Message, SwiftProtobuf._Messag } extension ModuleConfig.AudioConfig.Audio_Baud: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "CODEC2_DEFAULT"), - 1: .same(proto: "CODEC2_3200"), - 2: .same(proto: "CODEC2_2400"), - 3: .same(proto: "CODEC2_1600"), - 4: .same(proto: "CODEC2_1400"), - 5: .same(proto: "CODEC2_1300"), - 6: .same(proto: "CODEC2_1200"), - 7: .same(proto: "CODEC2_700"), - 8: .same(proto: "CODEC2_700B"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0CODEC2_DEFAULT\0\u{1}CODEC2_3200\0\u{1}CODEC2_2400\0\u{1}CODEC2_1600\0\u{1}CODEC2_1400\0\u{1}CODEC2_1300\0\u{1}CODEC2_1200\0\u{1}CODEC2_700\0\u{1}CODEC2_700B\0") } extension ModuleConfig.PaxcounterConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".PaxcounterConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "enabled"), - 2: .standard(proto: "paxcounter_update_interval"), - 3: .standard(proto: "wifi_threshold"), - 4: .standard(proto: "ble_threshold"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}enabled\0\u{3}paxcounter_update_interval\0\u{3}wifi_threshold\0\u{3}ble_threshold\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2122,16 +1937,7 @@ extension ModuleConfig.PaxcounterConfig: SwiftProtobuf.Message, SwiftProtobuf._M extension ModuleConfig.SerialConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".SerialConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "enabled"), - 2: .same(proto: "echo"), - 3: .same(proto: "rxd"), - 4: .same(proto: "txd"), - 5: .same(proto: "baud"), - 6: .same(proto: "timeout"), - 7: .same(proto: "mode"), - 8: .standard(proto: "override_console_serial_port"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}enabled\0\u{1}echo\0\u{1}rxd\0\u{1}txd\0\u{1}baud\0\u{1}timeout\0\u{1}mode\0\u{3}override_console_serial_port\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2195,59 +2001,16 @@ extension ModuleConfig.SerialConfig: SwiftProtobuf.Message, SwiftProtobuf._Messa } extension ModuleConfig.SerialConfig.Serial_Baud: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "BAUD_DEFAULT"), - 1: .same(proto: "BAUD_110"), - 2: .same(proto: "BAUD_300"), - 3: .same(proto: "BAUD_600"), - 4: .same(proto: "BAUD_1200"), - 5: .same(proto: "BAUD_2400"), - 6: .same(proto: "BAUD_4800"), - 7: .same(proto: "BAUD_9600"), - 8: .same(proto: "BAUD_19200"), - 9: .same(proto: "BAUD_38400"), - 10: .same(proto: "BAUD_57600"), - 11: .same(proto: "BAUD_115200"), - 12: .same(proto: "BAUD_230400"), - 13: .same(proto: "BAUD_460800"), - 14: .same(proto: "BAUD_576000"), - 15: .same(proto: "BAUD_921600"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0BAUD_DEFAULT\0\u{1}BAUD_110\0\u{1}BAUD_300\0\u{1}BAUD_600\0\u{1}BAUD_1200\0\u{1}BAUD_2400\0\u{1}BAUD_4800\0\u{1}BAUD_9600\0\u{1}BAUD_19200\0\u{1}BAUD_38400\0\u{1}BAUD_57600\0\u{1}BAUD_115200\0\u{1}BAUD_230400\0\u{1}BAUD_460800\0\u{1}BAUD_576000\0\u{1}BAUD_921600\0") } extension ModuleConfig.SerialConfig.Serial_Mode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DEFAULT"), - 1: .same(proto: "SIMPLE"), - 2: .same(proto: "PROTO"), - 3: .same(proto: "TEXTMSG"), - 4: .same(proto: "NMEA"), - 5: .same(proto: "CALTOPO"), - 6: .same(proto: "WS85"), - 7: .same(proto: "VE_DIRECT"), - 8: .same(proto: "MS_CONFIG"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DEFAULT\0\u{1}SIMPLE\0\u{1}PROTO\0\u{1}TEXTMSG\0\u{1}NMEA\0\u{1}CALTOPO\0\u{1}WS85\0\u{1}VE_DIRECT\0\u{1}MS_CONFIG\0") } extension ModuleConfig.ExternalNotificationConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".ExternalNotificationConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "enabled"), - 2: .standard(proto: "output_ms"), - 3: .same(proto: "output"), - 8: .standard(proto: "output_vibra"), - 9: .standard(proto: "output_buzzer"), - 4: .same(proto: "active"), - 5: .standard(proto: "alert_message"), - 10: .standard(proto: "alert_message_vibra"), - 11: .standard(proto: "alert_message_buzzer"), - 6: .standard(proto: "alert_bell"), - 12: .standard(proto: "alert_bell_vibra"), - 13: .standard(proto: "alert_bell_buzzer"), - 7: .standard(proto: "use_pwm"), - 14: .standard(proto: "nag_timeout"), - 15: .standard(proto: "use_i2s_as_buzzer"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}enabled\0\u{3}output_ms\0\u{1}output\0\u{1}active\0\u{3}alert_message\0\u{3}alert_bell\0\u{3}use_pwm\0\u{3}output_vibra\0\u{3}output_buzzer\0\u{3}alert_message_vibra\0\u{3}alert_message_buzzer\0\u{3}alert_bell_vibra\0\u{3}alert_bell_buzzer\0\u{3}nag_timeout\0\u{3}use_i2s_as_buzzer\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2347,14 +2110,7 @@ extension ModuleConfig.ExternalNotificationConfig: SwiftProtobuf.Message, SwiftP extension ModuleConfig.StoreForwardConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".StoreForwardConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "enabled"), - 2: .same(proto: "heartbeat"), - 3: .same(proto: "records"), - 4: .standard(proto: "history_return_max"), - 5: .standard(proto: "history_return_window"), - 6: .standard(proto: "is_server"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}enabled\0\u{1}heartbeat\0\u{1}records\0\u{3}history_return_max\0\u{3}history_return_window\0\u{3}is_server\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2409,12 +2165,7 @@ extension ModuleConfig.StoreForwardConfig: SwiftProtobuf.Message, SwiftProtobuf. extension ModuleConfig.RangeTestConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".RangeTestConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "enabled"), - 2: .same(proto: "sender"), - 3: .same(proto: "save"), - 4: .standard(proto: "clear_on_reboot"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}enabled\0\u{1}sender\0\u{1}save\0\u{3}clear_on_reboot\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2459,22 +2210,7 @@ extension ModuleConfig.RangeTestConfig: SwiftProtobuf.Message, SwiftProtobuf._Me extension ModuleConfig.TelemetryConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".TelemetryConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "device_update_interval"), - 2: .standard(proto: "environment_update_interval"), - 3: .standard(proto: "environment_measurement_enabled"), - 4: .standard(proto: "environment_screen_enabled"), - 5: .standard(proto: "environment_display_fahrenheit"), - 6: .standard(proto: "air_quality_enabled"), - 7: .standard(proto: "air_quality_interval"), - 8: .standard(proto: "power_measurement_enabled"), - 9: .standard(proto: "power_update_interval"), - 10: .standard(proto: "power_screen_enabled"), - 11: .standard(proto: "health_measurement_enabled"), - 12: .standard(proto: "health_update_interval"), - 13: .standard(proto: "health_screen_enabled"), - 14: .standard(proto: "device_telemetry_enabled"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}device_update_interval\0\u{3}environment_update_interval\0\u{3}environment_measurement_enabled\0\u{3}environment_screen_enabled\0\u{3}environment_display_fahrenheit\0\u{3}air_quality_enabled\0\u{3}air_quality_interval\0\u{3}power_measurement_enabled\0\u{3}power_update_interval\0\u{3}power_screen_enabled\0\u{3}health_measurement_enabled\0\u{3}health_update_interval\0\u{3}health_screen_enabled\0\u{3}device_telemetry_enabled\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2569,19 +2305,7 @@ extension ModuleConfig.TelemetryConfig: SwiftProtobuf.Message, SwiftProtobuf._Me extension ModuleConfig.CannedMessageConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".CannedMessageConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "rotary1_enabled"), - 2: .standard(proto: "inputbroker_pin_a"), - 3: .standard(proto: "inputbroker_pin_b"), - 4: .standard(proto: "inputbroker_pin_press"), - 5: .standard(proto: "inputbroker_event_cw"), - 6: .standard(proto: "inputbroker_event_ccw"), - 7: .standard(proto: "inputbroker_event_press"), - 8: .standard(proto: "updown1_enabled"), - 9: .same(proto: "enabled"), - 10: .standard(proto: "allow_input_source"), - 11: .standard(proto: "send_bell"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}rotary1_enabled\0\u{3}inputbroker_pin_a\0\u{3}inputbroker_pin_b\0\u{3}inputbroker_pin_press\0\u{3}inputbroker_event_cw\0\u{3}inputbroker_event_ccw\0\u{3}inputbroker_event_press\0\u{3}updown1_enabled\0\u{1}enabled\0\u{3}allow_input_source\0\u{3}send_bell\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2660,27 +2384,12 @@ extension ModuleConfig.CannedMessageConfig: SwiftProtobuf.Message, SwiftProtobuf } extension ModuleConfig.CannedMessageConfig.InputEventChar: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "NONE"), - 10: .same(proto: "SELECT"), - 17: .same(proto: "UP"), - 18: .same(proto: "DOWN"), - 19: .same(proto: "LEFT"), - 20: .same(proto: "RIGHT"), - 24: .same(proto: "CANCEL"), - 27: .same(proto: "BACK"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0NONE\0\u{2}\u{a}SELECT\0\u{2}\u{7}UP\0\u{1}DOWN\0\u{1}LEFT\0\u{1}RIGHT\0\u{2}\u{4}CANCEL\0\u{2}\u{3}BACK\0") } extension ModuleConfig.AmbientLightingConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = ModuleConfig.protoMessageName + ".AmbientLightingConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "led_state"), - 2: .same(proto: "current"), - 3: .same(proto: "red"), - 4: .same(proto: "green"), - 5: .same(proto: "blue"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}led_state\0\u{1}current\0\u{1}red\0\u{1}green\0\u{1}blue\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2730,11 +2439,7 @@ extension ModuleConfig.AmbientLightingConfig: SwiftProtobuf.Message, SwiftProtob extension RemoteHardwarePin: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".RemoteHardwarePin" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "gpio_pin"), - 2: .same(proto: "name"), - 3: .same(proto: "type"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}gpio_pin\0\u{1}name\0\u{1}type\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift index 94ed8cc9..4415e19a 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/mqtt.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// This message wraps a MeshPacket with extra metadata about the sender and how it arrived. -public struct ServiceEnvelope { +public struct ServiceEnvelope: Sendable { // 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. @@ -57,7 +57,7 @@ public struct ServiceEnvelope { /// /// Information about a node intended to be reported unencrypted to a map using MQTT. -public struct MapReport { +public struct MapReport: Sendable { // 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. @@ -126,22 +126,13 @@ public struct MapReport { public init() {} } -#if swift(>=5.5) && canImport(_Concurrency) -extension ServiceEnvelope: @unchecked Sendable {} -extension MapReport: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension ServiceEnvelope: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".ServiceEnvelope" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "packet"), - 2: .standard(proto: "channel_id"), - 3: .standard(proto: "gateway_id"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}packet\0\u{3}channel_id\0\u{3}gateway_id\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -185,22 +176,7 @@ extension ServiceEnvelope: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen extension MapReport: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".MapReport" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "long_name"), - 2: .standard(proto: "short_name"), - 3: .same(proto: "role"), - 4: .standard(proto: "hw_model"), - 5: .standard(proto: "firmware_version"), - 6: .same(proto: "region"), - 7: .standard(proto: "modem_preset"), - 8: .standard(proto: "has_default_channel"), - 9: .standard(proto: "latitude_i"), - 10: .standard(proto: "longitude_i"), - 11: .same(proto: "altitude"), - 12: .standard(proto: "position_precision"), - 13: .standard(proto: "num_online_local_nodes"), - 14: .standard(proto: "has_opted_report_location"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}long_name\0\u{3}short_name\0\u{1}role\0\u{3}hw_model\0\u{3}firmware_version\0\u{1}region\0\u{3}modem_preset\0\u{3}has_default_channel\0\u{3}latitude_i\0\u{3}longitude_i\0\u{1}altitude\0\u{3}position_precision\0\u{3}num_online_local_nodes\0\u{3}has_opted_report_location\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift index cf8aa463..0864d08f 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/paxcount.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// TODO: REPLACE -public struct Paxcount { +public struct Paxcount: Sendable { // 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. @@ -44,21 +44,13 @@ public struct Paxcount { public init() {} } -#if swift(>=5.5) && canImport(_Concurrency) -extension Paxcount: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension Paxcount: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Paxcount" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "wifi"), - 2: .same(proto: "ble"), - 3: .same(proto: "uptime"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}wifi\0\u{1}ble\0\u{1}uptime\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift index f9ff36f6..1d264b5b 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/portnums.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -33,7 +33,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// Note: This was formerly a Type enum named 'typ' with the same id # /// We have change to this 'portnum' based scheme for specifying app handlers for particular payloads. /// This change is backwards compatible by treating the legacy OPAQUE/CLEAR_TEXT values identically. -public enum PortNum: SwiftProtobuf.Enum { +public enum PortNum: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -131,6 +131,13 @@ public enum PortNum: SwiftProtobuf.Enum { /// ENCODING: protobuf case paxcounterApp // = 34 + /// + /// Store and Forward++ module included in the firmware + /// ENCODING: protobuf + /// This module is specifically for Native Linux nodes, and provides a Git-style + /// chain of messages. + case storeForwardPlusplusApp // = 35 + /// /// Provides a hardware serial interface to send and receive from the Meshtastic network. /// Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic @@ -246,6 +253,7 @@ public enum PortNum: SwiftProtobuf.Enum { case 32: self = .replyApp case 33: self = .ipTunnelApp case 34: self = .paxcounterApp + case 35: self = .storeForwardPlusplusApp case 64: self = .serialApp case 65: self = .storeForwardApp case 66: self = .rangeTestApp @@ -284,6 +292,7 @@ public enum PortNum: SwiftProtobuf.Enum { case .replyApp: return 32 case .ipTunnelApp: return 33 case .paxcounterApp: return 34 + case .storeForwardPlusplusApp: return 35 case .serialApp: return 64 case .storeForwardApp: return 65 case .rangeTestApp: return 66 @@ -304,11 +313,6 @@ public enum PortNum: SwiftProtobuf.Enum { } } -} - -#if swift(>=4.2) - -extension PortNum: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [PortNum] = [ .unknownApp, @@ -327,6 +331,7 @@ extension PortNum: CaseIterable { .replyApp, .ipTunnelApp, .paxcounterApp, + .storeForwardPlusplusApp, .serialApp, .storeForwardApp, .rangeTestApp, @@ -344,49 +349,11 @@ extension PortNum: CaseIterable { .atakForwarder, .max, ] + } -#endif // swift(>=4.2) - -#if swift(>=5.5) && canImport(_Concurrency) -extension PortNum: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. extension PortNum: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_APP"), - 1: .same(proto: "TEXT_MESSAGE_APP"), - 2: .same(proto: "REMOTE_HARDWARE_APP"), - 3: .same(proto: "POSITION_APP"), - 4: .same(proto: "NODEINFO_APP"), - 5: .same(proto: "ROUTING_APP"), - 6: .same(proto: "ADMIN_APP"), - 7: .same(proto: "TEXT_MESSAGE_COMPRESSED_APP"), - 8: .same(proto: "WAYPOINT_APP"), - 9: .same(proto: "AUDIO_APP"), - 10: .same(proto: "DETECTION_SENSOR_APP"), - 11: .same(proto: "ALERT_APP"), - 12: .same(proto: "KEY_VERIFICATION_APP"), - 32: .same(proto: "REPLY_APP"), - 33: .same(proto: "IP_TUNNEL_APP"), - 34: .same(proto: "PAXCOUNTER_APP"), - 64: .same(proto: "SERIAL_APP"), - 65: .same(proto: "STORE_FORWARD_APP"), - 66: .same(proto: "RANGE_TEST_APP"), - 67: .same(proto: "TELEMETRY_APP"), - 68: .same(proto: "ZPS_APP"), - 69: .same(proto: "SIMULATOR_APP"), - 70: .same(proto: "TRACEROUTE_APP"), - 71: .same(proto: "NEIGHBORINFO_APP"), - 72: .same(proto: "ATAK_PLUGIN"), - 73: .same(proto: "MAP_REPORT_APP"), - 74: .same(proto: "POWERSTRESS_APP"), - 76: .same(proto: "RETICULUM_TUNNEL_APP"), - 77: .same(proto: "CAYENNE_APP"), - 256: .same(proto: "PRIVATE_APP"), - 257: .same(proto: "ATAK_FORWARDER"), - 511: .same(proto: "MAX"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNKNOWN_APP\0\u{1}TEXT_MESSAGE_APP\0\u{1}REMOTE_HARDWARE_APP\0\u{1}POSITION_APP\0\u{1}NODEINFO_APP\0\u{1}ROUTING_APP\0\u{1}ADMIN_APP\0\u{1}TEXT_MESSAGE_COMPRESSED_APP\0\u{1}WAYPOINT_APP\0\u{1}AUDIO_APP\0\u{1}DETECTION_SENSOR_APP\0\u{1}ALERT_APP\0\u{1}KEY_VERIFICATION_APP\0\u{2}\u{14}REPLY_APP\0\u{1}IP_TUNNEL_APP\0\u{1}PAXCOUNTER_APP\0\u{1}STORE_FORWARD_PLUSPLUS_APP\0\u{2}\u{1d}SERIAL_APP\0\u{1}STORE_FORWARD_APP\0\u{1}RANGE_TEST_APP\0\u{1}TELEMETRY_APP\0\u{1}ZPS_APP\0\u{1}SIMULATOR_APP\0\u{1}TRACEROUTE_APP\0\u{1}NEIGHBORINFO_APP\0\u{1}ATAK_PLUGIN\0\u{1}MAP_REPORT_APP\0\u{1}POWERSTRESS_APP\0\u{2}\u{2}RETICULUM_TUNNEL_APP\0\u{1}CAYENNE_APP\0\u{2}s\u{2}PRIVATE_APP\0\u{1}ATAK_FORWARDER\0\u{2}~\u{3}MAX\0") } diff --git a/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift index 92f3c5ce..7332ba7c 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/powermon.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// Note: There are no 'PowerMon' messages normally in use (PowerMons are sent only as structured logs - slogs). /// But we wrap our State enum in this message to effectively nest a namespace (without our linter yelling at us) -public struct PowerMon { +public struct PowerMon: Sendable { // 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. @@ -31,7 +31,7 @@ public struct PowerMon { /// Any significant power changing event in meshtastic should be tagged with a powermon state transition. /// If you are making new meshtastic features feel free to add new entries at the end of this definition. - public enum State: SwiftProtobuf.Enum { + public enum State: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int case none // = 0 case cpuDeepSleep // = 1 @@ -104,37 +104,31 @@ public struct PowerMon { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [PowerMon.State] = [ + .none, + .cpuDeepSleep, + .cpuLightSleep, + .vext1On, + .loraRxon, + .loraTxon, + .loraRxactive, + .btOn, + .ledOn, + .screenOn, + .screenDrawing, + .wifiOn, + .gpsActive, + ] + } public init() {} } -#if swift(>=4.2) - -extension PowerMon.State: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [PowerMon.State] = [ - .none, - .cpuDeepSleep, - .cpuLightSleep, - .vext1On, - .loraRxon, - .loraTxon, - .loraRxactive, - .btOn, - .ledOn, - .screenOn, - .screenDrawing, - .wifiOn, - .gpsActive, - ] -} - -#endif // swift(>=4.2) - /// /// PowerStress testing support via the C++ PowerStress module -public struct PowerStressMessage { +public struct PowerStressMessage: Sendable { // 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. @@ -151,7 +145,7 @@ public struct PowerStressMessage { /// What operation would we like the UUT to perform. /// note: senders should probably set want_response in their request packets, so that they can know when the state /// machine has started processing their request - public enum Opcode: SwiftProtobuf.Enum { + public enum Opcode: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -272,48 +266,35 @@ public struct PowerStressMessage { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [PowerStressMessage.Opcode] = [ + .unset, + .printInfo, + .forceQuiet, + .endQuiet, + .screenOn, + .screenOff, + .cpuIdle, + .cpuDeepsleep, + .cpuFullon, + .ledOn, + .ledOff, + .loraOff, + .loraTx, + .loraRx, + .btOff, + .btOn, + .wifiOff, + .wifiOn, + .gpsOff, + .gpsOn, + ] + } public init() {} } -#if swift(>=4.2) - -extension PowerStressMessage.Opcode: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [PowerStressMessage.Opcode] = [ - .unset, - .printInfo, - .forceQuiet, - .endQuiet, - .screenOn, - .screenOff, - .cpuIdle, - .cpuDeepsleep, - .cpuFullon, - .ledOn, - .ledOff, - .loraOff, - .loraTx, - .loraRx, - .btOff, - .btOn, - .wifiOff, - .wifiOn, - .gpsOff, - .gpsOn, - ] -} - -#endif // swift(>=4.2) - -#if swift(>=5.5) && canImport(_Concurrency) -extension PowerMon: @unchecked Sendable {} -extension PowerMon.State: @unchecked Sendable {} -extension PowerStressMessage: @unchecked Sendable {} -extension PowerStressMessage.Opcode: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -323,8 +304,8 @@ extension PowerMon: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } + // Load everything into unknown fields + while try decoder.nextFieldNumber() != nil {} } public func traverse(visitor: inout V) throws { @@ -338,29 +319,12 @@ extension PowerMon: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB } extension PowerMon.State: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "None"), - 1: .same(proto: "CPU_DeepSleep"), - 2: .same(proto: "CPU_LightSleep"), - 4: .same(proto: "Vext1_On"), - 8: .same(proto: "Lora_RXOn"), - 16: .same(proto: "Lora_TXOn"), - 32: .same(proto: "Lora_RXActive"), - 64: .same(proto: "BT_On"), - 128: .same(proto: "LED_On"), - 256: .same(proto: "Screen_On"), - 512: .same(proto: "Screen_Drawing"), - 1024: .same(proto: "Wifi_On"), - 2048: .same(proto: "GPS_Active"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0None\0\u{1}CPU_DeepSleep\0\u{1}CPU_LightSleep\0\u{2}\u{2}Vext1_On\0\u{2}\u{4}Lora_RXOn\0\u{2}\u{8}Lora_TXOn\0\u{2}\u{10}Lora_RXActive\0\u{2} BT_On\0\u{2}@\u{1}LED_On\0\u{2}@\u{2}Screen_On\0\u{2}@\u{4}Screen_Drawing\0\u{2}@\u{8}Wifi_On\0\u{2}@\u{10}GPS_Active\0") } extension PowerStressMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".PowerStressMessage" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "cmd"), - 2: .standard(proto: "num_seconds"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}cmd\0\u{3}num_seconds\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -379,7 +343,7 @@ extension PowerStressMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.cmd != .unset { try visitor.visitSingularEnumField(value: self.cmd, fieldNumber: 1) } - if self.numSeconds != 0 { + if self.numSeconds.bitPattern != 0 { try visitor.visitSingularFloatField(value: self.numSeconds, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) @@ -394,26 +358,5 @@ extension PowerStressMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImple } extension PowerStressMessage.Opcode: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNSET"), - 1: .same(proto: "PRINT_INFO"), - 2: .same(proto: "FORCE_QUIET"), - 3: .same(proto: "END_QUIET"), - 16: .same(proto: "SCREEN_ON"), - 17: .same(proto: "SCREEN_OFF"), - 32: .same(proto: "CPU_IDLE"), - 33: .same(proto: "CPU_DEEPSLEEP"), - 34: .same(proto: "CPU_FULLON"), - 48: .same(proto: "LED_ON"), - 49: .same(proto: "LED_OFF"), - 64: .same(proto: "LORA_OFF"), - 65: .same(proto: "LORA_TX"), - 66: .same(proto: "LORA_RX"), - 80: .same(proto: "BT_OFF"), - 81: .same(proto: "BT_ON"), - 96: .same(proto: "WIFI_OFF"), - 97: .same(proto: "WIFI_ON"), - 112: .same(proto: "GPS_OFF"), - 113: .same(proto: "GPS_ON"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNSET\0\u{1}PRINT_INFO\0\u{1}FORCE_QUIET\0\u{1}END_QUIET\0\u{2}\u{d}SCREEN_ON\0\u{1}SCREEN_OFF\0\u{2}\u{f}CPU_IDLE\0\u{1}CPU_DEEPSLEEP\0\u{1}CPU_FULLON\0\u{2}\u{e}LED_ON\0\u{1}LED_OFF\0\u{2}\u{f}LORA_OFF\0\u{1}LORA_TX\0\u{1}LORA_RX\0\u{2}\u{e}BT_OFF\0\u{1}BT_ON\0\u{2}\u{f}WIFI_OFF\0\u{1}WIFI_ON\0\u{2}\u{f}GPS_OFF\0\u{1}GPS_ON\0") } diff --git a/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift index ac6eeb26..001db067 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/remote_hardware.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -30,7 +30,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// because no security yet (beyond the channel mechanism). /// It should be off by default and then protected based on some TBD mechanism /// (a special channel once multichannel support is included?) -public struct HardwareMessage { +public struct HardwareMessage: Sendable { // 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. @@ -52,7 +52,7 @@ public struct HardwareMessage { /// /// TODO: REPLACE - public enum TypeEnum: SwiftProtobuf.Enum { + public enum TypeEnum: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -110,43 +110,28 @@ public struct HardwareMessage { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [HardwareMessage.TypeEnum] = [ + .unset, + .writeGpios, + .watchGpios, + .gpiosChanged, + .readGpios, + .readGpiosReply, + ] + } public init() {} } -#if swift(>=4.2) - -extension HardwareMessage.TypeEnum: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [HardwareMessage.TypeEnum] = [ - .unset, - .writeGpios, - .watchGpios, - .gpiosChanged, - .readGpios, - .readGpiosReply, - ] -} - -#endif // swift(>=4.2) - -#if swift(>=5.5) && canImport(_Concurrency) -extension HardwareMessage: @unchecked Sendable {} -extension HardwareMessage.TypeEnum: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension HardwareMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".HardwareMessage" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "type"), - 2: .standard(proto: "gpio_mask"), - 3: .standard(proto: "gpio_value"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}type\0\u{3}gpio_mask\0\u{3}gpio_value\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -185,12 +170,5 @@ extension HardwareMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen } extension HardwareMessage.TypeEnum: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNSET"), - 1: .same(proto: "WRITE_GPIOS"), - 2: .same(proto: "WATCH_GPIOS"), - 3: .same(proto: "GPIOS_CHANGED"), - 4: .same(proto: "READ_GPIOS"), - 5: .same(proto: "READ_GPIOS_REPLY"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNSET\0\u{1}WRITE_GPIOS\0\u{1}WATCH_GPIOS\0\u{1}GPIOS_CHANGED\0\u{1}READ_GPIOS\0\u{1}READ_GPIOS_REPLY\0") } diff --git a/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift index 6fdf3208..0c114acb 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/rtttl.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Canned message module configuration. -public struct RTTTLConfig { +public struct RTTTLConfig: Sendable { // 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. @@ -36,19 +36,13 @@ public struct RTTTLConfig { public init() {} } -#if swift(>=5.5) && canImport(_Concurrency) -extension RTTTLConfig: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension RTTTLConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".RTTTLConfig" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "ringtone"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}ringtone\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift index 54efa77b..a0534387 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/storeforward.proto @@ -22,7 +23,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// TODO: REPLACE -public struct StoreAndForward { +public struct StoreAndForward: Sendable { // 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. @@ -79,7 +80,7 @@ public struct StoreAndForward { /// /// TODO: REPLACE - public enum OneOf_Variant: Equatable { + public enum OneOf_Variant: Equatable, Sendable { /// /// TODO: REPLACE case stats(StoreAndForward.Statistics) @@ -93,38 +94,12 @@ public struct StoreAndForward { /// Text from history message. case text(Data) - #if !swift(>=4.1) - public static func ==(lhs: StoreAndForward.OneOf_Variant, rhs: StoreAndForward.OneOf_Variant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.stats, .stats): return { - guard case .stats(let l) = lhs, case .stats(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.history, .history): return { - guard case .history(let l) = lhs, case .history(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.heartbeat, .heartbeat): return { - guard case .heartbeat(let l) = lhs, case .heartbeat(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.text, .text): return { - guard case .text(let l) = lhs, case .text(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } /// /// 001 - 063 = From Router /// 064 - 127 = From Client - public enum RequestResponse: SwiftProtobuf.Enum { + public enum RequestResponse: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -242,11 +217,31 @@ public struct StoreAndForward { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [StoreAndForward.RequestResponse] = [ + .unset, + .routerError, + .routerHeartbeat, + .routerPing, + .routerPong, + .routerBusy, + .routerHistory, + .routerStats, + .routerTextDirect, + .routerTextBroadcast, + .clientError, + .clientHistory, + .clientStats, + .clientPing, + .clientPong, + .clientAbort, + ] + } /// /// TODO: REPLACE - public struct Statistics { + public struct Statistics: Sendable { // 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. @@ -294,7 +289,7 @@ public struct StoreAndForward { /// /// TODO: REPLACE - public struct History { + public struct History: Sendable { // 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. @@ -319,7 +314,7 @@ public struct StoreAndForward { /// /// TODO: REPLACE - public struct Heartbeat { + public struct Heartbeat: Sendable { // 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. @@ -340,54 +335,13 @@ public struct StoreAndForward { public init() {} } -#if swift(>=4.2) - -extension StoreAndForward.RequestResponse: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [StoreAndForward.RequestResponse] = [ - .unset, - .routerError, - .routerHeartbeat, - .routerPing, - .routerPong, - .routerBusy, - .routerHistory, - .routerStats, - .routerTextDirect, - .routerTextBroadcast, - .clientError, - .clientHistory, - .clientStats, - .clientPing, - .clientPong, - .clientAbort, - ] -} - -#endif // swift(>=4.2) - -#if swift(>=5.5) && canImport(_Concurrency) -extension StoreAndForward: @unchecked Sendable {} -extension StoreAndForward.OneOf_Variant: @unchecked Sendable {} -extension StoreAndForward.RequestResponse: @unchecked Sendable {} -extension StoreAndForward.Statistics: @unchecked Sendable {} -extension StoreAndForward.History: @unchecked Sendable {} -extension StoreAndForward.Heartbeat: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension StoreAndForward: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".StoreAndForward" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "rr"), - 2: .same(proto: "stats"), - 3: .same(proto: "history"), - 4: .same(proto: "heartbeat"), - 5: .same(proto: "text"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}rr\0\u{1}stats\0\u{1}history\0\u{1}heartbeat\0\u{1}text\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -487,39 +441,12 @@ extension StoreAndForward: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen } extension StoreAndForward.RequestResponse: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNSET"), - 1: .same(proto: "ROUTER_ERROR"), - 2: .same(proto: "ROUTER_HEARTBEAT"), - 3: .same(proto: "ROUTER_PING"), - 4: .same(proto: "ROUTER_PONG"), - 5: .same(proto: "ROUTER_BUSY"), - 6: .same(proto: "ROUTER_HISTORY"), - 7: .same(proto: "ROUTER_STATS"), - 8: .same(proto: "ROUTER_TEXT_DIRECT"), - 9: .same(proto: "ROUTER_TEXT_BROADCAST"), - 64: .same(proto: "CLIENT_ERROR"), - 65: .same(proto: "CLIENT_HISTORY"), - 66: .same(proto: "CLIENT_STATS"), - 67: .same(proto: "CLIENT_PING"), - 68: .same(proto: "CLIENT_PONG"), - 106: .same(proto: "CLIENT_ABORT"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNSET\0\u{1}ROUTER_ERROR\0\u{1}ROUTER_HEARTBEAT\0\u{1}ROUTER_PING\0\u{1}ROUTER_PONG\0\u{1}ROUTER_BUSY\0\u{1}ROUTER_HISTORY\0\u{1}ROUTER_STATS\0\u{1}ROUTER_TEXT_DIRECT\0\u{1}ROUTER_TEXT_BROADCAST\0\u{2}7CLIENT_ERROR\0\u{1}CLIENT_HISTORY\0\u{1}CLIENT_STATS\0\u{1}CLIENT_PING\0\u{1}CLIENT_PONG\0\u{2}&CLIENT_ABORT\0") } extension StoreAndForward.Statistics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = StoreAndForward.protoMessageName + ".Statistics" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "messages_total"), - 2: .standard(proto: "messages_saved"), - 3: .standard(proto: "messages_max"), - 4: .standard(proto: "up_time"), - 5: .same(proto: "requests"), - 6: .standard(proto: "requests_history"), - 7: .same(proto: "heartbeat"), - 8: .standard(proto: "return_max"), - 9: .standard(proto: "return_window"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}messages_total\0\u{3}messages_saved\0\u{3}messages_max\0\u{3}up_time\0\u{1}requests\0\u{3}requests_history\0\u{1}heartbeat\0\u{3}return_max\0\u{3}return_window\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -589,11 +516,7 @@ extension StoreAndForward.Statistics: SwiftProtobuf.Message, SwiftProtobuf._Mess extension StoreAndForward.History: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = StoreAndForward.protoMessageName + ".History" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "history_messages"), - 2: .same(proto: "window"), - 3: .standard(proto: "last_request"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}history_messages\0\u{1}window\0\u{3}last_request\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -633,10 +556,7 @@ extension StoreAndForward.History: SwiftProtobuf.Message, SwiftProtobuf._Message extension StoreAndForward.Heartbeat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = StoreAndForward.protoMessageName + ".Heartbeat" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "period"), - 2: .same(proto: "secondary"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}period\0\u{1}secondary\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift index 1173189c..5ad5fad3 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/telemetry.proto @@ -7,7 +8,6 @@ // For information on using the generated types, please see the documentation: // https://github.com/apple/swift-protobuf/ -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Supported I2C Sensors for telemetry in Meshtastic -public enum TelemetrySensorType: SwiftProtobuf.Enum { +public enum TelemetrySensorType: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int /// @@ -204,6 +204,10 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum { /// /// TSL2561 light sensor case tsl2561 // = 44 + + /// + /// BH1750 light sensor + case bh1750 // = 45 case UNRECOGNIZED(Int) public init() { @@ -257,6 +261,7 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum { case 42: self = .sfa30 case 43: self = .sen5X case 44: self = .tsl2561 + case 45: self = .bh1750 default: self = .UNRECOGNIZED(rawValue) } } @@ -308,15 +313,11 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum { case .sfa30: return 42 case .sen5X: return 43 case .tsl2561: return 44 + case .bh1750: return 45 case .UNRECOGNIZED(let i): return i } } -} - -#if swift(>=4.2) - -extension TelemetrySensorType: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [TelemetrySensorType] = [ .sensorUnset, @@ -364,14 +365,14 @@ extension TelemetrySensorType: CaseIterable { .sfa30, .sen5X, .tsl2561, + .bh1750, ] -} -#endif // swift(>=4.2) +} /// /// Key native device metrics such as battery level -public struct DeviceMetrics { +public struct DeviceMetrics: Sendable { // 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. @@ -444,7 +445,7 @@ public struct DeviceMetrics { /// /// Weather station or other environmental metrics -public struct EnvironmentMetrics { +public struct EnvironmentMetrics: @unchecked Sendable { // 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. @@ -702,7 +703,7 @@ public struct EnvironmentMetrics { /// /// Power Metrics (voltage / current / etc) -public struct PowerMetrics { +public struct PowerMetrics: Sendable { // 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. @@ -907,7 +908,7 @@ public struct PowerMetrics { /// /// Air quality metrics -public struct AirQualityMetrics { +public struct AirQualityMetrics: @unchecked Sendable { // 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. @@ -1196,7 +1197,7 @@ public struct AirQualityMetrics { /// /// Local device mesh statistics -public struct LocalStats { +public struct LocalStats: Sendable { // 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. @@ -1255,6 +1256,10 @@ public struct LocalStats { /// Number of bytes free in the heap public var heapFreeBytes: UInt32 = 0 + /// + /// Number of packets that were dropped because the transmit queue was full. + public var numTxDropped: UInt32 = 0 + public var unknownFields = SwiftProtobuf.UnknownStorage() public init() {} @@ -1262,7 +1267,7 @@ public struct LocalStats { /// /// Health telemetry metrics -public struct HealthMetrics { +public struct HealthMetrics: Sendable { // 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. @@ -1311,7 +1316,7 @@ public struct HealthMetrics { /// /// Linux host metrics -public struct HostMetrics { +public struct HostMetrics: Sendable { // 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. @@ -1385,7 +1390,7 @@ public struct HostMetrics { /// /// Types of Measurements the telemetry module is equipped to handle -public struct Telemetry { +public struct Telemetry: @unchecked Sendable { // 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. @@ -1474,7 +1479,7 @@ public struct Telemetry { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_Variant: Equatable { + public enum OneOf_Variant: Equatable, Sendable { /// /// Key native device metrics such as battery level case deviceMetrics(DeviceMetrics) @@ -1497,44 +1502,6 @@ public struct Telemetry { /// Linux host metrics case hostMetrics(HostMetrics) - #if !swift(>=4.1) - public static func ==(lhs: Telemetry.OneOf_Variant, rhs: Telemetry.OneOf_Variant) -> Bool { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch (lhs, rhs) { - case (.deviceMetrics, .deviceMetrics): return { - guard case .deviceMetrics(let l) = lhs, case .deviceMetrics(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.environmentMetrics, .environmentMetrics): return { - guard case .environmentMetrics(let l) = lhs, case .environmentMetrics(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.airQualityMetrics, .airQualityMetrics): return { - guard case .airQualityMetrics(let l) = lhs, case .airQualityMetrics(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.powerMetrics, .powerMetrics): return { - guard case .powerMetrics(let l) = lhs, case .powerMetrics(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.localStats, .localStats): return { - guard case .localStats(let l) = lhs, case .localStats(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.healthMetrics, .healthMetrics): return { - guard case .healthMetrics(let l) = lhs, case .healthMetrics(let r) = rhs else { preconditionFailure() } - return l == r - }() - case (.hostMetrics, .hostMetrics): return { - guard case .hostMetrics(let l) = lhs, case .hostMetrics(let r) = rhs else { preconditionFailure() } - return l == r - }() - default: return false - } - } - #endif } public init() {} @@ -1544,7 +1511,7 @@ public struct Telemetry { /// /// NAU7802 Telemetry configuration, for saving to flash -public struct Nau7802Config { +public struct Nau7802Config: Sendable { // 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. @@ -1562,83 +1529,17 @@ public struct Nau7802Config { public init() {} } -#if swift(>=5.5) && canImport(_Concurrency) -extension TelemetrySensorType: @unchecked Sendable {} -extension DeviceMetrics: @unchecked Sendable {} -extension EnvironmentMetrics: @unchecked Sendable {} -extension PowerMetrics: @unchecked Sendable {} -extension AirQualityMetrics: @unchecked Sendable {} -extension LocalStats: @unchecked Sendable {} -extension HealthMetrics: @unchecked Sendable {} -extension HostMetrics: @unchecked Sendable {} -extension Telemetry: @unchecked Sendable {} -extension Telemetry.OneOf_Variant: @unchecked Sendable {} -extension Nau7802Config: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension TelemetrySensorType: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "SENSOR_UNSET"), - 1: .same(proto: "BME280"), - 2: .same(proto: "BME680"), - 3: .same(proto: "MCP9808"), - 4: .same(proto: "INA260"), - 5: .same(proto: "INA219"), - 6: .same(proto: "BMP280"), - 7: .same(proto: "SHTC3"), - 8: .same(proto: "LPS22"), - 9: .same(proto: "QMC6310"), - 10: .same(proto: "QMI8658"), - 11: .same(proto: "QMC5883L"), - 12: .same(proto: "SHT31"), - 13: .same(proto: "PMSA003I"), - 14: .same(proto: "INA3221"), - 15: .same(proto: "BMP085"), - 16: .same(proto: "RCWL9620"), - 17: .same(proto: "SHT4X"), - 18: .same(proto: "VEML7700"), - 19: .same(proto: "MLX90632"), - 20: .same(proto: "OPT3001"), - 21: .same(proto: "LTR390UV"), - 22: .same(proto: "TSL25911FN"), - 23: .same(proto: "AHT10"), - 24: .same(proto: "DFROBOT_LARK"), - 25: .same(proto: "NAU7802"), - 26: .same(proto: "BMP3XX"), - 27: .same(proto: "ICM20948"), - 28: .same(proto: "MAX17048"), - 29: .same(proto: "CUSTOM_SENSOR"), - 30: .same(proto: "MAX30102"), - 31: .same(proto: "MLX90614"), - 32: .same(proto: "SCD4X"), - 33: .same(proto: "RADSENS"), - 34: .same(proto: "INA226"), - 35: .same(proto: "DFROBOT_RAIN"), - 36: .same(proto: "DPS310"), - 37: .same(proto: "RAK12035"), - 38: .same(proto: "MAX17261"), - 39: .same(proto: "PCT2075"), - 40: .same(proto: "ADS1X15"), - 41: .same(proto: "ADS1X15_ALT"), - 42: .same(proto: "SFA30"), - 43: .same(proto: "SEN5X"), - 44: .same(proto: "TSL2561"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0SENSOR_UNSET\0\u{1}BME280\0\u{1}BME680\0\u{1}MCP9808\0\u{1}INA260\0\u{1}INA219\0\u{1}BMP280\0\u{1}SHTC3\0\u{1}LPS22\0\u{1}QMC6310\0\u{1}QMI8658\0\u{1}QMC5883L\0\u{1}SHT31\0\u{1}PMSA003I\0\u{1}INA3221\0\u{1}BMP085\0\u{1}RCWL9620\0\u{1}SHT4X\0\u{1}VEML7700\0\u{1}MLX90632\0\u{1}OPT3001\0\u{1}LTR390UV\0\u{1}TSL25911FN\0\u{1}AHT10\0\u{1}DFROBOT_LARK\0\u{1}NAU7802\0\u{1}BMP3XX\0\u{1}ICM20948\0\u{1}MAX17048\0\u{1}CUSTOM_SENSOR\0\u{1}MAX30102\0\u{1}MLX90614\0\u{1}SCD4X\0\u{1}RADSENS\0\u{1}INA226\0\u{1}DFROBOT_RAIN\0\u{1}DPS310\0\u{1}RAK12035\0\u{1}MAX17261\0\u{1}PCT2075\0\u{1}ADS1X15\0\u{1}ADS1X15_ALT\0\u{1}SFA30\0\u{1}SEN5X\0\u{1}TSL2561\0\u{1}BH1750\0") } extension DeviceMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".DeviceMetrics" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "battery_level"), - 2: .same(proto: "voltage"), - 3: .standard(proto: "channel_utilization"), - 4: .standard(proto: "air_util_tx"), - 5: .standard(proto: "uptime_seconds"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}battery_level\0\u{1}voltage\0\u{3}channel_utilization\0\u{3}air_util_tx\0\u{3}uptime_seconds\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -1692,30 +1593,7 @@ extension DeviceMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".EnvironmentMetrics" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "temperature"), - 2: .standard(proto: "relative_humidity"), - 3: .standard(proto: "barometric_pressure"), - 4: .standard(proto: "gas_resistance"), - 5: .same(proto: "voltage"), - 6: .same(proto: "current"), - 7: .same(proto: "iaq"), - 8: .same(proto: "distance"), - 9: .same(proto: "lux"), - 10: .standard(proto: "white_lux"), - 11: .standard(proto: "ir_lux"), - 12: .standard(proto: "uv_lux"), - 13: .standard(proto: "wind_direction"), - 14: .standard(proto: "wind_speed"), - 15: .same(proto: "weight"), - 16: .standard(proto: "wind_gust"), - 17: .standard(proto: "wind_lull"), - 18: .same(proto: "radiation"), - 19: .standard(proto: "rainfall_1h"), - 20: .standard(proto: "rainfall_24h"), - 21: .standard(proto: "soil_moisture"), - 22: .standard(proto: "soil_temperature"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}temperature\0\u{3}relative_humidity\0\u{3}barometric_pressure\0\u{3}gas_resistance\0\u{1}voltage\0\u{1}current\0\u{1}iaq\0\u{1}distance\0\u{1}lux\0\u{3}white_lux\0\u{3}ir_lux\0\u{3}uv_lux\0\u{3}wind_direction\0\u{3}wind_speed\0\u{1}weight\0\u{3}wind_gust\0\u{3}wind_lull\0\u{1}radiation\0\u{3}rainfall_1h\0\u{3}rainfall_24h\0\u{3}soil_moisture\0\u{3}soil_temperature\0") fileprivate class _StorageClass { var _temperature: Float? = nil @@ -1741,15 +1619,11 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple var _soilMoisture: UInt32? = nil var _soilTemperature: Float? = nil - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} @@ -1936,24 +1810,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple extension PowerMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".PowerMetrics" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "ch1_voltage"), - 2: .standard(proto: "ch1_current"), - 3: .standard(proto: "ch2_voltage"), - 4: .standard(proto: "ch2_current"), - 5: .standard(proto: "ch3_voltage"), - 6: .standard(proto: "ch3_current"), - 7: .standard(proto: "ch4_voltage"), - 8: .standard(proto: "ch4_current"), - 9: .standard(proto: "ch5_voltage"), - 10: .standard(proto: "ch5_current"), - 11: .standard(proto: "ch6_voltage"), - 12: .standard(proto: "ch6_current"), - 13: .standard(proto: "ch7_voltage"), - 14: .standard(proto: "ch7_current"), - 15: .standard(proto: "ch8_voltage"), - 16: .standard(proto: "ch8_current"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}ch1_voltage\0\u{3}ch1_current\0\u{3}ch2_voltage\0\u{3}ch2_current\0\u{3}ch3_voltage\0\u{3}ch3_current\0\u{3}ch4_voltage\0\u{3}ch4_current\0\u{3}ch5_voltage\0\u{3}ch5_current\0\u{3}ch6_voltage\0\u{3}ch6_current\0\u{3}ch7_voltage\0\u{3}ch7_current\0\u{3}ch8_voltage\0\u{3}ch8_current\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2062,33 +1919,7 @@ extension PowerMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat extension AirQualityMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".AirQualityMetrics" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "pm10_standard"), - 2: .standard(proto: "pm25_standard"), - 3: .standard(proto: "pm100_standard"), - 4: .standard(proto: "pm10_environmental"), - 5: .standard(proto: "pm25_environmental"), - 6: .standard(proto: "pm100_environmental"), - 7: .standard(proto: "particles_03um"), - 8: .standard(proto: "particles_05um"), - 9: .standard(proto: "particles_10um"), - 10: .standard(proto: "particles_25um"), - 11: .standard(proto: "particles_50um"), - 12: .standard(proto: "particles_100um"), - 13: .same(proto: "co2"), - 14: .standard(proto: "co2_temperature"), - 15: .standard(proto: "co2_humidity"), - 16: .standard(proto: "form_formaldehyde"), - 17: .standard(proto: "form_humidity"), - 18: .standard(proto: "form_temperature"), - 19: .standard(proto: "pm40_standard"), - 20: .standard(proto: "particles_40um"), - 21: .standard(proto: "pm_temperature"), - 22: .standard(proto: "pm_humidity"), - 23: .standard(proto: "pm_voc_idx"), - 24: .standard(proto: "pm_nox_idx"), - 25: .standard(proto: "particles_tps"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}pm10_standard\0\u{3}pm25_standard\0\u{3}pm100_standard\0\u{3}pm10_environmental\0\u{3}pm25_environmental\0\u{3}pm100_environmental\0\u{3}particles_03um\0\u{3}particles_05um\0\u{3}particles_10um\0\u{3}particles_25um\0\u{3}particles_50um\0\u{3}particles_100um\0\u{1}co2\0\u{3}co2_temperature\0\u{3}co2_humidity\0\u{3}form_formaldehyde\0\u{3}form_humidity\0\u{3}form_temperature\0\u{3}pm40_standard\0\u{3}particles_40um\0\u{3}pm_temperature\0\u{3}pm_humidity\0\u{3}pm_voc_idx\0\u{3}pm_nox_idx\0\u{3}particles_tps\0") fileprivate class _StorageClass { var _pm10Standard: UInt32? = nil @@ -2117,15 +1948,11 @@ extension AirQualityMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem var _pmNoxIdx: Float? = nil var _particlesTps: Float? = nil - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} @@ -2330,21 +2157,7 @@ extension AirQualityMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem extension LocalStats: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".LocalStats" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "uptime_seconds"), - 2: .standard(proto: "channel_utilization"), - 3: .standard(proto: "air_util_tx"), - 4: .standard(proto: "num_packets_tx"), - 5: .standard(proto: "num_packets_rx"), - 6: .standard(proto: "num_packets_rx_bad"), - 7: .standard(proto: "num_online_nodes"), - 8: .standard(proto: "num_total_nodes"), - 9: .standard(proto: "num_rx_dupe"), - 10: .standard(proto: "num_tx_relay"), - 11: .standard(proto: "num_tx_relay_canceled"), - 12: .standard(proto: "heap_total_bytes"), - 13: .standard(proto: "heap_free_bytes"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}uptime_seconds\0\u{3}channel_utilization\0\u{3}air_util_tx\0\u{3}num_packets_tx\0\u{3}num_packets_rx\0\u{3}num_packets_rx_bad\0\u{3}num_online_nodes\0\u{3}num_total_nodes\0\u{3}num_rx_dupe\0\u{3}num_tx_relay\0\u{3}num_tx_relay_canceled\0\u{3}heap_total_bytes\0\u{3}heap_free_bytes\0\u{3}num_tx_dropped\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2365,6 +2178,7 @@ extension LocalStats: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio case 11: try { try decoder.decodeSingularUInt32Field(value: &self.numTxRelayCanceled) }() case 12: try { try decoder.decodeSingularUInt32Field(value: &self.heapTotalBytes) }() case 13: try { try decoder.decodeSingularUInt32Field(value: &self.heapFreeBytes) }() + case 14: try { try decoder.decodeSingularUInt32Field(value: &self.numTxDropped) }() default: break } } @@ -2374,10 +2188,10 @@ extension LocalStats: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if self.uptimeSeconds != 0 { try visitor.visitSingularUInt32Field(value: self.uptimeSeconds, fieldNumber: 1) } - if self.channelUtilization != 0 { + if self.channelUtilization.bitPattern != 0 { try visitor.visitSingularFloatField(value: self.channelUtilization, fieldNumber: 2) } - if self.airUtilTx != 0 { + if self.airUtilTx.bitPattern != 0 { try visitor.visitSingularFloatField(value: self.airUtilTx, fieldNumber: 3) } if self.numPacketsTx != 0 { @@ -2410,6 +2224,9 @@ extension LocalStats: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if self.heapFreeBytes != 0 { try visitor.visitSingularUInt32Field(value: self.heapFreeBytes, fieldNumber: 13) } + if self.numTxDropped != 0 { + try visitor.visitSingularUInt32Field(value: self.numTxDropped, fieldNumber: 14) + } try unknownFields.traverse(visitor: &visitor) } @@ -2427,6 +2244,7 @@ extension LocalStats: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if lhs.numTxRelayCanceled != rhs.numTxRelayCanceled {return false} if lhs.heapTotalBytes != rhs.heapTotalBytes {return false} if lhs.heapFreeBytes != rhs.heapFreeBytes {return false} + if lhs.numTxDropped != rhs.numTxDropped {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -2434,11 +2252,7 @@ extension LocalStats: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio extension HealthMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".HealthMetrics" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "heart_bpm"), - 2: .same(proto: "spO2"), - 3: .same(proto: "temperature"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}heart_bpm\0\u{1}spO2\0\u{1}temperature\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2482,17 +2296,7 @@ extension HealthMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa extension HostMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".HostMetrics" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "uptime_seconds"), - 2: .standard(proto: "freemem_bytes"), - 3: .standard(proto: "diskfree1_bytes"), - 4: .standard(proto: "diskfree2_bytes"), - 5: .standard(proto: "diskfree3_bytes"), - 6: .same(proto: "load1"), - 7: .same(proto: "load5"), - 8: .same(proto: "load15"), - 9: .standard(proto: "user_string"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}uptime_seconds\0\u{3}freemem_bytes\0\u{3}diskfree1_bytes\0\u{3}diskfree2_bytes\0\u{3}diskfree3_bytes\0\u{1}load1\0\u{1}load5\0\u{1}load15\0\u{3}user_string\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2566,30 +2370,17 @@ extension HostMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati extension Telemetry: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Telemetry" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "time"), - 2: .standard(proto: "device_metrics"), - 3: .standard(proto: "environment_metrics"), - 4: .standard(proto: "air_quality_metrics"), - 5: .standard(proto: "power_metrics"), - 6: .standard(proto: "local_stats"), - 7: .standard(proto: "health_metrics"), - 8: .standard(proto: "host_metrics"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}time\0\u{3}device_metrics\0\u{3}environment_metrics\0\u{3}air_quality_metrics\0\u{3}power_metrics\0\u{3}local_stats\0\u{3}health_metrics\0\u{3}host_metrics\0") fileprivate class _StorageClass { var _time: UInt32 = 0 var _variant: Telemetry.OneOf_Variant? - #if swift(>=5.10) // This property is used as the initial default value for new instances of the type. // The type itself is protecting the reference to its storage via CoW semantics. // This will force a copy to be made of this reference when the first mutation occurs; // hence, it is safe to mark this as `nonisolated(unsafe)`. static nonisolated(unsafe) let defaultInstance = _StorageClass() - #else - static let defaultInstance = _StorageClass() - #endif private init() {} @@ -2774,10 +2565,7 @@ extension Telemetry: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation extension Nau7802Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".Nau7802Config" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "zeroOffset"), - 2: .same(proto: "calibrationFactor"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}zeroOffset\0\u{1}calibrationFactor\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2796,7 +2584,7 @@ extension Nau7802Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa if self.zeroOffset != 0 { try visitor.visitSingularInt32Field(value: self.zeroOffset, fieldNumber: 1) } - if self.calibrationFactor != 0 { + if self.calibrationFactor.bitPattern != 0 { try visitor.visitSingularFloatField(value: self.calibrationFactor, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) diff --git a/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift index 1f41fe0b..010c6eed 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/xmodem.proto @@ -20,7 +21,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct XModem { +public struct XModem: Sendable { // 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. @@ -35,7 +36,7 @@ public struct XModem { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum Control: SwiftProtobuf.Enum { + public enum Control: SwiftProtobuf.Enum, Swift.CaseIterable { public typealias RawValue = Int case nul // = 0 case soh // = 1 @@ -79,46 +80,30 @@ public struct XModem { } } + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [XModem.Control] = [ + .nul, + .soh, + .stx, + .eot, + .ack, + .nak, + .can, + .ctrlz, + ] + } public init() {} } -#if swift(>=4.2) - -extension XModem.Control: CaseIterable { - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [XModem.Control] = [ - .nul, - .soh, - .stx, - .eot, - .ack, - .nak, - .can, - .ctrlz, - ] -} - -#endif // swift(>=4.2) - -#if swift(>=5.5) && canImport(_Concurrency) -extension XModem: @unchecked Sendable {} -extension XModem.Control: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" extension XModem: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { public static let protoMessageName: String = _protobuf_package + ".XModem" - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "control"), - 2: .same(proto: "seq"), - 3: .same(proto: "crc16"), - 4: .same(proto: "buffer"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}control\0\u{1}seq\0\u{1}crc16\0\u{1}buffer\0") public mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -162,14 +147,5 @@ extension XModem: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas } extension XModem.Control: SwiftProtobuf._ProtoNameProviding { - public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "NUL"), - 1: .same(proto: "SOH"), - 2: .same(proto: "STX"), - 4: .same(proto: "EOT"), - 6: .same(proto: "ACK"), - 21: .same(proto: "NAK"), - 24: .same(proto: "CAN"), - 26: .same(proto: "CTRLZ"), - ] + public static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0NUL\0\u{1}SOH\0\u{1}STX\0\u{2}\u{2}EOT\0\u{2}\u{2}ACK\0\u{2}\u{f}NAK\0\u{2}\u{3}CAN\0\u{2}\u{2}CTRLZ\0") } diff --git a/protobufs b/protobufs index c1e31a96..62ef17b3 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit c1e31a9655e9920a8b5b8eccdf7c69ef1ae42a49 +Subproject commit 62ef17b3d1625fc6d78ed661f614d0baad4be9ef