mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
2.7.6 Working Changes (#1479)
* Bump version * Message list performance fixes into 2.7.6 (#1475) * Remove extra want config call when adding a contact * App badge and unnecessary notification fixes (#1455) * - Fix for app badge not going to zero if a message arrives while you have that chat open - Fix for push notifications popping up when a message is received while that chat is open * Fix for cancelling notifications, works now. And scroll to bottom of conversation upon new message * Fix: Channels help grammer fix (#1452) * remove outdated TCP not available on Apple devices (#1450) * Update initial onboarding view * remove toggle gating for mac * Update crash reporting opt out in real time * Update onboarding text * Use mDNS text records for node name * TCP IP and port on the connection screen * Hide app icon chooser on mac * Infinite loop hang bugfixes and performance improvements for both `UserMessageList` and `ChannelMessageList` (#1465) * 2.7.5 Working Changes (#1460) * Remove extra want config call when adding a contact * App badge and unnecessary notification fixes (#1455) * - Fix for app badge not going to zero if a message arrives while you have that chat open - Fix for push notifications popping up when a message is received while that chat is open * Fix for cancelling notifications, works now. And scroll to bottom of conversation upon new message * Fix: Channels help grammer fix (#1452) * remove outdated TCP not available on Apple devices (#1450) * Update initial onboarding view * remove toggle gating for mac * Update crash reporting opt out in real time * Update onboarding text --------- Co-authored-by: Gnome Adrift <646322+gnomeadrift@users.noreply.github.com> Co-authored-by: Zain Kergaye <62440012+ZainKergaye@users.noreply.github.com> Co-authored-by: NillRudd <102033730+NillRudd@users.noreply.github.com> * UserEntity: add mostRecentMessage and unreadMessages with early exit when lastMessage is nil, and fetch 1 row (not N) otherwise * UserList: replace 5 slow calls to user.messageList with new fast calls * NodeList: always put the connected node at the top of list (if it matches the node filters) * ChannelEntity: add faster mostRecentPrivateMessage and unreadMessages which fetch 1 row (not N) * ChannelList: replace 5 calls to channel.allPrivateMessage with new fast calls * Fix incorrect appState.unreadDirectMessages calculations * MyInfoEntity: also fix unreadMessages count here to be fast, and use it for appState.unreadChannelMessages * UserMessageList: use @FetchRequest to prevent the N^2 behavior that was happening in calls to allPrivateMessages * Refactor ChannelEntityExtension and MyInfoEntityExtension to be more similar to UserEntityExtension * Remove SwiftUI-infinite-loop-causing `.id(redrawTapbacksTrigger)` in ChannelMessageList and UserMessageList (duplicate row ids) * MyInfoEntityExtension: exclude emoji tapbacks (which never get marked as read anyway) from unread message count * Add SaveChannelLinkData so MessageText and MeshtasticApp can use .sheet(item: ...) and avoid infinite loop hang due to Binding rebuild * ChannelMessageList and UserMessageList: switch to stable messageId for ForEach SwiftUI row identity * ChannelMessageList and UserMessageList: debouncedScrollToBottom; keyboardWillShowNotification/keyboardDidShowNotification * ChannelMessageList and UserMessageList: scroll to bottom onFirstAppear * ChannelMessageList and UserMessageList: block spurious markMessagesAsRead when this View is not active --------- Co-authored-by: Garth Vander Houwen <garth@meshtastic.com> Co-authored-by: Gnome Adrift <646322+gnomeadrift@users.noreply.github.com> Co-authored-by: Zain Kergaye <62440012+ZainKergaye@users.noreply.github.com> Co-authored-by: NillRudd <102033730+NillRudd@users.noreply.github.com> * message-list-performance: revert scrolling changes (#1472) * Reverte0f0b4a0f7(ChannelMessageList and UserMessageList: scroll to bottom onFirstAppear) * Revert "ChannelMessageList and UserMessageList: debouncedScrollToBottom; keyboardWillShowNotification/keyboardDidShowNotification" This reverts commitee1a7c4415. --------- Co-authored-by: Gnome Adrift <646322+gnomeadrift@users.noreply.github.com> Co-authored-by: Zain Kergaye <62440012+ZainKergaye@users.noreply.github.com> Co-authored-by: NillRudd <102033730+NillRudd@users.noreply.github.com> Co-authored-by: Jake-B <jake-b@users.noreply.github.com> Co-authored-by: Mike Robbins <mrobbins@alum.mit.edu> * Explicitly set unmessagable, seems unnessary * Add back missing mesh map features * Fix: "Retrieving nodes" significantly slower after reconnect extracted from #1424 (#1477) * Fix: "Retrieving nodes" significantly slower after reconnect (#1424) The node database retrieval was calling context.save() for every single NodeInfo packet received (250 saves for 250 nodes). This caused severe performance degradation on reconnect when CoreData had accumulated state. Root Cause: - nodeInfoPacket() called context.save() immediately for each node - With 250 nodes, this meant 250 individual CoreData save operations - On first connection, CoreData is fresh and fast - On reconnect, CoreData has accumulated change tracking, undo management, and memory pressure, making each save progressively slower - This resulted in 10+ second retrieval times vs 1-2 seconds initially Solution: - Added deferSave parameter to nodeInfoPacket() function - During database retrieval (.retrievingDatabase state), defer all saves - Perform a single batch save when database retrieval completes (when NONCE_ONLY_DB configCompleteID is received) - This reduces 250 saves to 1 save Performance Impact: - Eliminates N individual saves during node database sync - Reduces database retrieval time back to 1-2 seconds on reconnect - Matches first-connection performance consistently Fixes #1424 * Revert *MessageListUnified files --------- Co-authored-by: Martin Bogomolni <martinbogo@gmail.com> Co-authored-by: Jake-B <jake-b@users.noreply.github.com> * Hide route lines filter from mesh map * Mesh Map: fuzz imprecise locations so they're distinguishable and clickable at the highest zoom levels (#1478) Co-authored-by: Garth Vander Houwen <garth@meshtastic.com> * Fix bad merge * Update Meshtastic/Extensions/CoreData/UserEntityExtension.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update Meshtastic/Views/Nodes/Helpers/Map/MapContent/MeshMapContent.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update Meshtastic/Extensions/CoreData/ChannelEntityExtension.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update Meshtastic/Extensions/CoreData/MyInfoEntityExtension.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update Meshtastic/Extensions/CoreData/ChannelEntityExtension.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Keep list of previous manual connections (#1484) * Keep list of previous manual connections * More descriptive manual connection rows * Merge fixes and new way to show IP on Connect view --------- Co-authored-by: Jake-B <jake-b@users.noreply.github.com> * Show who relayed messages (#1486) * Add identification for node that relayed text messages and add count for ammount of relayers of your message * Ack Relays * upsertPositionPacket: don't use future timestamps to set node's lastHeard (#1488) * R1 NEO * Neo * Update Meshtastic/Views/Settings/AppSettings.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Remove bad if * Git rid of extra environment variable * Update Meshtastic/Accessory/Transports/TCP/TCPTransport.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * MeshMap performance: quick wins (#1490) * MeshMap: change onMapCameraChange frequency to .onEnd so that zooming doesn't cause continuous SwiftUI reevaluation on every frame * MeshMapContent: factor out reducedPrecisionMapCircles into a separate function * MeshMapContent: when multiple reducedPrecisionCircles have the same (lat,lon,radius), just draw one (big perf boost in dense areas) * NodeMap performance improvements for high # positions history (#1480) * NodeMapContent: move Route Lines out of ForEach * NodeMapContent: move Convex Hull out of ForEach * NodeMapContent: Replace `position.nodePosition?` with `node` * NodeMapContent: drop unnecessary LazyVStack in showNodeHistory * NodeMapContent: hoist out nodeColorSwift * Move lineCoords, loraCoords calculations within showRouteLines, showConvexHull respectively * Hoist out repeated node.metadata?.positionFlags lookups / PositionFlags creation * NodeMapContent: remove unused @State * NodeMapSwiftUI: add NodeMapContentEquatableWrapper and NodeMapContentSignature to prevent frequent NodeMapContent recomputation and infinite render loops * NodeMapSwiftUI: disable animation during SwiftUI transactions * NodeMapContent: hoist nodeBorderColor and set allowsHitTesting(false) on history point views * NodeMapContent: prerenderHistoryPointCircle and prerenderHistoryPointArrow to avoid thousands of vector draw operations * NodeMapContent: Shared coordinate list for Route Lines and Convex Hull * NodeMapContent.prerenderHistoryPointArrow: add .frame(width: 16, height: 16) * Fix wantRangeTestPackets to correctly follow rangeTestConfig.enabled (#1489) * Fix interval drop down formatter * Clean up channel qr code functionality. * perferredPeripheralId fix * Set opt in * Retry once 5 second timer. dont throw the error * Queue for peripherals * Fix: hoplimit of dms would always fallback to hops away of the node even when configured hops was higher (#1495) * fix hops setting in dms * Fix hops for exchange position * Final fix * Don't favorite client base * Update device hardware * Prevent nil environment metrics * Bump datadog sdk * fix setting device telemetry enabled (#1515) * Update Muzi R1 Neo to actively supported * fix setting device telemetry enabled --------- Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz> Co-authored-by: Ben Meadors <benmmeadors@gmail.com> * Don't subscribe to mqtt topic if downlink is not on (#1501) * Dont sub if no downlink * moved reload mqtt connect config * Preview enabled in connected devices (#1509) * Update Muzi R1 Neo to actively supported * Preview enabled in connected devices * Fixing indentation * Fixing indentation --------- Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz> Co-authored-by: Ben Meadors <benmmeadors@gmail.com> * UpdateCoreData.updateAnyPacketFrom: mirror firmware's lastHeard/snr/rssi/hopsAway update logic from NodeDB::updateFrom (#1492) * `CLIENT_BASE` add-favorite/role-change confirmation dialog (#1493) * FavoriteNodeButton: refactor task out * AccessoryManager.connectedDeviceRole helper * FavoriteNodeButton: show confirmation dialog when a CLIENT_BASE is trying to add a favorite * addContactFromURL: add comment referencing upcoming change in https://github.com/meshtastic/firmware/pull/8495 * DeviceConfig: role picker: show a warning when selecting CLIENT_BASE, similar to warning shown for ROUTER * Adjust device configuration Client Base warning text * Compass view (#1521) * Added compass view * Added Compass View * Node colors in compass * Update Muzi R1 Neo to actively supported * Update PositionPopover.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update CompassView.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update CompassView.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update Meshtastic/Views/Helpers/CompassView.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update Meshtastic/Views/Helpers/CompassView.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz> Co-authored-by: Ben Meadors <benmmeadors@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Remove discovery queue * revert problematic retry functionalliy * format file * Update & improve zh-Hans translation (#1523) * Update Muzi R1 Neo to actively supported * update & improve zh-Hans translation rt --------- Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz> Co-authored-by: Ben Meadors <benmmeadors@gmail.com> * Update protobufs to 2.7.1 * Add long-turbo preset * Disable Range Test module when primary channel is public/unsecured (#1512) * Update Muzi R1 Neo to actively supported * Disable Range Test module when primary channel is public/unsecured Updated RangeTestConfig.swift to determine whether the primary channel (index 0) is operating without encryption or with a 1-byte minimal PSK. Disabled Range Test UI controls when on a public/default channel to prevent user interaction. Added safety enforcement in the save operation: Range Test enabled flag is automatically forced to false before sending updates to the device. Introduced a computed property isPrimaryChannelPublic following existing code patterns and security indicators (e.g., hexDescription PSK length). Matches the behavior implemented in the Android client for consistent policy across platforms. --------- Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz> Co-authored-by: Ben Meadors <benmmeadors@gmail.com> * Add new device images * Remove print statement, get rid of cut and paste error --------- Co-authored-by: Gnome Adrift <646322+gnomeadrift@users.noreply.github.com> Co-authored-by: Zain Kergaye <62440012+ZainKergaye@users.noreply.github.com> Co-authored-by: NillRudd <102033730+NillRudd@users.noreply.github.com> Co-authored-by: Jake-B <jake-b@users.noreply.github.com> Co-authored-by: Mike Robbins <mrobbins@alum.mit.edu> Co-authored-by: Martin Bogomolni <martinbogo@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: jake-b <1012393+jake-b@users.noreply.github.com> Co-authored-by: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz> Co-authored-by: Ben Meadors <benmmeadors@gmail.com> Co-authored-by: Charles Pinesky <25388414+Vaidios@users.noreply.github.com> Co-authored-by: Radio <35003866+radiolee@users.noreply.github.com> Co-authored-by: Jason Houk <dubsectordevelopment@gmail.com>
This commit is contained in:
parent
09c31e8228
commit
b30dc8645a
96 changed files with 3369 additions and 4282 deletions
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = "<group>"; };
|
||||
2346A7182E2FB9A300CB9239 /* SerialConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerialConnection.swift; sourceTree = "<group>"; };
|
||||
2346A71C2E2FB9C500CB9239 /* SerialTransport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerialTransport.swift; sourceTree = "<group>"; };
|
||||
2349A0492EAE4DA30060A581 /* ManualConnectionList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualConnectionList.swift; sourceTree = "<group>"; };
|
||||
2373AE122D0A216C0086C749 /* MetricsChartSeries.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetricsChartSeries.swift; sourceTree = "<group>"; };
|
||||
2373AE142D0A24930086C749 /* MetricsSeriesList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetricsSeriesList.swift; sourceTree = "<group>"; };
|
||||
2373AE162D0A26620086C749 /* EnvironmentDefaultSeries.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentDefaultSeries.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -407,6 +410,7 @@
|
|||
B3E905B02B71F7F300654D07 /* TextMessageField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextMessageField.swift; sourceTree = "<group>"; };
|
||||
BC10380E2DD4333C00B00BFA /* AddContactIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactIntent.swift; sourceTree = "<group>"; };
|
||||
BC6B45FE2CB2F98900723CEB /* SaveChannelSettingsIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveChannelSettingsIntent.swift; sourceTree = "<group>"; };
|
||||
BCA9A82B2EC802CF00166292 /* CompassView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompassView.swift; sourceTree = "<group>"; };
|
||||
BCB35B4E2E5FC41E00B04F60 /* MessageNodeIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageNodeIntent.swift; sourceTree = "<group>"; };
|
||||
BCB613802C67290800485544 /* SendWaypointIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendWaypointIntent.swift; sourceTree = "<group>"; };
|
||||
BCB613822C672A2600485544 /* MessageChannelIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageChannelIntent.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -832,6 +836,7 @@
|
|||
23D316922E5618D2002FA4FB /* AsyncGate.swift */,
|
||||
23E23F912E392C2B00919073 /* LogRecord+StringRepresentation.swift */,
|
||||
23D9D9382E50DA97005D1C18 /* ResettableTimer.swift */,
|
||||
2349A0492EAE4DA30060A581 /* ManualConnectionList.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1271,6 +1276,7 @@
|
|||
8D3F8A3E2D44BB02009EAAA4 /* PowerMetrics.swift */,
|
||||
237B46952DC8F1C100B22D99 /* RateLimitedButton.swift */,
|
||||
23A1AFB62E42BD2500E46C96 /* RXTXIndicatorView.swift */,
|
||||
BCA9A82B2EC802CF00166292 /* CompassView.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -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" */ = {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
meshPacket.channel = 0
|
||||
var dataMessage = DataMessage()
|
||||
guard let adminData: Data = try? adminPacket.serializedData() else {
|
||||
throw AccessoryError.ioFailed("sendReboot: Unable to serialize Admin packet")
|
||||
if !addChannels {
|
||||
// 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)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
meshPacket.channel = 0
|
||||
var dataMessage = DataMessage()
|
||||
guard let adminData: Data = try? adminPacket.serializedData() else {
|
||||
throw AccessoryError.ioFailed("sendReboot: Unable to serialize Admin packet")
|
||||
}
|
||||
dataMessage.payload = adminData
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
var toRadio: ToRadio!
|
||||
toRadio = ToRadio()
|
||||
toRadio.packet = meshPacket
|
||||
|
||||
let logString = String.localizedStringWithFormat("Sent a LoRa.Config for: %@".localized, String(deviceNum))
|
||||
try await send(toRadio, debugDescription: logString)
|
||||
}
|
||||
dataMessage.payload = adminData
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
var toRadio: ToRadio!
|
||||
toRadio = ToRadio()
|
||||
toRadio.packet = meshPacket
|
||||
|
||||
let logString = String.localizedStringWithFormat("Sent a LoRa.Config for: %@".localized, String(deviceNum))
|
||||
try await send(toRadio, debugDescription: logString)
|
||||
|
||||
Logger.transport.debug("[AccessoryManager] sending wantConfig for saveChannelSet")
|
||||
try await sendWantConfig()
|
||||
}
|
||||
|
|
@ -1813,7 +1814,7 @@ extension AccessoryManager {
|
|||
|
||||
public func sendNodeDBReset(fromUser: UserEntity, toUser: UserEntity) async throws {
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.nodedbReset = 5
|
||||
adminPacket.nodedbReset = true
|
||||
if fromUser != toUser {
|
||||
adminPacket.sessionPasskey = toUser.userNode?.sessionPasskey ?? Data()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ class AccessoryManager: ObservableObject, MqttClientProxyManagerDelegate {
|
|||
let transports: [any Transport]
|
||||
|
||||
// Config
|
||||
public var wantRangeTestPackets = true
|
||||
public var wantRangeTestPackets = false
|
||||
var wantStoreAndForwardPackets = false
|
||||
var shouldAutomaticallyConnectToPreferredPeripheral = true
|
||||
|
||||
|
|
@ -302,9 +302,9 @@ class AccessoryManager: ObservableObject, MqttClientProxyManagerDelegate {
|
|||
Logger.transport.error("updateDevice<T> 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()
|
||||
|
|
|
|||
61
Meshtastic/Accessory/Helpers/ManualConnectionList.swift
Normal file
61
Meshtastic/Accessory/Helpers/ManualConnectionList.swift
Normal file
|
|
@ -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<T>(deviceId: UUID, key: WritableKeyPath<Device, T>, 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
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ enum ConnectionEvent {
|
|||
case disconnected(shouldReconnect: Bool)
|
||||
}
|
||||
|
||||
enum ConnectionState: Equatable {
|
||||
enum ConnectionState: Equatable, Codable {
|
||||
case disconnected
|
||||
case connecting
|
||||
case connected
|
||||
|
|
|
|||
|
|
@ -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))"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ?? [] {
|
||||
|
|
|
|||
12
Meshtastic/Assets.xcassets/HELTECV4.imageset/Contents.json
vendored
Normal file
12
Meshtastic/Assets.xcassets/HELTECV4.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "heltec_v4.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/HELTECV4.imageset/heltec_v4.svg
vendored
Normal file
1
Meshtastic/Assets.xcassets/HELTECV4.imageset/heltec_v4.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 36 KiB |
12
Meshtastic/Assets.xcassets/MUZIR1NEO.imageset/Contents.json
vendored
Normal file
12
Meshtastic/Assets.xcassets/MUZIR1NEO.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "muzi_r1_neo.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
141
Meshtastic/Assets.xcassets/MUZIR1NEO.imageset/muzi_r1_neo.svg
vendored
Normal file
141
Meshtastic/Assets.xcassets/MUZIR1NEO.imageset/muzi_r1_neo.svg
vendored
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 217.61 761.78589"
|
||||
version="1.1"
|
||||
id="svg15"
|
||||
sodipodi:docname="buyer benmeshtastic-01 (6).svg"
|
||||
width="217.61"
|
||||
height="761.78589"
|
||||
inkscape:version="1.4 (e7c3feb1, 2024-10-09)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview15"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="1.0249904"
|
||||
inkscape:cx="-4.3902849"
|
||||
inkscape:cy="683.42102"
|
||||
inkscape:window-width="1472"
|
||||
inkscape:window-height="890"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="38"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg15" />
|
||||
<defs
|
||||
id="defs1">
|
||||
<style
|
||||
id="style1">.cls-1{fill:#9a4451;}.cls-2{fill:#5b232b;}.cls-3{fill:#eadadb;}.cls-4{fill:#191919;}.cls-5{fill:#1f2020;}.cls-6{fill:#353535;}.cls-7{fill:#8b3944;}.cls-8{fill:#2a2a2a;}.cls-9{fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:0.95px;}</style>
|
||||
</defs>
|
||||
<g
|
||||
id="Layer_3"
|
||||
data-name="Layer 3"
|
||||
transform="translate(-407.715,-82.379135)">
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 617.2,633.34 v 21.18 a 5.74,5.74 0 0 1 -11.48,0 v -14.38 l -50,26.45 -1,2.9 1,1.54 0.08,137.28 -0.05,2.08 69.19,-13 V 628.81 Z"
|
||||
id="path1" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 624.85,628.49 v 0.32 l -7.65,4.53 v -1.79 a 5.74,5.74 0 0 0 -11.48,0 v 8.59 l -47.72,28.13 -90.13,48.82 -13.82,92.52 -17.26,0.38 -28.6,-8.44 v -85.47 a 9.33,9.33 0 0 1 1,-4.12 l 19.64,-40 a 8.71,8.71 0 0 1 0.85,-1.4 l 5.13,-7 0.11,-0.82 11,-14.53 v 0 l 5.36,-7.05 h -0.11 l 3.37,-4.6 20.46,-28.15 a 9.35,9.35 0 0 1 5,-3.51 l 5.46,7.23 a 4.65,4.65 0 0 0 3.69,1.83 h 32.07 a 4.62,4.62 0 0 0 3.6,-1.72 l 6.19,-7.68 h 69.87 a 23.93,23.93 0 0 1 23.97,23.93 z"
|
||||
id="path2" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 451.29,641.14 -5.36,7.05 v 0 c -0.13,-0.13 0.33,-0.73 0.33,-0.73 l 5,-6.32 z"
|
||||
id="path3" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 531.05,604.56 -6.19,7.68 a 4.62,4.62 0 0 1 -3.6,1.72 h -32.07 a 4.65,4.65 0 0 1 -3.69,-1.83 L 480,604.9 a 9.41,9.41 0 0 1 2.49,-0.34 z"
|
||||
id="path4" />
|
||||
<path
|
||||
class="cls-3"
|
||||
d="m 531.05,604.56 -6.19,7.68 a 4.62,4.62 0 0 1 -3.6,1.72 h -32.07 a 4.65,4.65 0 0 1 -3.69,-1.83 L 480,604.9 a 9.41,9.41 0 0 1 2.49,-0.34 z"
|
||||
id="path5" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="m 462.31,618.89 v 7 l -12.15,16.71 -11.08,15.2 -10.29,14.2 v -48.63 l 5.51,-37.49 a 2.21,2.21 0 0 1 2.18,-1.88 h 17.73 a 2.21,2.21 0 0 1 2.17,1.81 z"
|
||||
id="path6" />
|
||||
<polygon
|
||||
class="cls-5"
|
||||
points="436.48,584 436.48,125.69 454.02,125.58 454.02,584 "
|
||||
id="polygon6" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="m 456.2,92.91 c 0,0.12 0,0.23 0,0.35 L 455.05,125 a 0.82,0.82 0 0 1 -0.82,0.78 h -18.14 a 0.81,0.81 0 0 1 -0.81,-0.79 l -1,-31.68 a 9.78,9.78 0 0 1 5.05,-8.88 h 0.08 a 12.08,12.08 0 0 1 11.77,0 9.78,9.78 0 0 1 5.02,8.48 z"
|
||||
id="path7" />
|
||||
<polygon
|
||||
class="cls-6"
|
||||
points="439.08,657.8 439.08,584 450.16,584 450.16,642.56 "
|
||||
id="polygon7" />
|
||||
<path
|
||||
class="cls-6"
|
||||
d="m 448.65,93 v 32.7 h -6.37 V 93 a 3.19,3.19 0 0 1 3.19,-3.19 3.15,3.15 0 0 1 2.25,0.94 3.18,3.18 0 0 1 0.93,2.25 z"
|
||||
id="path8" />
|
||||
<path
|
||||
class="cls-7"
|
||||
d="M 555.75,675.9 V 843.69 H 439.42 V 677 a 27.34,27.34 0 0 1 27.34,-27.34 h 62.75 a 26.24,26.24 0 0 1 26.24,26.24 z"
|
||||
id="path9" />
|
||||
<path
|
||||
class="cls-8"
|
||||
d="m 624.85,797.42 v 22.34 a 23.93,23.93 0 0 1 -23.93,23.93 h -168.8 a 23.93,23.93 0 0 1 -23.93,-23.93 v -18.21 l 31.25,8.45 h 118.62 z"
|
||||
id="path10" />
|
||||
</g>
|
||||
<g
|
||||
id="Layer_2"
|
||||
data-name="Layer 2"
|
||||
transform="translate(-407.715,-82.379135)">
|
||||
<path
|
||||
class="cls-9"
|
||||
d="m 624.85,628.49 v 191.27 a 23.94,23.94 0 0 1 -23.93,23.93 H 432.12 A 23.93,23.93 0 0 1 408.19,819.76 V 716.08 a 9.46,9.46 0 0 1 0.95,-4.12 l 19.65,-40 a 8.38,8.38 0 0 1 0.85,-1.41 l 24.91,-34 20.45,-28.14 a 9.35,9.35 0 0 1 7.56,-3.85 h 118.36 a 23.93,23.93 0 0 1 23.93,23.93 z"
|
||||
id="path11" />
|
||||
<rect
|
||||
class="cls-9"
|
||||
x="605.71997"
|
||||
y="625.81"
|
||||
width="11.49"
|
||||
height="34.459999"
|
||||
rx="5.7399998"
|
||||
id="rect11" />
|
||||
<polyline
|
||||
class="cls-9"
|
||||
points="408.19 801.55 439.44 809.97 439.44 809.97 555.79 810.09 555.79 810.09 624.85 797.42"
|
||||
id="polyline11" />
|
||||
<path
|
||||
class="cls-9"
|
||||
d="m 480,604.9 5.46,7.23 a 4.65,4.65 0 0 0 3.69,1.83 h 32.07 a 4.59,4.59 0 0 0 3.59,-1.72 l 6.2,-7.68"
|
||||
id="path12" />
|
||||
<path
|
||||
class="cls-9"
|
||||
d="m 428.79,672 v -48.63 l 5.51,-37.49 a 2.21,2.21 0 0 1 2.18,-1.88 h 17.73 a 2.19,2.19 0 0 1 2.16,1.81 l 5.94,33.08 v 7"
|
||||
id="path13" />
|
||||
<line
|
||||
class="cls-9"
|
||||
x1="436.48001"
|
||||
y1="584"
|
||||
x2="436.48001"
|
||||
y2="125.69"
|
||||
id="line13" />
|
||||
<line
|
||||
class="cls-9"
|
||||
x1="454.01999"
|
||||
y1="584"
|
||||
x2="454.01999"
|
||||
y2="125.58"
|
||||
id="line14" />
|
||||
<path
|
||||
class="cls-9"
|
||||
d="m 454.23,125.73 h -18.14 a 0.82,0.82 0 0 1 -0.82,-0.79 l -1,-31.69 a 9.78,9.78 0 0 1 5,-8.87 h 0.09 a 12.11,12.11 0 0 1 11.77,0 v 0 a 9.81,9.81 0 0 1 5,8.91 l -1.14,31.68 a 0.82,0.82 0 0 1 -0.76,0.76 z"
|
||||
id="path14" />
|
||||
<path
|
||||
class="cls-9"
|
||||
d="M 555.75,843.69 V 675.9 A 26.24,26.24 0 0 0 529.51,649.66 H 466.76 A 27.34,27.34 0 0 0 439.42,677 v 166.69"
|
||||
id="path15" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
12
Meshtastic/Assets.xcassets/THINKNODEM3.imageset/Contents.json
vendored
Normal file
12
Meshtastic/Assets.xcassets/THINKNODEM3.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "thinknode_m3.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/THINKNODEM3.imageset/thinknode_m3.svg
vendored
Normal file
1
Meshtastic/Assets.xcassets/THINKNODEM3.imageset/thinknode_m3.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 8.9 KiB |
12
Meshtastic/Assets.xcassets/THINKNODEM4.imageset/Contents.json
vendored
Normal file
12
Meshtastic/Assets.xcassets/THINKNODEM4.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "thinknode_m4.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/THINKNODEM4.imageset/thinknode_m4.svg
vendored
Normal file
1
Meshtastic/Assets.xcassets/THINKNODEM4.imageset/thinknode_m4.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 95 KiB |
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<MessageEntity> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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> = 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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,23 +6,39 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
extension MyInfoEntity {
|
||||
var messagePredicate: NSPredicate {
|
||||
return NSPredicate(format: "toUser == nil AND isEmoji == false")
|
||||
}
|
||||
|
||||
var messageFetchRequest: NSFetchRequest<MessageEntity> {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<MessageEntity> {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import OSLog
|
||||
|
||||
@propertyWrapper
|
||||
struct UserDefault<T: Decodable> {
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="24299" systemVersion="25A354" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="24299" systemVersion="25A362" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="AmbientLightingConfigEntity" representedClassName="AmbientLightingConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="blue" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="current" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
|
|
@ -164,6 +164,8 @@
|
|||
<attribute name="read" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="realACK" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="receivedACK" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="relayNode" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="relays" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="replyID" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="rssi" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
295
Meshtastic/Views/Helpers/CompassView.swift
Normal file
295
Meshtastic/Views/Helpers/CompassView.swift
Normal file
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<MessageEntity>
|
||||
|
||||
init(user: UserEntity) {
|
||||
self.user = user
|
||||
|
||||
// Configure fetch request here
|
||||
let request: NSFetchRequest<MessageEntity> = 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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<RouteEntity>
|
||||
|
||||
|
||||
@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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Content: View>: 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<Content>, rhs: NodeMapContentEquatableWrapper<Content>) -> 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 {
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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> = NodeInfoEntity.fetchRequest()
|
||||
|
|
@ -154,7 +154,7 @@ fileprivate struct FilteredNodeList: View {
|
|||
@EnvironmentObject var accessoryManager: AccessoryManager
|
||||
@FetchRequest private var nodes: FetchedResults<NodeInfoEntity>
|
||||
@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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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 ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<UpdateInterval>) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
/// <status battery='100' />
|
||||
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
|
||||
/// <contact endpoint='0.0.0.0:4242:tcp' phone='+12345678' callsign='FALKE'/>
|
||||
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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let _ = try decoder.nextFieldNumber() {
|
||||
}
|
||||
// Load everything into unknown fields
|
||||
while try decoder.nextFieldNumber() != nil {}
|
||||
}
|
||||
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(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<D: SwiftProtobuf.Decoder>(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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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<D: SwiftProtobuf.Decoder>(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)
|
||||
|
|
|
|||
|
|
@ -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<D: SwiftProtobuf.Decoder>(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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit c1e31a9655e9920a8b5b8eccdf7c69ef1ae42a49
|
||||
Subproject commit 62ef17b3d1625fc6d78ed661f614d0baad4be9ef
|
||||
Loading…
Add table
Add a link
Reference in a new issue