mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Merge branch '2.3.12_Working_Changes' into fetch-request-api
This commit is contained in:
commit
bc77834a86
125 changed files with 5329 additions and 3092 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# Exclude automatically generated Swift files
|
||||
excluded:
|
||||
- Meshtastic/Protobufs
|
||||
- MeshtasticProtobufs
|
||||
|
||||
line_length: 400
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,16 @@
|
|||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 55;
|
||||
objectVersion = 60;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
25183D462C0A6D97001E31D5 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25183D452C0A6D97001E31D5 /* Logger.swift */; };
|
||||
259792252C2F114500AD1659 /* ChannelEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD58C5F12919AD3C00D5BEFB /* ChannelEntityExtension.swift */; };
|
||||
259792262C2F114500AD1659 /* PositionEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */; };
|
||||
259792272C2F114500AD1659 /* TraceRouteEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE5B4052B227E3200FCDD05 /* TraceRouteEntityExtension.swift */; };
|
||||
259792282C2F114500AD1659 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25183D452C0A6D97001E31D5 /* Logger.swift */; };
|
||||
25A978BA2C13F8ED0003AAE7 /* MeshtasticProtobufs in Frameworks */ = {isa = PBXBuildFile; productRef = 25A978B92C13F8ED0003AAE7 /* MeshtasticProtobufs */; };
|
||||
25A978BC2C13F90D0003AAE7 /* MeshtasticProtobufs in Frameworks */ = {isa = PBXBuildFile; productRef = 25A978BB2C13F90D0003AAE7 /* MeshtasticProtobufs */; };
|
||||
6DA39D8E2A92DC52007E311C /* MeshtasticAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DA39D8D2A92DC52007E311C /* MeshtasticAppDelegate.swift */; };
|
||||
6DEDA55A2A957B8E00321D2E /* DetectionSensorLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEDA5592A957B8E00321D2E /* DetectionSensorLog.swift */; };
|
||||
6DEDA55C2A9592F900321D2E /* MessageEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEDA55B2A9592F900321D2E /* MessageEntityExtension.swift */; };
|
||||
|
|
@ -29,11 +34,7 @@
|
|||
DD007BAE2AA4E91200F5FA12 /* MyInfoEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD007BAD2AA4E91200F5FA12 /* MyInfoEntityExtension.swift */; };
|
||||
DD007BB02AA5981000F5FA12 /* NodeInfoEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD007BAF2AA5981000F5FA12 /* NodeInfoEntityExtension.swift */; };
|
||||
DD0D3D222A55CEB10066DB71 /* CocoaMQTT in Frameworks */ = {isa = PBXBuildFile; productRef = DD0D3D212A55CEB10066DB71 /* CocoaMQTT */; };
|
||||
DD0E20FC2B87090400F2D100 /* atak.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0E20F92B87090400F2D100 /* atak.pb.swift */; };
|
||||
DD0E20FD2B87090400F2D100 /* clientonly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0E20FA2B87090400F2D100 /* clientonly.pb.swift */; };
|
||||
DD0E20FE2B87090400F2D100 /* paxcount.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0E20FB2B87090400F2D100 /* paxcount.pb.swift */; };
|
||||
DD0E21012B8A6F1300F2D100 /* DeviceHardware.json in Resources */ = {isa = PBXBuildFile; fileRef = DD0E21002B8A6BC500F2D100 /* DeviceHardware.json */; };
|
||||
DD0F791B28713C8A00A6FDAD /* AdminMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */; };
|
||||
DD13AA492AB73BF400BA0C98 /* PositionPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD13AA482AB73BF400BA0C98 /* PositionPopover.swift */; };
|
||||
DD15E4F32B8BA56E00654F61 /* PaxCounterConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD15E4F22B8BA56E00654F61 /* PaxCounterConfig.swift */; };
|
||||
DD15E4F52B8BFC8E00654F61 /* PaxCounterLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD15E4F42B8BFC8E00654F61 /* PaxCounterLog.swift */; };
|
||||
|
|
@ -68,27 +69,7 @@
|
|||
DD4975A52B147BA90026544E /* AmbientLightingConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4975A42B147BA90026544E /* AmbientLightingConfig.swift */; };
|
||||
DD4A911E2708C65400501B7E /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4A911D2708C65400501B7E /* AppSettings.swift */; };
|
||||
DD4F23CD28779A3C001D37CB /* EnvironmentMetricsLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4F23CC28779A3C001D37CB /* EnvironmentMetricsLog.swift */; };
|
||||
DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = DD5394FB276993AD00AD86B1 /* SwiftProtobuf */; };
|
||||
DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */; };
|
||||
DD58C5F22919AD3C00D5BEFB /* ChannelEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD58C5F12919AD3C00D5BEFB /* ChannelEntityExtension.swift */; };
|
||||
DD5D0A9C2931B9F200F7EA61 /* EthernetModes.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5D0A9B2931B9F200F7EA61 /* EthernetModes.swift */; };
|
||||
DD5E5202298EE33B00D21B61 /* admin.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51F0298EE33B00D21B61 /* admin.pb.swift */; };
|
||||
DD5E5203298EE33B00D21B61 /* config.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51F1298EE33B00D21B61 /* config.pb.swift */; };
|
||||
DD5E5204298EE33B00D21B61 /* xmodem.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51F2298EE33B00D21B61 /* xmodem.pb.swift */; };
|
||||
DD5E5205298EE33B00D21B61 /* mesh.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51F3298EE33B00D21B61 /* mesh.pb.swift */; };
|
||||
DD5E5206298EE33B00D21B61 /* localonly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51F4298EE33B00D21B61 /* localonly.pb.swift */; };
|
||||
DD5E5207298EE33B00D21B61 /* connection_status.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51F5298EE33B00D21B61 /* connection_status.pb.swift */; };
|
||||
DD5E5208298EE33B00D21B61 /* rtttl.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51F6298EE33B00D21B61 /* rtttl.pb.swift */; };
|
||||
DD5E5209298EE33B00D21B61 /* module_config.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51F7298EE33B00D21B61 /* module_config.pb.swift */; };
|
||||
DD5E520A298EE33B00D21B61 /* channel.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51F8298EE33B00D21B61 /* channel.pb.swift */; };
|
||||
DD5E520C298EE33B00D21B61 /* portnums.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51FA298EE33B00D21B61 /* portnums.pb.swift */; };
|
||||
DD5E520D298EE33B00D21B61 /* storeforward.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51FB298EE33B00D21B61 /* storeforward.pb.swift */; };
|
||||
DD5E520E298EE33B00D21B61 /* mqtt.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51FC298EE33B00D21B61 /* mqtt.pb.swift */; };
|
||||
DD5E520F298EE33B00D21B61 /* cannedmessages.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51FD298EE33B00D21B61 /* cannedmessages.pb.swift */; };
|
||||
DD5E5210298EE33B00D21B61 /* telemetry.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51FE298EE33B00D21B61 /* telemetry.pb.swift */; };
|
||||
DD5E5211298EE33B00D21B61 /* remote_hardware.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51FF298EE33B00D21B61 /* remote_hardware.pb.swift */; };
|
||||
DD5E5212298EE33B00D21B61 /* apponly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E5200298EE33B00D21B61 /* apponly.pb.swift */; };
|
||||
DD5E5213298EE33B00D21B61 /* deviceonly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E5201298EE33B00D21B61 /* deviceonly.pb.swift */; };
|
||||
DD5E523F298F5A9E00D21B61 /* AirQualityIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E523E298F5A9E00D21B61 /* AirQualityIndex.swift */; };
|
||||
DD6193752862F6E600E59241 /* ExternalNotificationConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6193742862F6E600E59241 /* ExternalNotificationConfig.swift */; };
|
||||
DD6193772862F90F00E59241 /* CannedMessagesConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6193762862F90F00E59241 /* CannedMessagesConfig.swift */; };
|
||||
|
|
@ -156,7 +137,6 @@
|
|||
DDC2E15826CE248E0042C5E4 /* MeshtasticApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E15726CE248E0042C5E4 /* MeshtasticApp.swift */; };
|
||||
DDC2E15C26CE248F0042C5E4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */; };
|
||||
DDC2E15F26CE248F0042C5E4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15E26CE248F0042C5E4 /* Preview Assets.xcassets */; };
|
||||
DDC2E17A26CE248F0042C5E4 /* MeshtasticUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E17926CE248F0042C5E4 /* MeshtasticUITests.swift */; };
|
||||
DDC2E18F26CE25FE0042C5E4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */; };
|
||||
DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */; };
|
||||
DDC3B274283F411B00AC321C /* LastHeardText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC3B273283F411B00AC321C /* LastHeardText.swift */; };
|
||||
|
|
@ -168,6 +148,11 @@
|
|||
DDCDC6CB29481FCC004C1DDA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DDCDC6CD29481FCC004C1DDA /* Localizable.strings */; };
|
||||
DDCE4E2C2869F92900BE9F8F /* UserConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCE4E2B2869F92900BE9F8F /* UserConfig.swift */; };
|
||||
DDD43FE32A78C8900083A3E9 /* MqttClientProxyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD43FE22A78C8900083A3E9 /* MqttClientProxyManager.swift */; };
|
||||
DDD5BB092C285DDC007E03CA /* AppLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD5BB082C285DDC007E03CA /* AppLog.swift */; };
|
||||
DDD5BB0B2C285E45007E03CA /* LogDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD5BB0A2C285E45007E03CA /* LogDetail.swift */; };
|
||||
DDD5BB0D2C285F00007E03CA /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD5BB0C2C285F00007E03CA /* Logger.swift */; };
|
||||
DDD5BB102C285FB3007E03CA /* AppLogFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD5BB0F2C285FB3007E03CA /* AppLogFilter.swift */; };
|
||||
DDD5BB162C28B1E4007E03CA /* AppData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD5BB152C28B1E4007E03CA /* AppData.swift */; };
|
||||
DDD6EEAF29BC024700383354 /* Firmware.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD6EEAE29BC024700383354 /* Firmware.swift */; };
|
||||
DDD94A502845C8F5004A87A0 /* DateTimeText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD94A4F2845C8F5004A87A0 /* DateTimeText.swift */; };
|
||||
DDD9E4E4284B208E003777C5 /* UserEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD9E4E3284B208E003777C5 /* UserEntityExtension.swift */; };
|
||||
|
|
@ -177,7 +162,6 @@
|
|||
DDDB26462AACC0B7003AFCB7 /* NodeInfoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB26452AACC0B7003AFCB7 /* NodeInfoItem.swift */; };
|
||||
DDDB26482AACD6D1003AFCB7 /* NodeMapMapkit.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB26472AACD6D1003AFCB7 /* NodeMapMapkit.swift */; };
|
||||
DDDB443629F6287000EE2349 /* MapButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB443529F6287000EE2349 /* MapButtons.swift */; };
|
||||
DDDB443D29F6592F00EE2349 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB443C29F6592F00EE2349 /* NetworkManager.swift */; };
|
||||
DDDB444029F79AB000EE2349 /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB443F29F79AB000EE2349 /* UserDefaults.swift */; };
|
||||
DDDB444229F8A88700EE2349 /* Double.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB444129F8A88700EE2349 /* Double.swift */; };
|
||||
DDDB444429F8A8DD00EE2349 /* Float.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB444329F8A8DD00EE2349 /* Float.swift */; };
|
||||
|
|
@ -203,7 +187,6 @@
|
|||
DDDE5A1429AFEAB900490C6C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDDE5A1229AFEAB900490C6C /* Assets.xcassets */; };
|
||||
DDE0F7C5295F77B700B8AAB3 /* AppSettingsEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE0F7C4295F77B700B8AAB3 /* AppSettingsEnums.swift */; };
|
||||
DDE5B4042B2279A700FCDD05 /* TraceRouteLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE5B4032B2279A700FCDD05 /* TraceRouteLog.swift */; };
|
||||
DDE5B4062B227E3200FCDD05 /* TraceRouteEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE5B4052B227E3200FCDD05 /* TraceRouteEntityExtension.swift */; };
|
||||
DDE9659C2B1C3B6A00531070 /* RouteRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE9659B2B1C3B6A00531070 /* RouteRecorder.swift */; };
|
||||
DDF45C342BC1A48E005ED5F2 /* MQTTIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF45C332BC1A48E005ED5F2 /* MQTTIcon.swift */; };
|
||||
DDF45C372BC46A5A005ED5F2 /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF45C362BC46A5A005ED5F2 /* TimeZone.swift */; };
|
||||
|
|
@ -214,13 +197,6 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
DDC2E17626CE248F0042C5E4 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = DDC2E14C26CE248E0042C5E4 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = DDC2E15326CE248E0042C5E4;
|
||||
remoteInfo = MeshtasticClient;
|
||||
};
|
||||
DDDE5A0129AF163E00490C6C /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = DDC2E14C26CE248E0042C5E4 /* Project object */;
|
||||
|
|
@ -245,7 +221,6 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
25183D452C0A6D97001E31D5 /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
|
||||
6DA39D8D2A92DC52007E311C /* MeshtasticAppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticAppDelegate.swift; sourceTree = "<group>"; };
|
||||
6DEDA5592A957B8E00321D2E /* DetectionSensorLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetectionSensorLog.swift; sourceTree = "<group>"; };
|
||||
6DEDA55B2A9592F900321D2E /* MessageEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageEntityExtension.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -268,13 +243,9 @@
|
|||
DD007BAD2AA4E91200F5FA12 /* MyInfoEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyInfoEntityExtension.swift; sourceTree = "<group>"; };
|
||||
DD007BAF2AA5981000F5FA12 /* NodeInfoEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeInfoEntityExtension.swift; sourceTree = "<group>"; };
|
||||
DD05296F2B77F454008E44CD /* MeshtasticDataModelV 26.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 26.xcdatamodel"; sourceTree = "<group>"; };
|
||||
DD0E20F92B87090400F2D100 /* atak.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = atak.pb.swift; sourceTree = "<group>"; };
|
||||
DD0E20FA2B87090400F2D100 /* clientonly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = clientonly.pb.swift; sourceTree = "<group>"; };
|
||||
DD0E20FB2B87090400F2D100 /* paxcount.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = paxcount.pb.swift; sourceTree = "<group>"; };
|
||||
DD0E20FF2B892E1300F2D100 /* MeshtasticDataModelV 28.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 28.xcdatamodel"; sourceTree = "<group>"; };
|
||||
DD0E21002B8A6BC500F2D100 /* DeviceHardware.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = DeviceHardware.json; sourceTree = "<group>"; };
|
||||
DD0E9C222A30CE3A00580CBB /* MeshtasticDataModelV14.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV14.xcdatamodel; sourceTree = "<group>"; };
|
||||
DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminMessageList.swift; sourceTree = "<group>"; };
|
||||
DD13AA482AB73BF400BA0C98 /* PositionPopover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionPopover.swift; sourceTree = "<group>"; };
|
||||
DD14E72C2A80738F006E39BC /* MeshtasticDataModelV15.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV15.xcdatamodel; sourceTree = "<group>"; };
|
||||
DD15E4F22B8BA56E00654F61 /* PaxCounterConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaxCounterConfig.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -327,23 +298,6 @@
|
|||
DD5D0A9A2931AD6B00F7EA61 /* MeshtasticDataModelV2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV2.xcdatamodel; sourceTree = "<group>"; };
|
||||
DD5D0A9B2931B9F200F7EA61 /* EthernetModes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthernetModes.swift; sourceTree = "<group>"; };
|
||||
DD5E51CC2986643400D21B61 /* MeshtasticDataModelV7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV7.xcdatamodel; sourceTree = "<group>"; };
|
||||
DD5E51F0298EE33B00D21B61 /* admin.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = admin.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51F1298EE33B00D21B61 /* config.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = config.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51F2298EE33B00D21B61 /* xmodem.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = xmodem.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51F3298EE33B00D21B61 /* mesh.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = mesh.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51F4298EE33B00D21B61 /* localonly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = localonly.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51F5298EE33B00D21B61 /* connection_status.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = connection_status.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51F6298EE33B00D21B61 /* rtttl.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = rtttl.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51F7298EE33B00D21B61 /* module_config.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = module_config.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51F8298EE33B00D21B61 /* channel.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = channel.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51FA298EE33B00D21B61 /* portnums.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = portnums.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51FB298EE33B00D21B61 /* storeforward.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = storeforward.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51FC298EE33B00D21B61 /* mqtt.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = mqtt.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51FD298EE33B00D21B61 /* cannedmessages.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = cannedmessages.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51FE298EE33B00D21B61 /* telemetry.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = telemetry.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E51FF298EE33B00D21B61 /* remote_hardware.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = remote_hardware.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E5200298EE33B00D21B61 /* apponly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = apponly.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E5201298EE33B00D21B61 /* deviceonly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = deviceonly.pb.swift; sourceTree = "<group>"; };
|
||||
DD5E523E298F5A9E00D21B61 /* AirQualityIndex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirQualityIndex.swift; sourceTree = "<group>"; };
|
||||
DD6193742862F6E600E59241 /* ExternalNotificationConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalNotificationConfig.swift; sourceTree = "<group>"; };
|
||||
DD6193762862F90F00E59241 /* CannedMessagesConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CannedMessagesConfig.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -422,10 +376,6 @@
|
|||
DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = ../Assets.xcassets; sourceTree = "<group>"; };
|
||||
DDC2E15E26CE248F0042C5E4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||
DDC2E16526CE248F0042C5E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
DDC2E17026CE248F0042C5E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
DDC2E17526CE248F0042C5E4 /* MeshtasticUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MeshtasticUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DDC2E17926CE248F0042C5E4 /* MeshtasticUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticUITests.swift; sourceTree = "<group>"; };
|
||||
DDC2E17B26CE248F0042C5E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationHelper.swift; sourceTree = "<group>"; };
|
||||
DDC3B273283F411B00AC321C /* LastHeardText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastHeardText.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -441,8 +391,13 @@
|
|||
DDCE4E2B2869F92900BE9F8F /* UserConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserConfig.swift; sourceTree = "<group>"; };
|
||||
DDD28D362C0CCCD10063CFA3 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
DDD28D372C0CD2670063CFA3 /* MeshtasticDataModelV 37.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 37.xcdatamodel"; sourceTree = "<group>"; };
|
||||
DDD3BBD4292D763200D609B3 /* MeshtasticTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeshtasticTests.swift; sourceTree = "<group>"; };
|
||||
DDD43FE22A78C8900083A3E9 /* MqttClientProxyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MqttClientProxyManager.swift; sourceTree = "<group>"; };
|
||||
DDD5BB082C285DDC007E03CA /* AppLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLog.swift; sourceTree = "<group>"; };
|
||||
DDD5BB0A2C285E45007E03CA /* LogDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogDetail.swift; sourceTree = "<group>"; };
|
||||
DDD5BB0C2C285F00007E03CA /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
|
||||
DDD5BB0F2C285FB3007E03CA /* AppLogFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLogFilter.swift; sourceTree = "<group>"; };
|
||||
DDD5BB142C28680D007E03CA /* MeshtasticDataModelV 38.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 38.xcdatamodel"; sourceTree = "<group>"; };
|
||||
DDD5BB152C28B1E4007E03CA /* AppData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppData.swift; sourceTree = "<group>"; };
|
||||
DDD6EEAE29BC024700383354 /* Firmware.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Firmware.swift; sourceTree = "<group>"; };
|
||||
DDD94A4F2845C8F5004A87A0 /* DateTimeText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTimeText.swift; sourceTree = "<group>"; };
|
||||
DDD9E4E3284B208E003777C5 /* UserEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserEntityExtension.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -453,7 +408,6 @@
|
|||
DDDB26472AACD6D1003AFCB7 /* NodeMapMapkit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeMapMapkit.swift; sourceTree = "<group>"; };
|
||||
DDDB26492AAD743E003AFCB7 /* MeshtasticDataModelV18.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV18.xcdatamodel; sourceTree = "<group>"; };
|
||||
DDDB443529F6287000EE2349 /* MapButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapButtons.swift; sourceTree = "<group>"; };
|
||||
DDDB443C29F6592F00EE2349 /* NetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkManager.swift; sourceTree = "<group>"; };
|
||||
DDDB443F29F79AB000EE2349 /* UserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaults.swift; sourceTree = "<group>"; };
|
||||
DDDB444129F8A88700EE2349 /* Double.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Double.swift; sourceTree = "<group>"; };
|
||||
DDDB444329F8A8DD00EE2349 /* Float.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Float.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -503,16 +457,9 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
25A978BA2C13F8ED0003AAE7 /* MeshtasticProtobufs in Frameworks */,
|
||||
C9697FA527933B8C00250207 /* SQLite in Frameworks */,
|
||||
DD0D3D222A55CEB10066DB71 /* CocoaMQTT in Frameworks */,
|
||||
DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DDC2E17226CE248F0042C5E4 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -522,6 +469,7 @@
|
|||
files = (
|
||||
DDDE59F629AF163D00490C6C /* SwiftUI.framework in Frameworks */,
|
||||
DDDE59F529AF163D00490C6C /* WidgetKit.framework in Frameworks */,
|
||||
25A978BC2C13F90D0003AAE7 /* MeshtasticProtobufs in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -606,9 +554,11 @@
|
|||
DD4A911C2708C57100501B7E /* Settings */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DDD5BB0E2C285F92007E03CA /* Logs */,
|
||||
DD93800C2BA74CE3008BEC06 /* Channels */,
|
||||
DD97E96728EFE9A00056DDA4 /* About.swift */,
|
||||
DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */,
|
||||
DDD5BB152C28B1E4007E03CA /* AppData.swift */,
|
||||
DDD5BB082C285DDC007E03CA /* AppLog.swift */,
|
||||
DD4A911D2708C65400501B7E /* AppSettings.swift */,
|
||||
DDAB580C2B0DAA9E00147258 /* Routes.swift */,
|
||||
DDE9659B2B1C3B6A00531070 /* RouteRecorder.swift */,
|
||||
|
|
@ -626,33 +576,6 @@
|
|||
path = Settings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DD5E51EF298EE33B00D21B61 /* meshtastic */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DD0E20F92B87090400F2D100 /* atak.pb.swift */,
|
||||
DD0E20FA2B87090400F2D100 /* clientonly.pb.swift */,
|
||||
DD0E20FB2B87090400F2D100 /* paxcount.pb.swift */,
|
||||
DD5E51F0298EE33B00D21B61 /* admin.pb.swift */,
|
||||
DD5E51F1298EE33B00D21B61 /* config.pb.swift */,
|
||||
DD5E51F2298EE33B00D21B61 /* xmodem.pb.swift */,
|
||||
DD5E51F3298EE33B00D21B61 /* mesh.pb.swift */,
|
||||
DD5E51F4298EE33B00D21B61 /* localonly.pb.swift */,
|
||||
DD5E51F5298EE33B00D21B61 /* connection_status.pb.swift */,
|
||||
DD5E51F6298EE33B00D21B61 /* rtttl.pb.swift */,
|
||||
DD5E51F7298EE33B00D21B61 /* module_config.pb.swift */,
|
||||
DD5E51F8298EE33B00D21B61 /* channel.pb.swift */,
|
||||
DD5E51FA298EE33B00D21B61 /* portnums.pb.swift */,
|
||||
DD5E51FB298EE33B00D21B61 /* storeforward.pb.swift */,
|
||||
DD5E51FC298EE33B00D21B61 /* mqtt.pb.swift */,
|
||||
DD5E51FD298EE33B00D21B61 /* cannedmessages.pb.swift */,
|
||||
DD5E51FE298EE33B00D21B61 /* telemetry.pb.swift */,
|
||||
DD5E51FF298EE33B00D21B61 /* remote_hardware.pb.swift */,
|
||||
DD5E5200298EE33B00D21B61 /* apponly.pb.swift */,
|
||||
DD5E5201298EE33B00D21B61 /* deviceonly.pb.swift */,
|
||||
);
|
||||
path = meshtastic;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DD5E523D298F5A7D00D21B61 /* Weather */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -774,14 +697,6 @@
|
|||
path = Map;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DDAF8C5626ED07740058C060 /* Protobufs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DD5E51EF298EE33B00D21B61 /* meshtastic */,
|
||||
);
|
||||
path = Protobufs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DDB75A122A0593CD006ED576 /* Map */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -798,8 +713,6 @@
|
|||
DDCDC6CD29481FCC004C1DDA /* Localizable.strings */,
|
||||
DD3CC6BA28E366DF00FA9159 /* Meshtastic.xcdatamodeld */,
|
||||
DDC2E15626CE248E0042C5E4 /* Meshtastic */,
|
||||
DDC2E16D26CE248F0042C5E4 /* MeshtasticTests */,
|
||||
DDC2E17826CE248F0042C5E4 /* MeshtasticUITests */,
|
||||
DDDE59F729AF163D00490C6C /* Widgets */,
|
||||
DDC2E15526CE248E0042C5E4 /* Products */,
|
||||
DD8EDE9226F97A2B00A5A10B /* Frameworks */,
|
||||
|
|
@ -811,7 +724,6 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
DDC2E15426CE248E0042C5E4 /* Meshtastic.app */,
|
||||
DDC2E17526CE248F0042C5E4 /* MeshtasticUITests.xctest */,
|
||||
DDDE59F429AF163D00490C6C /* WidgetsExtension.appex */,
|
||||
);
|
||||
name = Products;
|
||||
|
|
@ -828,7 +740,6 @@
|
|||
DDC2E1A526CEB32B0042C5E4 /* Helpers */,
|
||||
DDC2E18826CE24EE0042C5E4 /* Model */,
|
||||
DDC4D5662754996200A4208E /* Persistence */,
|
||||
DDAF8C5626ED07740058C060 /* Protobufs */,
|
||||
DDC2E18926CE24F70042C5E4 /* Resources */,
|
||||
DDC2E18726CE24E40042C5E4 /* Views */,
|
||||
DDC2E15726CE248E0042C5E4 /* MeshtasticApp.swift */,
|
||||
|
|
@ -847,24 +758,6 @@
|
|||
path = "Preview Content";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DDC2E16D26CE248F0042C5E4 /* MeshtasticTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DDD3BBD4292D763200D609B3 /* MeshtasticTests.swift */,
|
||||
DDC2E17026CE248F0042C5E4 /* Info.plist */,
|
||||
);
|
||||
path = MeshtasticTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DDC2E17826CE248F0042C5E4 /* MeshtasticUITests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DDC2E17926CE248F0042C5E4 /* MeshtasticUITests.swift */,
|
||||
DDC2E17B26CE248F0042C5E4 /* Info.plist */,
|
||||
);
|
||||
path = MeshtasticUITests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DDC2E18726CE24E40042C5E4 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -917,19 +810,19 @@
|
|||
DDC2E18D26CE25CB0042C5E4 /* Helpers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DDF45C332BC1A48E005ED5F2 /* MQTTIcon.swift */,
|
||||
DD5E523D298F5A7D00D21B61 /* Weather */,
|
||||
DD3CC6BD28E4CD9800FA9159 /* BatteryGauge.swift */,
|
||||
DDB75A222A13CDA9006ED576 /* BatteryLevelCompact.swift */,
|
||||
DD457187293C7E63000C49FB /* BLESignalStrengthIndicator.swift */,
|
||||
DD47E3D526F17ED900029299 /* CircleText.swift */,
|
||||
DDF924C926FBB953009FE055 /* ConnectedDevice.swift */,
|
||||
DDC3B273283F411B00AC321C /* LastHeardText.swift */,
|
||||
DDD94A4F2845C8F5004A87A0 /* DateTimeText.swift */,
|
||||
DDB6ABDA28B0AC6000384BA1 /* DistanceText.swift */,
|
||||
DD3CC6BD28E4CD9800FA9159 /* BatteryGauge.swift */,
|
||||
DD97E96528EFD9820056DDA4 /* MeshtasticLogo.swift */,
|
||||
DD457187293C7E63000C49FB /* BLESignalStrengthIndicator.swift */,
|
||||
DDB75A1D2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift */,
|
||||
DDC3B273283F411B00AC321C /* LastHeardText.swift */,
|
||||
DDB75A202A12B954006ED576 /* LoRaSignalStrength.swift */,
|
||||
DDB75A222A13CDA9006ED576 /* BatteryLevelCompact.swift */,
|
||||
DDB75A1D2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift */,
|
||||
DD97E96528EFD9820056DDA4 /* MeshtasticLogo.swift */,
|
||||
DDF45C332BC1A48E005ED5F2 /* MQTTIcon.swift */,
|
||||
DD5E523D298F5A7D00D21B61 /* Weather */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -945,9 +838,7 @@
|
|||
DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */,
|
||||
DDA6B2E828419CF2003E8C16 /* MeshPackets.swift */,
|
||||
DD964FBC296E6B01007C176F /* EmojiOnlyTextField.swift */,
|
||||
DDDB443C29F6592F00EE2349 /* NetworkManager.swift */,
|
||||
DD3619142B1EF9F900C41C8C /* LocationsHandler.swift */,
|
||||
25183D452C0A6D97001E31D5 /* Logger.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -970,6 +861,15 @@
|
|||
path = Mqtt;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DDD5BB0E2C285F92007E03CA /* Logs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DDD5BB0A2C285E45007E03CA /* LogDetail.swift */,
|
||||
DDD5BB0F2C285FB3007E03CA /* AppLogFilter.swift */,
|
||||
);
|
||||
path = Logs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DDDB26402AABEF7B003AFCB7 /* Helpers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -1003,6 +903,7 @@
|
|||
DD1933772B084F4200771CD5 /* Measurement.swift */,
|
||||
DDFFA7462B3A7F3C004730DB /* Bundle.swift */,
|
||||
DDF45C362BC46A5A005ED5F2 /* TimeZone.swift */,
|
||||
DDD5BB0C2C285F00007E03CA /* Logger.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1050,32 +951,14 @@
|
|||
);
|
||||
name = Meshtastic;
|
||||
packageProductDependencies = (
|
||||
DD5394FB276993AD00AD86B1 /* SwiftProtobuf */,
|
||||
C9697FA427933B8C00250207 /* SQLite */,
|
||||
DD0D3D212A55CEB10066DB71 /* CocoaMQTT */,
|
||||
25A978B92C13F8ED0003AAE7 /* MeshtasticProtobufs */,
|
||||
);
|
||||
productName = MeshtasticClient;
|
||||
productReference = DDC2E15426CE248E0042C5E4 /* Meshtastic.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
DDC2E17426CE248F0042C5E4 /* MeshtasticUITests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = DDC2E18426CE248F0042C5E4 /* Build configuration list for PBXNativeTarget "MeshtasticUITests" */;
|
||||
buildPhases = (
|
||||
DDC2E17126CE248F0042C5E4 /* Sources */,
|
||||
DDC2E17226CE248F0042C5E4 /* Frameworks */,
|
||||
DDC2E17326CE248F0042C5E4 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
DDC2E17726CE248F0042C5E4 /* PBXTargetDependency */,
|
||||
);
|
||||
name = MeshtasticUITests;
|
||||
productName = MeshtasticClientUITests;
|
||||
productReference = DDC2E17526CE248F0042C5E4 /* MeshtasticUITests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.ui-testing";
|
||||
};
|
||||
DDDE59F329AF163D00490C6C /* WidgetsExtension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = DDDE5A0529AF163F00490C6C /* Build configuration list for PBXNativeTarget "WidgetsExtension" */;
|
||||
|
|
@ -1089,6 +972,9 @@
|
|||
dependencies = (
|
||||
);
|
||||
name = WidgetsExtension;
|
||||
packageProductDependencies = (
|
||||
25A978BB2C13F90D0003AAE7 /* MeshtasticProtobufs */,
|
||||
);
|
||||
productName = WidgetsExtension;
|
||||
productReference = DDDE59F429AF163D00490C6C /* WidgetsExtension.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
|
|
@ -1107,10 +993,6 @@
|
|||
CreatedOnToolsVersion = 12.5.1;
|
||||
LastSwiftMigration = 1340;
|
||||
};
|
||||
DDC2E17426CE248F0042C5E4 = {
|
||||
CreatedOnToolsVersion = 12.5.1;
|
||||
TestTargetID = DDC2E15326CE248E0042C5E4;
|
||||
};
|
||||
DDDE59F329AF163D00490C6C = {
|
||||
CreatedOnToolsVersion = 14.2;
|
||||
};
|
||||
|
|
@ -1134,16 +1016,16 @@
|
|||
);
|
||||
mainGroup = DDC2E14B26CE248E0042C5E4;
|
||||
packageReferences = (
|
||||
DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */,
|
||||
C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */,
|
||||
DD0D3D202A55CEB10066DB71 /* XCRemoteSwiftPackageReference "CocoaMQTT" */,
|
||||
25A978B82C13F8ED0003AAE7 /* XCLocalSwiftPackageReference "MeshtasticProtobufs" */,
|
||||
259792242C2F10B600AD1659 /* XCRemoteSwiftPackageReference "swift-protobuf" */,
|
||||
);
|
||||
productRefGroup = DDC2E15526CE248E0042C5E4 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
DDC2E15326CE248E0042C5E4 /* Meshtastic */,
|
||||
DDC2E17426CE248F0042C5E4 /* MeshtasticUITests */,
|
||||
DDDE59F329AF163D00490C6C /* WidgetsExtension */,
|
||||
);
|
||||
};
|
||||
|
|
@ -1164,13 +1046,6 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DDC2E17326CE248F0042C5E4 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DDDE59F229AF163D00490C6C /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
|
@ -1207,14 +1082,16 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
259792252C2F114500AD1659 /* ChannelEntityExtension.swift in Sources */,
|
||||
259792262C2F114500AD1659 /* PositionEntityExtension.swift in Sources */,
|
||||
259792272C2F114500AD1659 /* TraceRouteEntityExtension.swift in Sources */,
|
||||
259792282C2F114500AD1659 /* Logger.swift in Sources */,
|
||||
DDDB444829F8A9C900EE2349 /* String.swift in Sources */,
|
||||
DDFFA7472B3A7F3C004730DB /* Bundle.swift in Sources */,
|
||||
DD5E520C298EE33B00D21B61 /* portnums.pb.swift in Sources */,
|
||||
DD457188293C7E63000C49FB /* BLESignalStrengthIndicator.swift in Sources */,
|
||||
DDA9515C2BC6631200CEA535 /* TelemetryEnums.swift in Sources */,
|
||||
DDFEB3BB29900C1200EE7472 /* CurrentConditionsCompact.swift in Sources */,
|
||||
DD836AE726F6B38600ABCC23 /* Connect.swift in Sources */,
|
||||
DD0E20FD2B87090400F2D100 /* clientonly.pb.swift in Sources */,
|
||||
D93069082B81DF040066FBC8 /* SaveConfigButton.swift in Sources */,
|
||||
DD5E523F298F5A9E00D21B61 /* AirQualityIndex.swift in Sources */,
|
||||
DD964FBF296E76EF007C176F /* WaypointFormMapKit.swift in Sources */,
|
||||
|
|
@ -1223,10 +1100,8 @@
|
|||
DDDB443629F6287000EE2349 /* MapButtons.swift in Sources */,
|
||||
DD5D0A9C2931B9F200F7EA61 /* EthernetModes.swift in Sources */,
|
||||
6DEDA55A2A957B8E00321D2E /* DetectionSensorLog.swift in Sources */,
|
||||
DD5E5203298EE33B00D21B61 /* config.pb.swift in Sources */,
|
||||
DD798B072915928D005217CD /* ChannelMessageList.swift in Sources */,
|
||||
DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */,
|
||||
DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */,
|
||||
DD77093D2AA1AFA3007A8BF0 /* ChannelTips.swift in Sources */,
|
||||
DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */,
|
||||
DDDB444C29F8AAA600EE2349 /* Color.swift in Sources */,
|
||||
|
|
@ -1237,6 +1112,7 @@
|
|||
DD93800E2BA74D0C008BEC06 /* ChannelForm.swift in Sources */,
|
||||
DD41A61529AB0035003C5A37 /* NodeWeatherForecast.swift in Sources */,
|
||||
DDB6ABD628AE742000384BA1 /* BluetoothConfig.swift in Sources */,
|
||||
DDD5BB102C285FB3007E03CA /* AppLogFilter.swift in Sources */,
|
||||
DD4640202AFF10F4002A5ECB /* WaypointForm.swift in Sources */,
|
||||
DD769E0328D18BF1001A3F05 /* DeviceMetricsLog.swift in Sources */,
|
||||
DDAF8C5326EB1DF10058C060 /* BLEManager.swift in Sources */,
|
||||
|
|
@ -1255,23 +1131,20 @@
|
|||
DDDB445429F8AD1600EE2349 /* Data.swift in Sources */,
|
||||
DDDB26462AACC0B7003AFCB7 /* NodeInfoItem.swift in Sources */,
|
||||
DD2AD8A8296D2DF9001FF0E7 /* MapViewSwiftUI.swift in Sources */,
|
||||
DD5E5213298EE33B00D21B61 /* deviceonly.pb.swift in Sources */,
|
||||
DDE5B4042B2279A700FCDD05 /* TraceRouteLog.swift in Sources */,
|
||||
DD5E5208298EE33B00D21B61 /* rtttl.pb.swift in Sources */,
|
||||
DD6193792863875F00E59241 /* SerialConfig.swift in Sources */,
|
||||
DDDB263F2AABEE20003AFCB7 /* NodeList.swift in Sources */,
|
||||
DDD5BB0B2C285E45007E03CA /* LogDetail.swift in Sources */,
|
||||
DDA0B6B2294CDC55001356EC /* Channels.swift in Sources */,
|
||||
DDE9659C2B1C3B6A00531070 /* RouteRecorder.swift in Sources */,
|
||||
B399E8A42B6F486400E4488E /* RetryButton.swift in Sources */,
|
||||
DDB8F4102A9EE5B400230ECE /* Messages.swift in Sources */,
|
||||
DDDB26482AACD6D1003AFCB7 /* NodeMapMapkit.swift in Sources */,
|
||||
DD4A911E2708C65400501B7E /* AppSettings.swift in Sources */,
|
||||
DD5E5209298EE33B00D21B61 /* module_config.pb.swift in Sources */,
|
||||
DD2160AF28C5552500C17253 /* MQTTConfig.swift in Sources */,
|
||||
DD13AA492AB73BF400BA0C98 /* PositionPopover.swift in Sources */,
|
||||
6DEDA55C2A9592F900321D2E /* MessageEntityExtension.swift in Sources */,
|
||||
DDDB444229F8A88700EE2349 /* Double.swift in Sources */,
|
||||
DD5E520F298EE33B00D21B61 /* cannedmessages.pb.swift in Sources */,
|
||||
DDF45C342BC1A48E005ED5F2 /* MQTTIcon.swift in Sources */,
|
||||
DDA9515A2BC6624100CEA535 /* TelemetryWeather.swift in Sources */,
|
||||
DDB75A232A13CDA9006ED576 /* BatteryLevelCompact.swift in Sources */,
|
||||
|
|
@ -1287,7 +1160,6 @@
|
|||
DD33DB622B3D27C7003E1EA0 /* FirmwareApi.swift in Sources */,
|
||||
DD3CC6B528E33FD100FA9159 /* ShareChannels.swift in Sources */,
|
||||
DD1BF2F92776FE2E008C8D2F /* UserMessageList.swift in Sources */,
|
||||
DD5E5207298EE33B00D21B61 /* connection_status.pb.swift in Sources */,
|
||||
DD3CC6C228EB9D4900FA9159 /* UpdateCoreData.swift in Sources */,
|
||||
DDE0F7C5295F77B700B8AAB3 /* AppSettingsEnums.swift in Sources */,
|
||||
DDB6ABE628B1406100384BA1 /* LoraConfigEnums.swift in Sources */,
|
||||
|
|
@ -1295,19 +1167,14 @@
|
|||
DDD43FE32A78C8900083A3E9 /* MqttClientProxyManager.swift in Sources */,
|
||||
DD007BB02AA5981000F5FA12 /* NodeInfoEntityExtension.swift in Sources */,
|
||||
DDDB26422AABF655003AFCB7 /* NodeListItem.swift in Sources */,
|
||||
DD0E20FC2B87090400F2D100 /* atak.pb.swift in Sources */,
|
||||
DDDB444629F8A96500EE2349 /* Character.swift in Sources */,
|
||||
DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */,
|
||||
DDB6ABDB28B0AC6000384BA1 /* DistanceText.swift in Sources */,
|
||||
DD5E520D298EE33B00D21B61 /* storeforward.pb.swift in Sources */,
|
||||
DD94B7402ACCE3BE00DCD1D1 /* MapSettingsForm.swift in Sources */,
|
||||
DD964FC2297272AE007C176F /* WaypointEntityExtension.swift in Sources */,
|
||||
6DA39D8E2A92DC52007E311C /* MeshtasticAppDelegate.swift in Sources */,
|
||||
D93068DB2B81C85E0066FBC8 /* PowerConfig.swift in Sources */,
|
||||
D93068D32B8129510066FBC8 /* MessageContextMenuItems.swift in Sources */,
|
||||
DD0E20FE2B87090400F2D100 /* paxcount.pb.swift in Sources */,
|
||||
DD5E520A298EE33B00D21B61 /* channel.pb.swift in Sources */,
|
||||
25183D462C0A6D97001E31D5 /* Logger.swift in Sources */,
|
||||
DD8EBF43285058FA00426DCA /* DisplayConfig.swift in Sources */,
|
||||
DD964FC42974767D007C176F /* MapViewFitExtension.swift in Sources */,
|
||||
DD47E3D626F17ED900029299 /* CircleText.swift in Sources */,
|
||||
|
|
@ -1323,8 +1190,8 @@
|
|||
D93068DD2B81CA820066FBC8 /* ConfigHeader.swift in Sources */,
|
||||
DDA1C48E28DB49D3009933EC /* ChannelRoles.swift in Sources */,
|
||||
D9BC22DB2B7DE8E2006A37D5 /* TileDownloadStatus.swift in Sources */,
|
||||
DDD5BB092C285DDC007E03CA /* AppLog.swift in Sources */,
|
||||
DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */,
|
||||
DD5E5202298EE33B00D21B61 /* admin.pb.swift in Sources */,
|
||||
DDC1B81A2AB5377B00C71E39 /* MessagesTips.swift in Sources */,
|
||||
DD964FC62975DBFD007C176F /* QueryCoreData.swift in Sources */,
|
||||
DDB75A112A059258006ED576 /* Url.swift in Sources */,
|
||||
|
|
@ -1351,34 +1218,26 @@
|
|||
D93068D92B81509C0066FBC8 /* TapbackResponses.swift in Sources */,
|
||||
DD86D40A287F04F100BAEB7A /* InvalidVersion.swift in Sources */,
|
||||
DDD94A502845C8F5004A87A0 /* DateTimeText.swift in Sources */,
|
||||
DD5E5212298EE33B00D21B61 /* apponly.pb.swift in Sources */,
|
||||
DDB6ABE228B13FB500384BA1 /* PositionConfigEnums.swift in Sources */,
|
||||
DD5E520E298EE33B00D21B61 /* mqtt.pb.swift in Sources */,
|
||||
DD994B69295F88B60013760A /* IntervalEnums.swift in Sources */,
|
||||
DDDCD5702BB26F5C00BE6B60 /* NodeListFilter.swift in Sources */,
|
||||
DD1933762B0835D500771CD5 /* PositionAltitudeChart.swift in Sources */,
|
||||
DD415828285859C4009B0E59 /* TelemetryConfig.swift in Sources */,
|
||||
DDDB443D29F6592F00EE2349 /* NetworkManager.swift in Sources */,
|
||||
DDB6CCFB2AAF805100945AF6 /* NodeMapSwiftUI.swift in Sources */,
|
||||
DD73FD1128750779000852D6 /* PositionLog.swift in Sources */,
|
||||
DD5E5206298EE33B00D21B61 /* localonly.pb.swift in Sources */,
|
||||
DD15E4F52B8BFC8E00654F61 /* PaxCounterLog.swift in Sources */,
|
||||
DD3CC6C028E7A60700FA9159 /* MessagingEnums.swift in Sources */,
|
||||
DD97E96628EFD9820056DDA4 /* MeshtasticLogo.swift in Sources */,
|
||||
DDAB580D2B0DAA9E00147258 /* Routes.swift in Sources */,
|
||||
C9697F9D279336B700250207 /* LocalMBTileOverlay.swift in Sources */,
|
||||
D93068D52B812B700066FBC8 /* MessageDestination.swift in Sources */,
|
||||
DD58C5F22919AD3C00D5BEFB /* ChannelEntityExtension.swift in Sources */,
|
||||
DDA9515E2BC6F56F00CEA535 /* IndoorAirQuality.swift in Sources */,
|
||||
DDDB444E29F8AB0E00EE2349 /* Int.swift in Sources */,
|
||||
DD0F791B28713C8A00A6FDAD /* AdminMessageList.swift in Sources */,
|
||||
DD3CC6BC28E366DF00FA9159 /* Meshtastic.xcdatamodeld in Sources */,
|
||||
DDC4C9FF2A8D982900CE201C /* DetectionSensorConfig.swift in Sources */,
|
||||
D9C983A22B79D1A600BDBE6A /* RequestPositionButton.swift in Sources */,
|
||||
DDDB26442AAC0206003AFCB7 /* NodeDetail.swift in Sources */,
|
||||
DD5E5210298EE33B00D21B61 /* telemetry.pb.swift in Sources */,
|
||||
DD77093F2AA1B146007A8BF0 /* UIColor.swift in Sources */,
|
||||
DD5E5205298EE33B00D21B61 /* mesh.pb.swift in Sources */,
|
||||
DDF6B2482A9AEBF500BA6931 /* StoreForwardConfig.swift in Sources */,
|
||||
DD8169F9271F1A6100F4AB02 /* MeshLogger.swift in Sources */,
|
||||
DD93800B2BA3F968008BEC06 /* NodeMapContent.swift in Sources */,
|
||||
|
|
@ -1387,22 +1246,11 @@
|
|||
DDDB444429F8A8DD00EE2349 /* Float.swift in Sources */,
|
||||
DDAB580F2B0DAFBC00147258 /* LocationEntityExtension.swift in Sources */,
|
||||
B3E905B12B71F7F300654D07 /* TextMessageField.swift in Sources */,
|
||||
DD5E5211298EE33B00D21B61 /* remote_hardware.pb.swift in Sources */,
|
||||
D93068D72B8146690066FBC8 /* MessageText.swift in Sources */,
|
||||
DD5E5204298EE33B00D21B61 /* xmodem.pb.swift in Sources */,
|
||||
DDE5B4062B227E3200FCDD05 /* TraceRouteEntityExtension.swift in Sources */,
|
||||
DDC2E15826CE248E0042C5E4 /* MeshtasticApp.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DDC2E17126CE248F0042C5E4 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DDC2E17A26CE248F0042C5E4 /* MeshtasticUITests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DDDE59F029AF163D00490C6C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
|
@ -1417,11 +1265,6 @@
|
|||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
DDC2E17726CE248F0042C5E4 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = DDC2E15326CE248E0042C5E4 /* Meshtastic */;
|
||||
targetProxy = DDC2E17626CE248F0042C5E4 /* PBXContainerItemProxy */;
|
||||
};
|
||||
DDDE5A0229AF163E00490C6C /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
platformFilter = ios;
|
||||
|
|
@ -1590,12 +1433,12 @@
|
|||
INFOPLIST_FILE = Meshtastic/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Meshtastic;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.3.12;
|
||||
MARKETING_VERSION = 2.3.11;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
@ -1639,48 +1482,6 @@
|
|||
};
|
||||
name = Release;
|
||||
};
|
||||
DDC2E18526CE248F0042C5E4 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = GCH7VS5Y9R;
|
||||
INFOPLIST_FILE = MeshtasticUITests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_TARGET_NAME = Meshtastic;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
DDC2E18626CE248F0042C5E4 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = GCH7VS5Y9R;
|
||||
INFOPLIST_FILE = MeshtasticUITests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_TARGET_NAME = Meshtastic;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
DDDE5A0629AF163F00490C6C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
|
@ -1702,7 +1503,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.3.10;
|
||||
MARKETING_VERSION = 2.3.11;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
|
@ -1735,7 +1536,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.3.10;
|
||||
MARKETING_VERSION = 2.3.11;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
|
@ -1768,15 +1569,6 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
DDC2E18426CE248F0042C5E4 /* Build configuration list for PBXNativeTarget "MeshtasticUITests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
DDC2E18526CE248F0042C5E4 /* Debug */,
|
||||
DDC2E18626CE248F0042C5E4 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
DDDE5A0529AF163F00490C6C /* Build configuration list for PBXNativeTarget "WidgetsExtension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
|
@ -1788,7 +1580,22 @@
|
|||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCLocalSwiftPackageReference section */
|
||||
25A978B82C13F8ED0003AAE7 /* XCLocalSwiftPackageReference "MeshtasticProtobufs" */ = {
|
||||
isa = XCLocalSwiftPackageReference;
|
||||
relativePath = MeshtasticProtobufs;
|
||||
};
|
||||
/* End XCLocalSwiftPackageReference section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
259792242C2F10B600AD1659 /* XCRemoteSwiftPackageReference "swift-protobuf" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/apple/swift-protobuf.git";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 1.26.0;
|
||||
};
|
||||
};
|
||||
C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/stephencelis/SQLite.swift.git";
|
||||
|
|
@ -1805,17 +1612,17 @@
|
|||
minimumVersion = 2.0.0;
|
||||
};
|
||||
};
|
||||
DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/apple/swift-protobuf.git";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 1.19.0;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
25A978B92C13F8ED0003AAE7 /* MeshtasticProtobufs */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = MeshtasticProtobufs;
|
||||
};
|
||||
25A978BB2C13F90D0003AAE7 /* MeshtasticProtobufs */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = MeshtasticProtobufs;
|
||||
};
|
||||
C9697FA427933B8C00250207 /* SQLite */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */;
|
||||
|
|
@ -1826,17 +1633,13 @@
|
|||
package = DD0D3D202A55CEB10066DB71 /* XCRemoteSwiftPackageReference "CocoaMQTT" */;
|
||||
productName = CocoaMQTT;
|
||||
};
|
||||
DD5394FB276993AD00AD86B1 /* SwiftProtobuf */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */;
|
||||
productName = SwiftProtobuf;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
|
||||
/* Begin XCVersionGroup section */
|
||||
DD3CC6BA28E366DF00FA9159 /* Meshtastic.xcdatamodeld */ = {
|
||||
isa = XCVersionGroup;
|
||||
children = (
|
||||
DDD5BB142C28680D007E03CA /* MeshtasticDataModelV 38.xcdatamodel */,
|
||||
DDD28D372C0CD2670063CFA3 /* MeshtasticDataModelV 37.xcdatamodel */,
|
||||
DD31B04D2BDC6FD30024FA63 /* MeshtasticDataModelV 36.xcdatamodel */,
|
||||
DD268D8C2BCC7D11008073AE /* MeshtasticDataModelV 35.xcdatamodel */,
|
||||
|
|
@ -1875,7 +1678,7 @@
|
|||
DD5D0A9A2931AD6B00F7EA61 /* MeshtasticDataModelV2.xcdatamodel */,
|
||||
DD3CC6BB28E366DF00FA9159 /* MeshtasticDataModel.xcdatamodel */,
|
||||
);
|
||||
currentVersion = DDD28D372C0CD2670063CFA3 /* MeshtasticDataModelV 37.xcdatamodel */;
|
||||
currentVersion = DDD5BB142C28680D007E03CA /* MeshtasticDataModelV 38.xcdatamodel */;
|
||||
name = Meshtastic.xcdatamodeld;
|
||||
path = Meshtastic/Meshtastic.xcdatamodeld;
|
||||
sourceTree = "<group>";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"originHash" : "32ea1ad7873163554215310b8eea710c94c63f855b5b01c0b790e7b537747ceb",
|
||||
"originHash" : "2d0b85469585b0d6079eac292d63864096062c24848a49380b9d9727f0ceb96c",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "cocoamqtt",
|
||||
|
|
@ -10,24 +10,6 @@
|
|||
"version" : "2.1.5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "collectionconcurrencykit",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git",
|
||||
"state" : {
|
||||
"revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95",
|
||||
"version" : "0.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "cryptoswift",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/krzyzanowskim/CryptoSwift.git",
|
||||
"state" : {
|
||||
"revision" : "c9c3df6ab812de32bae61fc0cd1bf6d45170ebf0",
|
||||
"version" : "1.8.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "mqttcocoaasyncsocket",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
|
@ -37,15 +19,6 @@
|
|||
"version" : "1.0.8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "sourcekitten",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/jpsim/SourceKitten.git",
|
||||
"state" : {
|
||||
"revision" : "fd4df99170f5e9d7cf9aa8312aa8506e0e7a44e7",
|
||||
"version" : "0.35.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "sqlite.swift",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
|
@ -64,67 +37,13 @@
|
|||
"version" : "3.1.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-argument-parser",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-argument-parser.git",
|
||||
"state" : {
|
||||
"revision" : "0fbc8848e389af3bb55c182bc19ca9d5dc2f255b",
|
||||
"version" : "1.4.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-protobuf",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-protobuf.git",
|
||||
"state" : {
|
||||
"revision" : "ce20dc083ee485524b802669890291c0d8090170",
|
||||
"version" : "1.22.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-syntax",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-syntax.git",
|
||||
"state" : {
|
||||
"revision" : "303e5c5c36d6a558407d364878df131c3546fad8",
|
||||
"version" : "510.0.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swiftlint",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/realm/SwiftLint",
|
||||
"state" : {
|
||||
"revision" : "b515723b16eba33f15c4677ee65f3fef2ce8c255",
|
||||
"version" : "0.55.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swiftytexttable",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/scottrhoyt/SwiftyTextTable.git",
|
||||
"state" : {
|
||||
"revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3",
|
||||
"version" : "0.9.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swxmlhash",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/drmohundro/SWXMLHash.git",
|
||||
"state" : {
|
||||
"revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f",
|
||||
"version" : "7.0.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "yams",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/jpsim/Yams.git",
|
||||
"state" : {
|
||||
"revision" : "9234124cff5e22e178988c18d8b95a8ae8007f76",
|
||||
"version" : "5.1.2"
|
||||
"revision" : "9f0c76544701845ad98716f3f6a774a892152bcb",
|
||||
"version" : "1.26.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@
|
|||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
askForAppToLaunch = "Yes"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
|
|
|
|||
13
Meshtastic.xcworkspace/contents.xcworkspacedata
generated
Normal file
13
Meshtastic.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:README.md">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Meshtastic.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:MeshtasticProtobufs">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
51
Meshtastic.xcworkspace/xcshareddata/swiftpm/Package.resolved
Normal file
51
Meshtastic.xcworkspace/xcshareddata/swiftpm/Package.resolved
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"originHash" : "a8b652cbdc560223dff5bdd094d446cf377b06bd42ce7a7bc4c008a659f0097d",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "cocoamqtt",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/emqx/CocoaMQTT",
|
||||
"state" : {
|
||||
"revision" : "aff43422925cc30b9af319f4c4dce4f52859baf4",
|
||||
"version" : "2.1.8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "mqttcocoaasyncsocket",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/leeway1208/MqttCocoaAsyncSocket",
|
||||
"state" : {
|
||||
"revision" : "ce3e18607fd01079495f86ff6195d8a3ca469f73",
|
||||
"version" : "1.0.8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "sqlite.swift",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/stephencelis/SQLite.swift.git",
|
||||
"state" : {
|
||||
"revision" : "a95fc6df17d108bd99210db5e8a9bac90fe984b8",
|
||||
"version" : "0.15.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "starscream",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/daltoniam/Starscream.git",
|
||||
"state" : {
|
||||
"revision" : "c6bfd1af48efcc9a9ad203665db12375ba6b145a",
|
||||
"version" : "4.0.8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-protobuf",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-protobuf.git",
|
||||
"state" : {
|
||||
"revision" : "9f0c76544701845ad98716f3f6a774a892152bcb",
|
||||
"version" : "1.26.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 3
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
// Copyright(c) Garth Vander Houwen 8/19/22.
|
||||
//
|
||||
import Foundation
|
||||
import MeshtasticProtobufs
|
||||
|
||||
enum BluetoothModes: Int, CaseIterable, Identifiable {
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
// Copyright(c) Garth Vander Houwen 9/10/22.
|
||||
//
|
||||
import Foundation
|
||||
import MeshtasticProtobufs
|
||||
|
||||
// Default of 0 is unset
|
||||
enum ConfigPresets: Int, CaseIterable, Identifiable {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
// Copyright(c) Garth Vander Houwen 9/21/22.
|
||||
//
|
||||
import Foundation
|
||||
import MeshtasticProtobufs
|
||||
|
||||
// Default of 0 is Client
|
||||
enum ChannelRoles: Int, CaseIterable, Identifiable {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import MeshtasticProtobufs
|
||||
|
||||
// Default of 0 is Client
|
||||
enum DeviceRoles: Int, CaseIterable, Identifiable {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import MeshtasticProtobufs
|
||||
|
||||
enum ScreenUnits: Int, CaseIterable, Identifiable {
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import MeshtasticProtobufs
|
||||
|
||||
enum EthernetMode: Int, CaseIterable, Identifiable {
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import MeshtasticProtobufs
|
||||
|
||||
enum RegionCodes: Int, CaseIterable, Identifiable {
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import MeshtasticProtobufs
|
||||
|
||||
enum GpsFormats: Int, CaseIterable, Identifiable {
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
// Copyright(c) Garth Vander Houwen 8/4/22.
|
||||
//
|
||||
import Foundation
|
||||
import MeshtasticProtobufs
|
||||
|
||||
enum RoutingError: Int, CaseIterable, Identifiable {
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
// Copyright(c) Garth Vander Houwen 9/10/22.
|
||||
//
|
||||
import Foundation
|
||||
import MeshtasticProtobufs
|
||||
|
||||
enum SerialBaudRates: Int, CaseIterable, Identifiable {
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
import OSLog
|
||||
|
||||
func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> String {
|
||||
var csvString: String = ""
|
||||
|
|
@ -64,6 +65,27 @@ func detectionsToCsv(detections: [MessageEntity]) -> String {
|
|||
return csvString
|
||||
}
|
||||
|
||||
func logToCsvFile(log: [OSLogEntryLog]) -> String {
|
||||
var csvString: String = ""
|
||||
let localeDateFormat = DateFormatter.dateFormat(fromTemplate: "yyMMddjmma", options: 0, locale: Locale.current)
|
||||
let dateFormatString = (localeDateFormat ?? "MM/dd/YY j:mma").replacingOccurrences(of: ",", with: "")
|
||||
// Create PAX Header
|
||||
csvString = "Process, Category, Level, Message, \("timestamp".localized)"
|
||||
for l in log {
|
||||
csvString += "\n"
|
||||
csvString += String(l.process)
|
||||
csvString += ", "
|
||||
csvString += String(l.category)
|
||||
csvString += ", "
|
||||
csvString += String(l.level.description)
|
||||
csvString += ", "
|
||||
csvString += String(l.composedMessage)
|
||||
csvString += ", "
|
||||
csvString += l.date.formattedDate(format: dateFormatString)
|
||||
}
|
||||
return csvString
|
||||
}
|
||||
|
||||
func paxToCsvFile(pax: [PaxCounterEntity]) -> String {
|
||||
var csvString: String = ""
|
||||
let localeDateFormat = DateFormatter.dateFormat(fromTemplate: "yyMMddjmma", options: 0, locale: Locale.current)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
// Copyright(c) Garth Vander Houwen 11/7/22.
|
||||
//
|
||||
import Foundation
|
||||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
|
||||
extension ChannelEntity {
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
import Foundation
|
||||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
|
||||
extension DeviceMetadataEntity {
|
||||
convenience init(
|
||||
context: NSManagedObjectContext,
|
||||
metadata: DeviceMetadata
|
||||
) {
|
||||
self.init(context: context)
|
||||
self.time = Date()
|
||||
self.deviceStateVersion = Int32(metadata.deviceStateVersion)
|
||||
self.canShutdown = metadata.canShutdown
|
||||
self.hasWifi = metadata.hasWifi_p
|
||||
self.hasBluetooth = metadata.hasBluetooth_p
|
||||
self.hasEthernet = metadata.hasEthernet_p
|
||||
self.role = Int32(metadata.role.rawValue)
|
||||
self.positionFlags = Int32(metadata.positionFlags)
|
||||
// Swift does strings weird, this does work to get the version without the github hash
|
||||
let lastDotIndex = metadata.firmwareVersion.lastIndex(of: ".")
|
||||
var version = metadata.firmwareVersion[...(lastDotIndex ?? String.Index(utf16Offset: 6, in: metadata.firmwareVersion))]
|
||||
version = version.dropLast()
|
||||
self.firmwareVersion = String(version)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
|
||||
extension ExternalNotificationConfigEntity {
|
||||
convenience init(
|
||||
context: NSManagedObjectContext,
|
||||
config: ModuleConfig.ExternalNotificationConfig
|
||||
) {
|
||||
self.init(context: context)
|
||||
self.enabled = config.enabled
|
||||
self.usePWM = config.usePwm
|
||||
self.alertBell = config.alertBell
|
||||
self.alertBellBuzzer = config.alertBellBuzzer
|
||||
self.alertBellVibra = config.alertBellVibra
|
||||
self.alertMessage = config.alertMessage
|
||||
self.alertMessageBuzzer = config.alertMessageBuzzer
|
||||
self.alertMessageVibra = config.alertMessageVibra
|
||||
self.active = config.active
|
||||
self.output = Int32(config.output)
|
||||
self.outputBuzzer = Int32(config.outputBuzzer)
|
||||
self.outputVibra = Int32(config.outputVibra)
|
||||
self.outputMilliseconds = Int32(config.outputMs)
|
||||
self.nagTimeout = Int32(config.nagTimeout)
|
||||
self.useI2SAsBuzzer = config.useI2SAsBuzzer
|
||||
}
|
||||
|
||||
func update(with config: ModuleConfig.ExternalNotificationConfig) {
|
||||
enabled = config.enabled
|
||||
usePWM = config.usePwm
|
||||
alertBell = config.alertBell
|
||||
alertBellBuzzer = config.alertBellBuzzer
|
||||
alertBellVibra = config.alertBellVibra
|
||||
alertMessage = config.alertMessage
|
||||
alertMessageBuzzer = config.alertMessageBuzzer
|
||||
alertMessageVibra = config.alertMessageVibra
|
||||
active = config.active
|
||||
output = Int32(config.output)
|
||||
outputBuzzer = Int32(config.outputBuzzer)
|
||||
outputVibra = Int32(config.outputVibra)
|
||||
outputMilliseconds = Int32(config.outputMs)
|
||||
nagTimeout = Int32(config.nagTimeout)
|
||||
useI2SAsBuzzer = config.useI2SAsBuzzer
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
|
||||
extension MQTTConfigEntity {
|
||||
convenience init(
|
||||
context: NSManagedObjectContext,
|
||||
config: ModuleConfig.MQTTConfig
|
||||
) {
|
||||
self.init(context: context)
|
||||
self.enabled = config.enabled
|
||||
self.proxyToClientEnabled = config.proxyToClientEnabled
|
||||
self.address = config.address
|
||||
self.username = config.username
|
||||
self.password = config.password
|
||||
self.root = config.root
|
||||
self.encryptionEnabled = config.encryptionEnabled
|
||||
self.jsonEnabled = config.jsonEnabled
|
||||
self.tlsEnabled = config.tlsEnabled
|
||||
self.mapReportingEnabled = config.mapReportingEnabled
|
||||
self.mapPositionPrecision = Int32(config.mapReportSettings.positionPrecision)
|
||||
self.mapPublishIntervalSecs = Int32(config.mapReportSettings.publishIntervalSecs)
|
||||
}
|
||||
|
||||
func update(with config: ModuleConfig.MQTTConfig) {
|
||||
enabled = config.enabled
|
||||
proxyToClientEnabled = config.proxyToClientEnabled
|
||||
address = config.address
|
||||
username = config.username
|
||||
password = config.password
|
||||
root = config.root
|
||||
encryptionEnabled = config.encryptionEnabled
|
||||
jsonEnabled = config.jsonEnabled
|
||||
tlsEnabled = config.tlsEnabled
|
||||
mapReportingEnabled = config.mapReportingEnabled
|
||||
mapPositionPrecision = Int32(config.mapReportSettings.positionPrecision)
|
||||
mapPublishIntervalSecs = Int32(config.mapReportSettings.publishIntervalSecs)
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
import CoreData
|
||||
import CoreLocation
|
||||
import MapKit
|
||||
import MeshtasticProtobufs
|
||||
import SwiftUI
|
||||
|
||||
extension PositionEntity {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
|
||||
extension RangeTestConfigEntity {
|
||||
convenience init(
|
||||
context: NSManagedObjectContext,
|
||||
config: ModuleConfig.RangeTestConfig
|
||||
) {
|
||||
self.init(context: context)
|
||||
self.sender = Int32(config.sender)
|
||||
self.enabled = config.enabled
|
||||
self.save = config.save
|
||||
}
|
||||
|
||||
func update(with config: ModuleConfig.RangeTestConfig) {
|
||||
sender = Int32(config.sender)
|
||||
enabled = config.enabled
|
||||
save = config.save
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
|
||||
extension SerialConfigEntity {
|
||||
convenience init(
|
||||
context: NSManagedObjectContext,
|
||||
config: ModuleConfig.SerialConfig
|
||||
) {
|
||||
self.init(context: context)
|
||||
self.enabled = config.enabled
|
||||
self.echo = config.echo
|
||||
self.rxd = Int32(config.rxd)
|
||||
self.txd = Int32(config.txd)
|
||||
self.baudRate = Int32(config.baud.rawValue)
|
||||
self.timeout = Int32(config.timeout)
|
||||
self.mode = Int32(config.mode.rawValue)
|
||||
}
|
||||
|
||||
func update(with config: ModuleConfig.SerialConfig) {
|
||||
enabled = config.enabled
|
||||
echo = config.echo
|
||||
rxd = Int32(config.rxd)
|
||||
txd = Int32(config.txd)
|
||||
baudRate = Int32(config.baud.rawValue)
|
||||
timeout = Int32(config.timeout)
|
||||
mode = Int32(config.mode.rawValue)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
|
||||
extension StoreForwardConfigEntity {
|
||||
convenience init(
|
||||
context: NSManagedObjectContext,
|
||||
config: ModuleConfig.StoreForwardConfig
|
||||
) {
|
||||
self.init(context: context)
|
||||
self.enabled = config.enabled
|
||||
self.heartbeat = config.heartbeat
|
||||
self.records = Int32(config.records)
|
||||
self.historyReturnMax = Int32(config.historyReturnMax)
|
||||
self.historyReturnWindow = Int32(config.historyReturnWindow)
|
||||
}
|
||||
|
||||
func update(with config: ModuleConfig.StoreForwardConfig) {
|
||||
enabled = config.enabled
|
||||
heartbeat = config.heartbeat
|
||||
records = Int32(config.records)
|
||||
historyReturnMax = Int32(config.historyReturnMax)
|
||||
historyReturnWindow = Int32(config.historyReturnWindow)
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import Foundation
|
||||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
|
||||
extension UserEntity {
|
||||
|
||||
|
|
@ -14,10 +15,6 @@ extension UserEntity {
|
|||
self.value(forKey: "allMessages") as? [MessageEntity] ?? [MessageEntity]()
|
||||
}
|
||||
|
||||
var adminMessageList: [MessageEntity] {
|
||||
self.value(forKey: "adminMessages") as? [MessageEntity] ?? [MessageEntity]()
|
||||
}
|
||||
|
||||
var sensorMessageList: [MessageEntity] {
|
||||
self.value(forKey: "detectionSensorMessages") as? [MessageEntity] ?? [MessageEntity]()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,12 +53,12 @@ public extension FileManager {
|
|||
do {
|
||||
accumulatedSize += try contentItemURL.regularFileAllocatedSize()
|
||||
} catch {
|
||||
Logger.services.error("💥 File Manager Error: \(error.localizedDescription)")
|
||||
Logger.services.error("💥 File Manager Error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
|
||||
}
|
||||
if let error = enumeratorError {
|
||||
Logger.services.error("💥 AllocatedSizeOfDirectory enumeratorError = \(error.localizedDescription)")
|
||||
Logger.services.error("💥 AllocatedSizeOfDirectory enumeratorError = \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
|
||||
return Double(accumulatedSize).toBytes
|
||||
|
|
|
|||
|
|
@ -15,3 +15,15 @@ extension Int {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension UInt32 {
|
||||
func toHex() -> String {
|
||||
return String(format: "!%2X", self)
|
||||
}
|
||||
}
|
||||
|
||||
extension Int64 {
|
||||
func toHex() -> String {
|
||||
return String(format: "!%2X", self)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
74
Meshtastic/Extensions/Logger.swift
Normal file
74
Meshtastic/Extensions/Logger.swift
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// Logger.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Copyright(c) Garth Vander Houwen 6/3/24.
|
||||
//
|
||||
|
||||
import OSLog
|
||||
|
||||
extension Logger {
|
||||
|
||||
/// The logger's subsystem.
|
||||
private static var subsystem = Bundle.main.bundleIdentifier!
|
||||
|
||||
/// All admin messages
|
||||
static let admin = Logger(subsystem: subsystem, category: "🏛 Admin")
|
||||
|
||||
/// All logs related to data such as decoding error, parsing issues, etc.
|
||||
static let data = Logger(subsystem: subsystem, category: "🗄️ Data")
|
||||
|
||||
/// All logs related to the mesh
|
||||
static let mesh = Logger(subsystem: subsystem, category: "🕸️ Mesh")
|
||||
|
||||
/// All logs related to MQTT
|
||||
static let mqtt = Logger(subsystem: subsystem, category: "📱 MQTT")
|
||||
|
||||
/// All detailed logs originating from the device (radio).
|
||||
static let radio = Logger(subsystem: subsystem, category: "📟 Radio")
|
||||
|
||||
/// All logs related to services such as network calls, location, etc.
|
||||
static let services = Logger(subsystem: subsystem, category: "🍏 Services")
|
||||
|
||||
/// All logs related to tracking and analytics.
|
||||
static let statistics = Logger(subsystem: subsystem, category: "📊 Stats")
|
||||
|
||||
/// Fetch from the logstore
|
||||
static public func fetch(predicateFormat: String) async throws -> [OSLogEntryLog] {
|
||||
|
||||
let store = try OSLogStore(scope: .currentProcessIdentifier)
|
||||
let position = store.position(timeIntervalSinceLatestBoot: 0)
|
||||
// let calendar = Calendar.current
|
||||
// let dayAgo = calendar.date(byAdding: .day, value: -1, to: Date.now)
|
||||
// let position = store.position(date: dayAgo!)
|
||||
let predicate = NSPredicate(format: predicateFormat)
|
||||
let entries = try store.getEntries(at: position, matching: predicate)
|
||||
|
||||
var logs: [OSLogEntryLog] = []
|
||||
for entry in entries {
|
||||
|
||||
try Task.checkCancellation()
|
||||
|
||||
if let log = entry as? OSLogEntryLog {
|
||||
logs.append(log)
|
||||
}
|
||||
}
|
||||
|
||||
if logs.isEmpty { logs = [] }
|
||||
return logs
|
||||
}
|
||||
}
|
||||
|
||||
extension OSLogEntryLog.Level {
|
||||
var description: String {
|
||||
switch self {
|
||||
case .undefined: "undefined"
|
||||
case .debug: "🪲 Debug"
|
||||
case .info: "ℹ️ Info"
|
||||
case .notice: "⚠️ Notice"
|
||||
case .error: "🚨 Error"
|
||||
case .fault: "💥 Fault"
|
||||
@unknown default: "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Meshtastic/Extensions/Protobufs/NodeInfoExtensions.swift
Normal file
12
Meshtastic/Extensions/Protobufs/NodeInfoExtensions.swift
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import Foundation
|
||||
import MeshtasticProtobufs
|
||||
|
||||
extension NodeInfo {
|
||||
var isValidPosition: Bool {
|
||||
hasPosition &&
|
||||
position.longitudeI != 0 &&
|
||||
position.latitudeI != 0 &&
|
||||
position.latitudeI != 373346000 &&
|
||||
position.longitudeI != -1220090000
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import OSLog
|
||||
|
||||
extension URL {
|
||||
|
||||
|
|
@ -30,4 +31,24 @@ extension URL {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
var attributes: [FileAttributeKey: Any]? {
|
||||
do {
|
||||
return try FileManager.default.attributesOfItem(atPath: path)
|
||||
} catch let error as NSError {
|
||||
Logger.services.error("FileAttribute error: \(error, privacy: . public)")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var fileSize: UInt64 {
|
||||
return attributes?[.size] as? UInt64 ?? UInt64(0)
|
||||
}
|
||||
|
||||
var fileSizeString: String {
|
||||
return ByteCountFormatter.string(fromByteCount: Int64(fileSize), countStyle: .file)
|
||||
}
|
||||
|
||||
var creationDate: Date? {
|
||||
return attributes?[.creationDate] as? Date
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ import CoreData
|
|||
import CoreBluetooth
|
||||
import SwiftUI
|
||||
import MapKit
|
||||
import MeshtasticProtobufs
|
||||
import CocoaMQTT
|
||||
import OSLog
|
||||
import RegexBuilder
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Meshtastic BLE Device Manager
|
||||
|
|
@ -41,11 +43,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
var TORADIO_characteristic: CBCharacteristic!
|
||||
var FROMRADIO_characteristic: CBCharacteristic!
|
||||
var FROMNUM_characteristic: CBCharacteristic!
|
||||
var LOGRADIO_characteristic: CBCharacteristic!
|
||||
let meshtasticServiceCBUUID = CBUUID(string: "0x6BA1B218-15A8-461F-9FA8-5DCAE273EAFD")
|
||||
let TORADIO_UUID = CBUUID(string: "0xF75C76D2-129E-4DAD-A1DD-7866124401E7")
|
||||
let FROMRADIO_UUID = CBUUID(string: "0x2C55E69E-4993-11ED-B878-0242AC120002")
|
||||
let EOL_FROMRADIO_UUID = CBUUID(string: "0x8BA2BCC2-EE02-4A55-A531-C525C5E454D5")
|
||||
let FROMNUM_UUID = CBUUID(string: "0xED9DA18C-A800-4F66-A670-AA7547E34453")
|
||||
let LOGRADIO_UUID = CBUUID(string: "0x6C6FD238-78FA-436B-AACF-15C5BE1EF2E2")
|
||||
|
||||
// MARK: init BLEManager
|
||||
override init() {
|
||||
|
|
@ -62,7 +66,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
func startScanning() {
|
||||
if isSwitchedOn {
|
||||
centralManager.scanForPeripherals(withServices: [meshtasticServiceCBUUID], options: [CBCentralManagerScanOptionAllowDuplicatesKey: false])
|
||||
Logger.services.info("✅ Scanning Started")
|
||||
Logger.services.info("✅ [BLE] Scanning Started")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +74,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
func stopScanning() {
|
||||
if centralManager.isScanning {
|
||||
centralManager.stopScan()
|
||||
Logger.services.info("🛑 Stopped Scanning")
|
||||
Logger.services.info("🛑 [BLE] Stopped Scanning")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +107,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
self.timeoutTimerCount = 0
|
||||
self.startScanning()
|
||||
} else {
|
||||
Logger.services.info("🚨 BLE Connecting 2 Second Timeout Timer Fired \(self.timeoutTimerCount) Time(s): \(name)")
|
||||
Logger.services.info("🚨 [BLE] Connecting 2 Second Timeout Timer Fired \(self.timeoutTimerCount, privacy: .public) Time(s): \(name, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -116,7 +120,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
self.automaticallyReconnect = true
|
||||
}
|
||||
if connectedPeripheral != nil {
|
||||
Logger.services.info("ℹ️ BLE Disconnecting from: \(self.connectedPeripheral.name) to connect to \(peripheral.name ?? "Unknown")")
|
||||
Logger.services.info("ℹ️ [BLE] Disconnecting from: \(self.connectedPeripheral.name, privacy: .public) to connect to \(peripheral.name ?? "Unknown", privacy: .public)")
|
||||
disconnectPeripheral()
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +134,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
let context = ["name": "\(peripheral.name ?? "Unknown")"]
|
||||
timeoutTimer = Timer.scheduledTimer(timeInterval: 1.5, target: self, selector: #selector(timeoutTimerFired), userInfo: context, repeats: true)
|
||||
RunLoop.current.add(timeoutTimer!, forMode: .common)
|
||||
Logger.services.info("ℹ️ BLE Connecting: \(peripheral.name ?? "Unknown")")
|
||||
Logger.services.info("ℹ️ BLE Connecting: \(peripheral.name ?? "Unknown", privacy: .public)")
|
||||
}
|
||||
|
||||
// Disconnect Connected Peripheral
|
||||
|
|
@ -194,19 +198,19 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
connectedPeripheral.peripheral.delegate = self
|
||||
} else {
|
||||
// we are null just disconnect and start over
|
||||
lastConnectionError = "Bluetooth connection error, please try again."
|
||||
lastConnectionError = "🚫 [BLE] Bluetooth connection error, please try again."
|
||||
disconnectPeripheral()
|
||||
return
|
||||
}
|
||||
// Discover Services
|
||||
peripheral.discoverServices([meshtasticServiceCBUUID])
|
||||
Logger.services.info("✅ BLE Connected: \(peripheral.name ?? "Unknown")")
|
||||
Logger.services.info("✅ [BLE] Connected: \(peripheral.name ?? "Unknown", privacy: .public)")
|
||||
}
|
||||
|
||||
// Called when a Peripheral fails to connect
|
||||
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
|
||||
cancelPeripheralConnection()
|
||||
Logger.services.error("🚫 BLE Failed to Connect: \(peripheral.name ?? "Unknown")")
|
||||
Logger.services.error("🚫 [BLE] Failed to Connect: \(peripheral.name ?? "Unknown", privacy: .public)")
|
||||
}
|
||||
|
||||
// Disconnect Peripheral Event
|
||||
|
|
@ -222,7 +226,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
if errorCode == 6 { // CBError.Code.connectionTimeout The connection has timed out unexpectedly.
|
||||
// Happens when device is manually reset / powered off
|
||||
lastConnectionError = "🚨" + String.localizedStringWithFormat("ble.errorcode.6 %@".localized, e.localizedDescription)
|
||||
Logger.services.error("🚨 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(e.localizedDescription)")
|
||||
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown", privacy: .public) Error Code: \(errorCode, privacy: .public) Error: \(e.localizedDescription, privacy: .public)")
|
||||
} else if errorCode == 7 { // CBError.Code.peripheralDisconnected The specified device has disconnected from us.
|
||||
// Seems to be what is received when a tbeam sleeps, immediately recconnecting does not work.
|
||||
if UserDefaults.preferredPeripheralId == peripheral.identifier.uuidString {
|
||||
|
|
@ -239,11 +243,11 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
manager.schedule()
|
||||
}
|
||||
lastConnectionError = "🚨 \(e.localizedDescription)"
|
||||
Logger.services.error("🚨 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(e.localizedDescription)")
|
||||
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown", privacy: .public) Error Code: \(errorCode, privacy: .public) Error: \(e.localizedDescription, privacy: .public)")
|
||||
} else if errorCode == 14 { // Peer removed pairing information
|
||||
// Forgetting and reconnecting seems to be necessary so we need to show the user an error telling them to do that
|
||||
lastConnectionError = "🚨 " + String.localizedStringWithFormat("ble.errorcode.14 %@".localized, e.localizedDescription)
|
||||
Logger.services.error("🚨 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(self.lastConnectionError)")
|
||||
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode, privacy: .public) Error: \(self.lastConnectionError, privacy: .public)")
|
||||
} else {
|
||||
if UserDefaults.preferredPeripheralId == peripheral.identifier.uuidString {
|
||||
manager.notifications = [
|
||||
|
|
@ -259,12 +263,12 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
manager.schedule()
|
||||
}
|
||||
lastConnectionError = "🚨 \(e.localizedDescription)"
|
||||
Logger.services.error("🚨 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(e.localizedDescription)")
|
||||
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown", privacy: .public) Error Code: \(errorCode, privacy: .public) Error: \(e.localizedDescription, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
// Disconnected without error which indicates user intent to disconnect
|
||||
// Happens when swiping to disconnect
|
||||
Logger.services.info("ℹ️ BLE Disconnected: \(peripheral.name ?? "Unknown"): User Initiated Disconnect")
|
||||
Logger.services.info("ℹ️ [BLE] Disconnected: \(peripheral.name ?? "Unknown", privacy: .public): User Initiated Disconnect")
|
||||
}
|
||||
// Start a scan so the disconnected peripheral is moved to the peripherals[] if it is awake
|
||||
self.startScanning()
|
||||
|
|
@ -273,12 +277,12 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
// MARK: Peripheral Services functions
|
||||
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
|
||||
if let error {
|
||||
Logger.services.error("🚫 Discover Services error \(error.localizedDescription)")
|
||||
Logger.services.error("🚫 [BLE] Discover Services error \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
guard let services = peripheral.services else { return }
|
||||
for service in services where service.uuid == meshtasticServiceCBUUID {
|
||||
peripheral.discoverCharacteristics([TORADIO_UUID, FROMRADIO_UUID, FROMNUM_UUID], for: service)
|
||||
Logger.services.info("✅ BLE Service for Meshtastic discovered by \(peripheral.name ?? "Unknown")")
|
||||
peripheral.discoverCharacteristics([TORADIO_UUID, FROMRADIO_UUID, FROMNUM_UUID, LOGRADIO_UUID], for: service)
|
||||
Logger.services.info("✅ [BLE] Service for Meshtastic discovered by \(peripheral.name ?? "Unknown", privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -286,7 +290,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
|
||||
|
||||
if let error {
|
||||
Logger.services.error("🚫 BLE Discover Characteristics error for \(peripheral.name ?? "Unknown") \(error.localizedDescription) disconnecting device")
|
||||
Logger.services.error("🚫 [BLE] Discover Characteristics error for \(peripheral.name ?? "Unknown", privacy: .public) \(error.localizedDescription, privacy: .public) disconnecting device")
|
||||
// Try and stop crashes when this error occurs
|
||||
disconnectPeripheral()
|
||||
return
|
||||
|
|
@ -298,19 +302,24 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
switch characteristic.uuid {
|
||||
|
||||
case TORADIO_UUID:
|
||||
Logger.services.info("✅ BLE did discover TORADIO characteristic for Meshtastic by \(peripheral.name ?? "Unknown")")
|
||||
Logger.services.info("✅ [BLE] did discover TORADIO characteristic for Meshtastic by \(peripheral.name ?? "Unknown", privacy: .public)")
|
||||
TORADIO_characteristic = characteristic
|
||||
|
||||
case FROMRADIO_UUID:
|
||||
Logger.services.info("✅ BLE did discover FROMRADIO characteristic for Meshtastic by \(peripheral.name ?? "Unknown")")
|
||||
Logger.services.info("✅ [BLE] did discover FROMRADIO characteristic for Meshtastic by \(peripheral.name ?? "Unknown", privacy: .public)")
|
||||
FROMRADIO_characteristic = characteristic
|
||||
peripheral.readValue(for: FROMRADIO_characteristic)
|
||||
|
||||
case FROMNUM_UUID:
|
||||
Logger.services.info("✅ BLE did discover FROMNUM (Notify) characteristic for Meshtastic by \(peripheral.name ?? "Unknown")")
|
||||
Logger.services.info("✅ [BLE] did discover FROMNUM (Notify) characteristic for Meshtastic by \(peripheral.name ?? "Unknown", privacy: .public)")
|
||||
FROMNUM_characteristic = characteristic
|
||||
peripheral.setNotifyValue(true, for: characteristic)
|
||||
|
||||
case LOGRADIO_UUID:
|
||||
Logger.services.info("✅ [BLE] did discover LOGRADIO (Notify) characteristic for Meshtastic by \(peripheral.name ?? "Unknown", privacy: .public)")
|
||||
LOGRADIO_characteristic = characteristic
|
||||
peripheral.setNotifyValue(true, for: characteristic)
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
@ -327,13 +336,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
func onMqttConnected() {
|
||||
mqttProxyConnected = true
|
||||
mqttError = ""
|
||||
Logger.services.info("📲 Mqtt Client Proxy onMqttConnected now subscribing to \(self.mqttManager.topic).")
|
||||
Logger.services.info("📲 [MQTT Client Proxy] onMqttConnected now subscribing to \(self.mqttManager.topic, privacy: .public).")
|
||||
mqttManager.mqttClientProxy?.subscribe(mqttManager.topic)
|
||||
}
|
||||
|
||||
func onMqttDisconnected() {
|
||||
mqttProxyConnected = false
|
||||
Logger.services.info("MQTT Disconnected")
|
||||
Logger.services.info("📲 MQTT Disconnected")
|
||||
}
|
||||
|
||||
func onMqttMessageReceived(message: CocoaMQTTMessage) {
|
||||
|
|
@ -360,7 +369,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
func onMqttError(message: String) {
|
||||
mqttProxyConnected = false
|
||||
mqttError = message
|
||||
Logger.services.info("📲 Mqtt Client Proxy onMqttError: \(message)")
|
||||
Logger.services.info("📲 [MQTT Client Proxy] onMqttError: \(message, privacy: .public)")
|
||||
}
|
||||
|
||||
// MARK: Protobuf Methods
|
||||
|
|
@ -387,8 +396,8 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
return 0
|
||||
}
|
||||
|
||||
let messageDescription = "🛎️ Requested Device Metadata for node \(toUser.longName ?? "unknown".localized) by \(fromUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
let messageDescription = "🛎️ [Device Metadata] Requested for node \(toUser.longName ?? "unknown".localized) by \(fromUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
return 0
|
||||
|
|
@ -446,14 +455,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
}
|
||||
do {
|
||||
try context!.save()
|
||||
Logger.data.info("💾 Saved TraceRoute sent to node: \(String(receivingNode?.user?.longName ?? "unknown".localized))")
|
||||
Logger.data.info("💾 Saved TraceRoute sent to node: \(String(receivingNode?.user?.longName ?? "unknown".localized), privacy: .public)")
|
||||
} catch {
|
||||
context!.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data BluetoothConfigEntity: \(nsError)")
|
||||
Logger.data.error("Error Updating Core Data BluetoothConfigEntity: \(nsError, privacy: .public)")
|
||||
}
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.traceroute.sent %@".localized, String(destNum))
|
||||
let logString = String.localizedStringWithFormat("mesh.log.traceroute.sent %@".localized, destNum.toHex())
|
||||
MeshLogger.log("🪧 \(logString)")
|
||||
|
||||
} catch {
|
||||
|
|
@ -490,7 +499,11 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
|
||||
Logger.services.error("didUpdateNotificationStateFor error: \(error?.localizedDescription ?? "Unknown")")
|
||||
if let error {
|
||||
Logger.services.error("💥 [BLE] didUpdateNotificationStateFor error: \(characteristic.uuid, privacy: .public) \(error.localizedDescription, privacy: .public)")
|
||||
} else {
|
||||
Logger.services.info("ℹ️ [BLE] peripheral didUpdateNotificationStateFor \(characteristic.uuid, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Data Read / Update Characteristic Event
|
||||
|
|
@ -498,20 +511,86 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
if let error {
|
||||
|
||||
Logger.services.error("🚫 didUpdateValueFor Characteristic error \(error.localizedDescription)")
|
||||
Logger.services.error("🚫 [BLE] didUpdateValueFor Characteristic error \(error.localizedDescription, privacy: .public)")
|
||||
let errorCode = (error as NSError).code
|
||||
if errorCode == 5 || errorCode == 15 {
|
||||
// BLE PIN connection errors
|
||||
// 5 CBATTErrorDomain Code=5 "Authentication is insufficient."
|
||||
// 15 CBATTErrorDomain Code=15 "Encryption is insufficient."
|
||||
lastConnectionError = "🚨" + String.localizedStringWithFormat("ble.errorcode.pin %@".localized, error.localizedDescription)
|
||||
Logger.services.error("\(error.localizedDescription) Please try connecting again and check the PIN carefully.")
|
||||
Logger.services.error("🚫 [BLE] \(error.localizedDescription, privacy: .public) Please try connecting again and check the PIN carefully.")
|
||||
self.disconnectPeripheral(reconnect: false)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
switch characteristic.uuid {
|
||||
case LOGRADIO_UUID:
|
||||
if characteristic.value == nil || characteristic.value!.isEmpty {
|
||||
return
|
||||
}
|
||||
let coordsSearch = Regex {
|
||||
Capture {
|
||||
Regex {
|
||||
"lat="
|
||||
OneOrMore(.digit)
|
||||
}
|
||||
}
|
||||
Capture {" "}
|
||||
Capture {
|
||||
Regex {
|
||||
"long="
|
||||
OneOrMore(.digit)
|
||||
}
|
||||
}
|
||||
}
|
||||
.anchorsMatchLineEndings()
|
||||
if var log = String(data: characteristic.value!, encoding: .utf8) {
|
||||
/// Debug Log Level
|
||||
if log.starts(with: "DEBUG |") {
|
||||
do {
|
||||
let logString = log
|
||||
if let coordsMatch = try coordsSearch.firstMatch(in: logString) {
|
||||
log = "\(log.replacingOccurrences(of: "DEBUG |", with: "").trimmingCharacters(in: .whitespaces))"
|
||||
log = log.replacingOccurrences(of: "[,]", with: "", options: .regularExpression)
|
||||
Logger.radio.debug("🛰️ \(log.prefix(upTo: coordsMatch.range.lowerBound), privacy: .public) \(coordsMatch.0.replacingOccurrences(of: "[,]", with: "", options: .regularExpression), privacy: .private) \(log.suffix(from: coordsMatch.range.upperBound), privacy: .public)")
|
||||
} else {
|
||||
log = log.replacingOccurrences(of: "[,]", with: "", options: .regularExpression)
|
||||
Logger.radio.debug("🕵🏻♂️ \(log.replacingOccurrences(of: "DEBUG |", with: "").trimmingCharacters(in: .whitespaces), privacy: .public)")
|
||||
}
|
||||
} catch {
|
||||
log = log.replacingOccurrences(of: "[,]", with: "", options: .regularExpression)
|
||||
Logger.radio.debug("🕵🏻♂️ \(log.replacingOccurrences(of: "DEBUG |", with: "").trimmingCharacters(in: .whitespaces), privacy: .public)")
|
||||
}
|
||||
} else if log.starts(with: "INFO |") {
|
||||
do {
|
||||
let logString = log
|
||||
if let coordsMatch = try coordsSearch.firstMatch(in: logString) {
|
||||
log = "\(log.replacingOccurrences(of: "INFO |", with: "").trimmingCharacters(in: .whitespaces))"
|
||||
log = log.replacingOccurrences(of: "[,]", with: "", options: .regularExpression)
|
||||
Logger.radio.info("🛰️ \(log.prefix(upTo: coordsMatch.range.lowerBound), privacy: .public) \(coordsMatch.0.replacingOccurrences(of: "[,]", with: "", options: .regularExpression), privacy: .private) \(log.suffix(from: coordsMatch.range.upperBound), privacy: .public)")
|
||||
} else {
|
||||
log = log.replacingOccurrences(of: "[,]", with: "", options: .regularExpression)
|
||||
Logger.radio.info("📢 \(log.replacingOccurrences(of: "INFO |", with: "").trimmingCharacters(in: .whitespaces), privacy: .public)")
|
||||
}
|
||||
} catch {
|
||||
log = log.replacingOccurrences(of: "[,]", with: "", options: .regularExpression)
|
||||
Logger.radio.info("📢 \(log.replacingOccurrences(of: "INFO |", with: "").trimmingCharacters(in: .whitespaces), privacy: .public)")
|
||||
}
|
||||
} else if log.starts(with: "WARN |") {
|
||||
log = log.replacingOccurrences(of: "[,]", with: "", options: .regularExpression)
|
||||
Logger.radio.warning("⚠️ \(log.replacingOccurrences(of: "WARN |", with: "").trimmingCharacters(in: .whitespaces), privacy: .public)")
|
||||
} else if log.starts(with: "ERROR |") {
|
||||
log = log.replacingOccurrences(of: "[,]", with: "", options: .regularExpression)
|
||||
Logger.radio.error("💥 \(log.replacingOccurrences(of: "ERROR |", with: "").trimmingCharacters(in: .whitespaces), privacy: .public)")
|
||||
} else if log.starts(with: "CRIT |") {
|
||||
log = log.replacingOccurrences(of: "[,]", with: "", options: .regularExpression)
|
||||
Logger.radio.critical("🧨 \(log.replacingOccurrences(of: "CRIT |", with: "").trimmingCharacters(in: .whitespaces), privacy: .public)")
|
||||
} else {
|
||||
log = log.replacingOccurrences(of: "[,]", with: "", options: .regularExpression)
|
||||
Logger.radio.debug("📟 \(log, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
case FROMRADIO_UUID:
|
||||
|
||||
|
|
@ -524,7 +603,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
decodedInfo = try FromRadio(serializedData: characteristic.value!)
|
||||
|
||||
} catch {
|
||||
Logger.services.error("\(error.localizedDescription) \(characteristic.value!)")
|
||||
Logger.services.error("💥 \(error.localizedDescription, privacy: .public) \(characteristic.value!, privacy: .public)")
|
||||
}
|
||||
|
||||
// Publish mqttClientProxyMessages received on the from radio
|
||||
|
|
@ -555,6 +634,28 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
connectedPeripheral.num = myInfo?.myNodeNum ?? 0
|
||||
connectedPeripheral.name = myInfo?.bleName ?? "unknown".localized
|
||||
connectedPeripheral.longName = myInfo?.bleName ?? "unknown".localized
|
||||
let newConnection = Int64(UserDefaults.preferredPeripheralNum) != Int64(decodedInfo.myInfo.myNodeNum)
|
||||
if newConnection {
|
||||
let container = NSPersistentContainer(name: "Meshtastic")
|
||||
if let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
|
||||
let databasePath = url.appendingPathComponent("backup")
|
||||
.appendingPathComponent("\(UserDefaults.preferredPeripheralNum)")
|
||||
.appendingPathComponent("Meshtastic.sqlite")
|
||||
if FileManager.default.fileExists(atPath: databasePath.path) {
|
||||
do {
|
||||
disconnectPeripheral(reconnect: false)
|
||||
try container.restorePersistentStore(from: databasePath)
|
||||
let request = MyInfoEntity.fetchRequest()
|
||||
try context?.fetch(request)
|
||||
UserDefaults.preferredPeripheralNum = Int(myInfo?.myNodeNum ?? 0)
|
||||
connectTo(peripheral: peripheral)
|
||||
Logger.data.notice("🗂️ Restored Core data for /\(UserDefaults.preferredPeripheralNum, privacy: .public)")
|
||||
} catch {
|
||||
Logger.data.error("🗂️ Restore Core data copy error: \(error, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tryClearExistingChannels()
|
||||
}
|
||||
|
|
@ -720,7 +821,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
} catch {
|
||||
context!.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data TraceRouteHOp: \(nsError)")
|
||||
Logger.data.error("Error Updating Core Data TraceRouteHOp: \(nsError, privacy: .public)")
|
||||
}
|
||||
let logString = String.localizedStringWithFormat("mesh.log.traceroute.received.route %@".localized, routeString)
|
||||
MeshLogger.log("🪧 \(logString)")
|
||||
|
|
@ -747,7 +848,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
invalidVersion = false
|
||||
lastConnectionError = ""
|
||||
isSubscribed = true
|
||||
Logger.mesh.info("🤜 Want Config Complete. ID:\(decodedInfo.configCompleteID)")
|
||||
Logger.mesh.info("[BLE] 🤜 Want Config Complete. ID:\(decodedInfo.configCompleteID)")
|
||||
peripherals.removeAll(where: { $0.peripheral.state == CBPeripheralState.disconnected })
|
||||
// Config conplete returns so we don't read the characteristic again
|
||||
|
||||
|
|
@ -801,9 +902,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
}
|
||||
|
||||
case FROMNUM_UUID:
|
||||
Logger.services.info("🗞️ BLE (Notify) characteristic, value will be read next")
|
||||
Logger.services.info("🗞️ [BLE] (Notify) characteristic value will be read next")
|
||||
default:
|
||||
Logger.services.error("Unhandled Characteristic UUID: \(characteristic.uuid)")
|
||||
Logger.services.error("🚫 Unhandled Characteristic UUID: \(characteristic.uuid, privacy: .public)")
|
||||
}
|
||||
if FROMRADIO_characteristic != nil {
|
||||
// Either Read the config complete value or from num notify value
|
||||
|
|
@ -905,18 +1006,18 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
}
|
||||
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
let logString = String.localizedStringWithFormat("mesh.log.textmessage.sent %@ %@ %@".localized, String(newMessage.messageId), String(fromUserNum), String(toUserNum))
|
||||
let logString = String.localizedStringWithFormat("mesh.log.textmessage.sent %@ %@ %@".localized, String(newMessage.messageId), fromUserNum.toHex(), toUserNum.toHex())
|
||||
|
||||
MeshLogger.log("💬 \(logString)")
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Saved a new sent message from \(self.connectedPeripheral.num) to \(toUserNum)")
|
||||
Logger.data.info("💾 Saved a new sent message from \(self.connectedPeripheral.num.toHex(), privacy: .public) to \(toUserNum.toHex(), privacy: .public)")
|
||||
success = true
|
||||
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Unresolved Core Data error in Send Message Function your database is corrupted running a node db reset should clean up the data. Error: \(nsError)")
|
||||
Logger.data.error("Unresolved Core Data error in Send Message Function your database is corrupted running a node db reset should clean up the data. Error: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -982,11 +1083,11 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
}
|
||||
do {
|
||||
try context!.save()
|
||||
Logger.data.info("💾 Updated Waypoint from Waypoint App Packet From: \(fromNodeNum)")
|
||||
Logger.data.info("💾 Updated Waypoint from Waypoint App Packet From: \(fromNodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context!.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving NodeInfoEntity from WAYPOINT_APP \(nsError)")
|
||||
Logger.data.error("Error Saving NodeInfoEntity from WAYPOINT_APP \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
return success
|
||||
|
|
@ -1060,7 +1161,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
return false
|
||||
}
|
||||
let messageDescription = "🚀 Sent Set Fixed Postion Admin Message to: \(fromUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: fromUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -1085,7 +1186,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
return false
|
||||
}
|
||||
let messageDescription = "🚀 Sent Remove Fixed Position Admin Message to: \(fromUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: fromUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -1155,7 +1256,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
return false
|
||||
}
|
||||
let messageDescription = "🚀 Sent Shutdown Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -1180,7 +1281,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
return false
|
||||
}
|
||||
let messageDescription = "🚀 Sent Reboot Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -1205,7 +1306,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
return false
|
||||
}
|
||||
let messageDescription = "🚀 Sent Reboot OTA Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -1231,7 +1332,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
}
|
||||
automaticallyReconnect = false
|
||||
let messageDescription = "🚀 Sent enter DFU mode Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -1256,7 +1357,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
}
|
||||
|
||||
let messageDescription = "🚀 Sent Factory Reset Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -1280,7 +1381,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
meshPacket.decoded = dataMessage
|
||||
let messageDescription = "🚀 Sent NodeDB Reset Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -1323,7 +1424,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🎛️ Requested Channel \(channel.index) for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
return 0
|
||||
|
|
@ -1347,7 +1448,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛟 Saved Channel \(channel.index) for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
return 0
|
||||
|
|
@ -1493,7 +1594,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
return 0
|
||||
}
|
||||
let messageDescription = "🛟 Saved User Config for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
return 0
|
||||
|
|
@ -1614,7 +1715,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
let messageDescription = "🛟 Saved Ham Parameters for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
return 0
|
||||
|
|
@ -1638,7 +1739,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
let messageDescription = "🛟 Saved Bluetooth Config for \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertBluetoothConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1666,7 +1767,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
let messageDescription = "🛟 Saved Device Config for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertDeviceConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1693,7 +1794,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
let messageDescription = "🛟 Saved Display Config for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertDisplayConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1720,7 +1821,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
let messageDescription = "🛟 Saved LoRa Config for \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertLoRaConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1751,7 +1852,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛟 Saved Position Config for \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertPositionConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1782,7 +1883,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛟 Saved Power Config for \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertPowerConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1813,7 +1914,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛟 Saved Network Config for \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertNetworkConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1843,7 +1944,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛟 Saved Ambient Lighting Module Config for \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertAmbientLightingModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1873,7 +1974,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛟 Saved Canned Message Module Config for \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertCannedMessagesModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1904,7 +2005,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛟 Saved Canned Message Module Messages for \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1934,7 +2035,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛟 Saved Detection Sensor Module Config for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertDetectionSensorModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1963,7 +2064,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛟 Saved External Notification Module Config for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertExternalNotificationModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -1992,7 +2093,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛟 Saved PAX Counter Module Config for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertPaxCounterModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -2022,7 +2123,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛟 Saved RTTTL Ringtone Config for \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertRtttlConfigPacket(ringtone: ringtone, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -2053,7 +2154,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛟 Saved MQTT Config for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertMqttModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -2082,7 +2183,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛟 Saved Range Test Module Config for \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertRangeTestModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -2112,7 +2213,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛟 Saved Serial Module Config for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertSerialModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -2141,7 +2242,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛟 Saved Store & Forward Module Config for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertStoreForwardModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -2170,7 +2271,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
upsertTelemetryModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
|
@ -2201,7 +2302,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛎️ Sent a Get Channel \(channelIndex) Request Admin Message for node: \(toUser.longName ?? "unknown".localized))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
@ -2275,7 +2376,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛎️ Requested Bluetooth Config on admin channel \(adminIndex) for node: \(String(connectedPeripheral.num))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2306,7 +2407,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛎️ Requested Device Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2337,7 +2438,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛎️ Requested Display Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2368,7 +2469,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛎️ Requested LoRa Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
@ -2400,7 +2501,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
|
||||
let messageDescription = "🛎️ Requested Network Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2430,7 +2531,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested Position Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2460,7 +2561,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested Power Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2490,7 +2591,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested Ambient Lighting Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2520,7 +2621,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested Canned Messages Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2550,7 +2651,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested External Notificaiton Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2580,7 +2681,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested PAX Counter Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2610,7 +2711,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested RTTTL Ringtone Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2640,7 +2741,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested Range Test Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2670,7 +2771,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested MQTT Module Config on admin channel \(adminIndex) for node: \(String(connectedPeripheral.num))"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2700,7 +2801,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested Detection Sensor Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2730,7 +2831,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested Serial Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2760,7 +2861,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested Store and Forward Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2790,14 +2891,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested Telemetry Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Send an admin message to a radio, save a message to core data for logging
|
||||
private func sendAdminMessageToRadio(meshPacket: MeshPacket, adminDescription: String, fromUser: UserEntity, toUser: UserEntity) -> Bool {
|
||||
private func sendAdminMessageToRadio(meshPacket: MeshPacket, adminDescription: String) -> Bool {
|
||||
|
||||
var toRadio: ToRadio!
|
||||
toRadio = ToRadio()
|
||||
|
|
@ -2807,25 +2908,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
}
|
||||
|
||||
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(meshPacket.id)
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.admin = true
|
||||
newMessage.adminDescription = adminDescription
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
|
||||
do {
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
try context!.save()
|
||||
Logger.mesh.debug("\(adminDescription)")
|
||||
return true
|
||||
} catch {
|
||||
context!.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error inserting new core data MessageEntity: \(nsError)")
|
||||
}
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
Logger.mesh.debug("\(adminDescription)")
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
@ -2860,7 +2945,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
}
|
||||
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
Logger.mesh.debug("📮 Sent a request for a Store & Forward Client History to \(toUser.num) for the last \(120) minutes.")
|
||||
Logger.mesh.debug("📮 Sent a request for a Store & Forward Client History to \(toUser.num.toHex(), privacy: .public) for the last \(120, privacy: .public) minutes.")
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -2871,9 +2956,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
// Handle each of the store and forward request / response messages
|
||||
switch storeAndForwardMessage.rr {
|
||||
case .unset:
|
||||
MeshLogger.log("📮 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("📮 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .routerError:
|
||||
MeshLogger.log("☠️ Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("☠️ Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .routerHeartbeat:
|
||||
/// When we get a router heartbeat we know there is a store and forward node on the network
|
||||
/// Check if it is the primary S&F Router and save the timestamp of the last heartbeat so that we can show the request message history menu item on node long press if the router has been seen recently
|
||||
|
|
@ -2901,13 +2986,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
Logger.data.error("Save Store and Forward Router Error")
|
||||
}
|
||||
}
|
||||
MeshLogger.log("💓 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("💓 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .routerPing:
|
||||
MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .routerPong:
|
||||
MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .routerBusy:
|
||||
MeshLogger.log("🐝 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("🐝 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .routerHistory:
|
||||
/// Set the Router History Last Request Value
|
||||
guard let routerNode = getNodeInfo(id: Int64(packet.from), context: context) else {
|
||||
|
|
@ -2927,28 +3012,28 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
context.rollback()
|
||||
Logger.data.error("Save Store and Forward Router Error")
|
||||
}
|
||||
MeshLogger.log("📜 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("📜 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .routerStats:
|
||||
MeshLogger.log("📊 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("📊 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .clientError:
|
||||
MeshLogger.log("☠️ Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("☠️ Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .clientHistory:
|
||||
MeshLogger.log("📜 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("📜 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .clientStats:
|
||||
MeshLogger.log("📊 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("📊 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .clientPing:
|
||||
MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .clientPong:
|
||||
MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .clientAbort:
|
||||
MeshLogger.log("🛑 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("🛑 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .UNRECOGNIZED:
|
||||
MeshLogger.log("📮 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("📮 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
case .routerTextDirect:
|
||||
MeshLogger.log("💬 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("💬 Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
textMessageAppPacket(packet: packet, wantRangeTestPackets: false, connectedNode: connectedNodeNum, storeForward: true, context: context)
|
||||
case .routerTextBroadcast:
|
||||
MeshLogger.log("✉️ Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from)")
|
||||
MeshLogger.log("✉️ Store and Forward \(storeAndForwardMessage.rr) message received from \(packet.from.toHex())")
|
||||
textMessageAppPacket(packet: packet, wantRangeTestPackets: false, connectedNode: connectedNodeNum, storeForward: true, context: context)
|
||||
}
|
||||
}
|
||||
|
|
@ -2969,11 +3054,11 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
do {
|
||||
try context.save()
|
||||
} catch {
|
||||
Logger.data.error("Failed to clear existing channels from local app database: \(error.localizedDescription)")
|
||||
Logger.data.error("Failed to clear existing channels from local app database: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Logger.data.error("Failed to find a node MyInfo to save these channels to: \(error.localizedDescription)")
|
||||
Logger.data.error("Failed to find a node MyInfo to save these channels to: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2984,7 +3069,7 @@ extension BLEManager: CBCentralManagerDelegate {
|
|||
// MARK: Bluetooth enabled/disabled
|
||||
func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
if central.state == CBManagerState.poweredOn {
|
||||
Logger.services.debug("🔌 BLE powered on")
|
||||
Logger.services.info("✅ [BLE] powered on")
|
||||
isSwitchedOn = true
|
||||
startScanning()
|
||||
} else {
|
||||
|
|
@ -3009,7 +3094,7 @@ extension BLEManager: CBCentralManagerDelegate {
|
|||
default:
|
||||
status = "default"
|
||||
}
|
||||
Logger.services.debug("📜 BLEManager status: \(status)")
|
||||
Logger.services.info("📜 [BLE] Bluetooth status: \(status)")
|
||||
}
|
||||
|
||||
// Called each time a peripheral is discovered
|
||||
|
|
@ -3017,7 +3102,7 @@ extension BLEManager: CBCentralManagerDelegate {
|
|||
|
||||
if self.automaticallyReconnect && peripheral.identifier.uuidString == UserDefaults.standard.object(forKey: "preferredPeripheralId") as? String ?? "" {
|
||||
self.connectTo(peripheral: peripheral)
|
||||
Logger.services.info("BLE Reconnecting to prefered peripheral: \(peripheral.name ?? "Unknown")")
|
||||
Logger.services.info("✅ [BLE] Reconnecting to prefered peripheral: \(peripheral.name ?? "Unknown", privacy: .public)")
|
||||
}
|
||||
let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String
|
||||
let device = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: name ?? "Unknown", shortName: "?", longName: name ?? "Unknown", firmwareVersion: "Unknown", rssi: RSSI.intValue, lastUpdate: Date(), peripheral: peripheral)
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class LocalNotificationManager {
|
|||
UNUserNotificationCenter.current().getPendingNotificationRequests { notifications in
|
||||
|
||||
for notification in notifications {
|
||||
Logger.services.debug("\(notification)")
|
||||
Logger.services.debug("\(notification, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,6 @@ class LocationHelper: NSObject, ObservableObject, CLLocationManagerDelegate {
|
|||
|
||||
}
|
||||
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
|
||||
Logger.services.error("Location manager error: \(error.localizedDescription)")
|
||||
Logger.services.error("Location manager error: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ import OSLog
|
|||
if self.manager.authorizationStatus == .notDetermined {
|
||||
self.manager.requestWhenInUseAuthorization()
|
||||
}
|
||||
Logger.services.info("📍 Starting location updates")
|
||||
Logger.services.info("📍 [App] Starting location updates")
|
||||
Task {
|
||||
do {
|
||||
self.updatesStarted = true
|
||||
|
|
@ -70,14 +70,14 @@ import OSLog
|
|||
}
|
||||
}
|
||||
} catch {
|
||||
Logger.services.error("💥 Could not start location updates: \(error.localizedDescription)")
|
||||
Logger.services.error("💥 [App] Could not start location updates: \(error.localizedDescription)")
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func stopLocationUpdates() {
|
||||
Logger.services.info("🛑 Stopping location updates")
|
||||
Logger.services.info("🛑 [App] Stopping location updates")
|
||||
self.updatesStarted = false
|
||||
}
|
||||
|
||||
|
|
@ -85,15 +85,15 @@ import OSLog
|
|||
if smartPostion {
|
||||
let age = -location.timestamp.timeIntervalSinceNow
|
||||
if age > 10 {
|
||||
Logger.services.warning("📍 Bad Location \(self.count): Too Old \(age) seconds ago \(location)")
|
||||
Logger.services.warning("📍 [App] Bad Location \(self.count, privacy: .public): Too Old \(age, privacy: .public) seconds ago \(location, privacy: .private)")
|
||||
return false
|
||||
}
|
||||
if location.horizontalAccuracy < 0 {
|
||||
Logger.services.warning("📍 Bad Location \(self.count): Horizontal Accuracy: \(location.horizontalAccuracy) \(location)")
|
||||
Logger.services.warning("📍 [App] Bad Location \(self.count, privacy: .public): Horizontal Accuracy: \(location.horizontalAccuracy) \(location, privacy: .private)")
|
||||
return false
|
||||
}
|
||||
if location.horizontalAccuracy > 5 {
|
||||
Logger.services.warning("📍 Bad Location \(self.count): Horizontal Accuracy: \(location.horizontalAccuracy) \(location)")
|
||||
Logger.services.warning("📍 [App] Bad Location \(self.count, privacy: .public): Horizontal Accuracy: \(location.horizontalAccuracy) \(location, privacy: .private)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@ extension Logger {
|
|||
private static var subsystem = Bundle.main.bundleIdentifier!
|
||||
|
||||
/// All logs related to data such as decoding error, parsing issues, etc.
|
||||
static let data = Logger(subsystem: subsystem, category: "🗄️ Data")
|
||||
public static let data = Logger(subsystem: subsystem, category: "🗄️ Data")
|
||||
|
||||
/// All logs related to the mesh
|
||||
static let mesh = Logger(subsystem: subsystem, category: "🕸️ Mesh")
|
||||
public static let mesh = Logger(subsystem: subsystem, category: "🕸️ Mesh")
|
||||
|
||||
/// All logs related to services such as network calls, location, etc.
|
||||
static let services = Logger(subsystem: subsystem, category: "🍏 Services")
|
||||
public static let services = Logger(subsystem: subsystem, category: "🍏 Services")
|
||||
|
||||
/// All logs related to tracking and analytics.
|
||||
static let statistics = Logger(subsystem: subsystem, category: "📈 Stats")
|
||||
public static let statistics = Logger(subsystem: subsystem, category: "📈 Stats")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class OfflineTileManager: ObservableObject {
|
|||
}
|
||||
|
||||
init() {
|
||||
Logger.services.debug("Documents Directory = \(self.documentsDirectory.absoluteString)")
|
||||
Logger.services.debug("Documents Directory = \(self.documentsDirectory.absoluteString, privacy: .public)")
|
||||
createDirectoriesIfNecessary()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ class MeshLogger {
|
|||
} else {
|
||||
try data.write(to: logFile, options: .atomicWrite)
|
||||
let log = String(data: data, encoding: .utf8) ?? "unknown".localized
|
||||
Logger.mesh.notice("\(log)")
|
||||
Logger.mesh.notice("\(log, privacy: .public)")
|
||||
}
|
||||
} catch {
|
||||
Logger.mesh.error("Error writing mesh log data: \(error.localizedDescription)")
|
||||
Logger.mesh.error("Error writing mesh log data: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import Foundation
|
||||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
import SwiftUI
|
||||
import RegexBuilder
|
||||
import OSLog
|
||||
|
|
@ -110,12 +111,12 @@ func myInfoPacket (myInfo: MyNodeInfo, peripheralId: String, context: NSManagedO
|
|||
myInfoEntity.rebootCount = Int32(myInfo.rebootCount)
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Saved a new myInfo for node number: \(String(myInfo.myNodeNum))")
|
||||
Logger.data.info("💾 Saved a new myInfo for node: \(myInfo.myNodeNum.toHex(), privacy: .public)")
|
||||
return myInfoEntity
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Inserting New Core Data MyInfoEntity: \(nsError)")
|
||||
Logger.data.error("💥 Error Inserting New Core Data MyInfoEntity: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
|
||||
|
|
@ -125,16 +126,16 @@ func myInfoPacket (myInfo: MyNodeInfo, peripheralId: String, context: NSManagedO
|
|||
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated myInfo for node number: \(String(myInfo.myNodeNum))")
|
||||
Logger.data.info("💾 Updated myInfo for node: \(myInfo.myNodeNum.toHex(), privacy: .public)")
|
||||
return fetchedMyInfo[0]
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data MyInfoEntity: \(nsError)")
|
||||
Logger.data.error("💥 Error Updating Core Data MyInfoEntity: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Logger.data.error("Fetch MyInfo Error")
|
||||
Logger.data.error("💥 Fetch MyInfo Error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -181,16 +182,16 @@ func channelPacket (channel: Channel, fromNum: Int64, context: NSManagedObjectCo
|
|||
do {
|
||||
try context.save()
|
||||
} catch {
|
||||
Logger.data.error("Failed to save channel: \(error.localizedDescription)")
|
||||
Logger.data.error("💥 Failed to save channel: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
Logger.data.info("💾 Updated MyInfo channel \(channel.index) from Channel App Packet For: \(fetchedMyInfo[0].myNodeNum)")
|
||||
} else if channel.role.rawValue > 0 {
|
||||
Logger.data.error("Trying to save a channel to a MyInfo that does not exist: \(fromNum)")
|
||||
Logger.data.error("💥Trying to save a channel to a MyInfo that does not exist: \(fromNum.toHex(), privacy: .public)")
|
||||
}
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving MyInfo Channel from ADMIN_APP \(nsError)")
|
||||
Logger.data.error("💥 Error Saving MyInfo Channel from ADMIN_APP \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -198,7 +199,7 @@ func channelPacket (channel: Channel, fromNum: Int64, context: NSManagedObjectCo
|
|||
func deviceMetadataPacket (metadata: DeviceMetadata, fromNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
if metadata.isInitialized {
|
||||
let logString = String.localizedStringWithFormat("mesh.log.device.metadata.received %@".localized, String(fromNum))
|
||||
let logString = String.localizedStringWithFormat("mesh.log.device.metadata.received %@".localized, fromNum.toHex())
|
||||
MeshLogger.log("🏷️ \(logString)")
|
||||
|
||||
let fetchedNodeRequest = NodeInfoEntity.fetchRequest()
|
||||
|
|
@ -232,13 +233,13 @@ func deviceMetadataPacket (metadata: DeviceMetadata, fromNum: Int64, context: NS
|
|||
do {
|
||||
try context.save()
|
||||
} catch {
|
||||
Logger.data.error("Failed to save device metadata: \(error.localizedDescription)")
|
||||
Logger.data.error("💥 Failed to save device metadata: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
Logger.data.info("💾 Updated Device Metadata from Admin App Packet For: \(fromNum)")
|
||||
Logger.data.info("💾 Updated Device Metadata from Admin App Packet For: \(fromNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving MyInfo Channel from ADMIN_APP \(nsError)")
|
||||
Logger.data.error("Error Saving MyInfo Channel from ADMIN_APP \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -403,19 +404,19 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
|
|||
}
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 NodeInfo saved for \(nodeInfo.num)")
|
||||
Logger.data.info("💾 [NodeInfo] saved for \(nodeInfo.num.toHex(), privacy: .public)")
|
||||
return fetchedNode[0]
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving Core Data NodeInfoEntity: \(nsError)")
|
||||
Logger.data.error("💥 Error Saving Core Data NodeInfoEntity: \(nsError, privacy: .public)")
|
||||
}
|
||||
} catch {
|
||||
Logger.data.error("Fetch MyInfo Error")
|
||||
Logger.data.error("💥 Fetch MyInfo Error")
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Logger.data.error("Fetch NodeInfoEntity Error")
|
||||
Logger.data.error("💥 Fetch NodeInfoEntity Error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -430,7 +431,7 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
|
|||
|
||||
if !cmmc.messages.isEmpty {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.cannedmessages.messages.received %@".localized, String(packet.from))
|
||||
let logString = String.localizedStringWithFormat("mesh.log.cannedmessages.messages.received %@".localized, packet.from.toHex())
|
||||
MeshLogger.log("🥫 \(logString)")
|
||||
|
||||
let fetchNodeRequest = NodeInfoEntity.fetchRequest()
|
||||
|
|
@ -446,15 +447,15 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
|
|||
fetchedNode[0].cannedMessageConfig?.messages = messages
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Canned Messages Messages For: \(fetchedNode[0].num)")
|
||||
Logger.data.info("💾 Updated Canned Messages Messages For: \(fetchedNode[0].num.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving NodeInfoEntity from POSITION_APP \(nsError)")
|
||||
Logger.data.error("💥 Error Saving NodeInfoEntity from POSITION_APP \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Logger.data.error("Error Deserializing ADMIN_APP packet.")
|
||||
Logger.data.error("💥 Error Deserializing ADMIN_APP packet.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -664,6 +665,7 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
|
|||
telemetry.voltage = telemetryMessage.deviceMetrics.voltage
|
||||
telemetry.uptimeSeconds = Int32(telemetryMessage.deviceMetrics.uptimeSeconds)
|
||||
telemetry.metricsType = 0
|
||||
Logger.statistics.info("📈 [Mesh Statistics] Channel Utilization: \(telemetryMessage.deviceMetrics.channelUtilization) Airtime: \(telemetryMessage.deviceMetrics.airUtilTx) for Node: \(packet.from.toHex())")
|
||||
} else if telemetryMessage.variant == Telemetry.OneOf_Variant.environmentMetrics(telemetryMessage.environmentMetrics) {
|
||||
// Environment Metrics
|
||||
telemetry.barometricPressure = telemetryMessage.environmentMetrics.barometricPressure
|
||||
|
|
@ -689,7 +691,7 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
|
|||
try context.save()
|
||||
// Only log telemetry from the mesh not the connected device
|
||||
if connectedNode != Int64(packet.from) {
|
||||
Logger.data.info("💾 Telemetry Saved for Node: \(packet.from)")
|
||||
Logger.data.info("💾 [Telemetry] Saved for Node: \(packet.from.toHex())")
|
||||
} else if telemetry.metricsType == 0 {
|
||||
// Connected Device Metrics
|
||||
// ------------------------
|
||||
|
|
@ -730,10 +732,10 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
|
|||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving Telemetry for Node \(packet.from) Error: \(nsError)")
|
||||
Logger.data.error("💥 Error Saving Telemetry for Node \(packet.from, privacy: .public) Error: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("Error Fetching NodeInfoEntity for Node \(packet.from)")
|
||||
Logger.data.error("💥 Error Fetching NodeInfoEntity for Node \(packet.from.toHex(), privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,28 +81,28 @@ class MqttClientProxyManager {
|
|||
}
|
||||
}
|
||||
func subscribe(topic: String, qos: CocoaMQTTQoS) {
|
||||
Logger.services.info("📲 MQTT Client Proxy subscribed to: \(topic)")
|
||||
Logger.mqtt.info("📲 [MQTT Client Proxy] subscribed to: \(topic, privacy: .public)")
|
||||
mqttClientProxy?.subscribe(topic, qos: qos)
|
||||
}
|
||||
func unsubscribe(topic: String) {
|
||||
mqttClientProxy?.unsubscribe(topic)
|
||||
Logger.services.info("📲 MQTT Client Proxy unsubscribe for: \(topic)")
|
||||
Logger.mqtt.info("📲 [MQTT Client Proxy] unsubscribe to topic: \(topic, privacy: .public)")
|
||||
}
|
||||
func publish(message: String, topic: String, qos: CocoaMQTTQoS) {
|
||||
mqttClientProxy?.publish(topic, withString: message, qos: qos)
|
||||
Logger.services.debug("📲 MQTT Client Proxy publish for: \(topic)")
|
||||
Logger.mqtt.debug("📲 [MQTT Client Proxy] publish for: \(topic, privacy: .public)")
|
||||
}
|
||||
func disconnect() {
|
||||
if let client = mqttClientProxy {
|
||||
client.disconnect()
|
||||
Logger.services.info("📲 MQTT Client Proxy Disconnected")
|
||||
Logger.mqtt.info("📲 [MQTT Client Proxy] disconnected")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension MqttClientProxyManager: CocoaMQTTDelegate {
|
||||
func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
|
||||
Logger.services.info("📲 MQTT Client Proxy didConnectAck: \(ack)")
|
||||
Logger.mqtt.info("📲 [MQTT Client Proxy] didConnectAck: \(ack, privacy: .public)")
|
||||
if ack == .accept {
|
||||
delegate?.onMqttConnected()
|
||||
} else {
|
||||
|
|
@ -112,7 +112,7 @@ extension MqttClientProxyManager: CocoaMQTTDelegate {
|
|||
case .accept:
|
||||
errorDescription = "No Error"
|
||||
case .unacceptableProtocolVersion:
|
||||
errorDescription = "Proto ver"
|
||||
errorDescription = "Unacceptable Protocol version"
|
||||
case .identifierRejected:
|
||||
errorDescription = "Invalid Id"
|
||||
case .serverUnavailable:
|
||||
|
|
@ -124,40 +124,39 @@ extension MqttClientProxyManager: CocoaMQTTDelegate {
|
|||
default:
|
||||
errorDescription = "Unknown Error"
|
||||
}
|
||||
Logger.services.error("\(errorDescription)")
|
||||
Logger.services.error("📲 [MQTT Client Proxy] \(errorDescription, privacy: .public)")
|
||||
delegate?.onMqttError(message: errorDescription)
|
||||
self.disconnect()
|
||||
}
|
||||
}
|
||||
func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) {
|
||||
Logger.services.debug("mqttDidDisconnect: \(err?.localizedDescription ?? "")")
|
||||
|
||||
Logger.mqtt.debug("📲 [MQTT Client Proxy] disconnected: \(err?.localizedDescription ?? "", privacy: .public)")
|
||||
if let error = err {
|
||||
delegate?.onMqttError(message: error.localizedDescription)
|
||||
}
|
||||
delegate?.onMqttDisconnected()
|
||||
}
|
||||
func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {
|
||||
Logger.services.debug("📲 MQTT Client Proxy didPublishMessage from MqttClientProxyManager: \(message)")
|
||||
Logger.mqtt.info("📲 [MQTT Client Proxy] published messsage from MqttClientProxyManager: \(message, privacy: .public)")
|
||||
}
|
||||
func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {
|
||||
Logger.services.debug("📲 MQTT Client Proxy didPublishAck from MqttClientProxyManager: \(id)")
|
||||
Logger.mqtt.info("📲 [MQTT Client Proxy] published Ack from MqttClientProxyManager: \(id, privacy: .public)")
|
||||
}
|
||||
|
||||
public func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
|
||||
delegate?.onMqttMessageReceived(message: message)
|
||||
Logger.services.debug("📲 MQTT Client Proxy message received on topic: \(message.topic)")
|
||||
Logger.mqtt.info("📲 [MQTT Client Proxy] message received on topic: \(message.topic, privacy: .public)")
|
||||
}
|
||||
func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopics success: NSDictionary, failed: [String]) {
|
||||
Logger.services.info("📲 MQTT Client Proxy didSubscribeTopics: \(success.allKeys.count) topics. failed: \(failed.count) topics")
|
||||
Logger.mqtt.debug("📲 [MQTT Client Proxy] subscribed to topics: \(success.allKeys.count, privacy: .public) topics. failed: \(failed.count, privacy: .public) topics")
|
||||
}
|
||||
func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopics topics: [String]) {
|
||||
Logger.services.info("didUnsubscribeTopics: \(topics.joined(separator: ", "))")
|
||||
Logger.mqtt.debug("📲 [MQTT Client Proxy] unsubscribed from topics: \(topics.joined(separator: "- "), privacy: .public)")
|
||||
}
|
||||
func mqttDidPing(_ mqtt: CocoaMQTT) {
|
||||
Logger.services.info("📲 MQTT Client Proxy mqttDidPing")
|
||||
Logger.mqtt.debug("📲 [MQTT Client Proxy] ping")
|
||||
}
|
||||
func mqttDidReceivePong(_ mqtt: CocoaMQTT) {
|
||||
Logger.services.info("📲 MQTT Client Proxy mqttDidReceivePong")
|
||||
Logger.mqtt.debug("📲 [MQTT Client Proxy] pong")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
//
|
||||
// NetworkManager.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Copyright(c) Garth Vander Houwen on 4/23/23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Network
|
||||
import OSLog
|
||||
|
||||
class NetworkManager {
|
||||
static let shared = NetworkManager()
|
||||
// MARK: Public methods
|
||||
func runIfNetwork(completion: @escaping () -> Void ) {
|
||||
let pathMonitor = NWPathMonitor()
|
||||
pathMonitor.pathUpdateHandler = {
|
||||
guard $0.status == .satisfied else {
|
||||
// No network available
|
||||
Logger.services.info("Network Not available")
|
||||
return pathMonitor.cancel()
|
||||
}
|
||||
pathMonitor.cancel()
|
||||
completion()
|
||||
}
|
||||
pathMonitor.start(queue: DispatchQueue.global(qos: .background))
|
||||
}
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@
|
|||
<key>NSBluetoothAlwaysUsageDescription</key>
|
||||
<string>We use bluetooth to connect to nearby Meshtastic Devices</string>
|
||||
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||
<string>Bluetooth is used to connect an iPhone to a user's meshtastic device to allow text messaging and location data for the mesh network.</string>
|
||||
<string>Bluetooth is used to connect an iPhone to a user's meshtastic device to allow text messaging and location data for the mesh network.</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>We use the camera to share channels using a QR Code</string>
|
||||
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||
|
|
@ -116,7 +116,7 @@
|
|||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportsDocumentBrowser</key>
|
||||
<false/>
|
||||
<true/>
|
||||
<key>UTImportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>_XCCurrentVersionName</key>
|
||||
<string>MeshtasticDataModelV 37.xcdatamodel</string>
|
||||
<string>MeshtasticDataModelV 38.xcdatamodel</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,465 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22758" systemVersion="23F79" 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"/>
|
||||
<attribute name="green" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ledState" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="red" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="ambientLightingConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="ambientLightingConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="BluetoothConfigEntity" representedClassName="BluetoothConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="deviceLoggingEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="fixedPin" optional="YES" attributeType="Integer 32" defaultValueString="123456" usesScalarValueType="YES"/>
|
||||
<attribute name="mode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="bluetoothConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="bluetoothConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="CannedMessageConfigEntity" representedClassName="CannedMessageConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerEventCcw" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerEventCw" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerEventPress" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerPinA" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerPinB" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerPinPress" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
<attribute name="messages" optional="YES" attributeType="String" minValueString="0" maxValueString="198"/>
|
||||
<attribute name="rotary1Enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="sendBell" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="updown1Enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<relationship name="cannedMessagesConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="cannedMessageConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="ChannelEntity" representedClassName="ChannelEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="downlinkEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="id" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="index" attributeType="Integer 32" minValueString="0" maxValueString="13" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="mute" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="name" optional="YES" attributeType="String"/>
|
||||
<attribute name="positionPrecision" optional="YES" attributeType="Integer 32" defaultValueString="32" usesScalarValueType="YES"/>
|
||||
<attribute name="psk" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="role" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="uplinkEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<relationship name="myInfoChannel" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MyInfoEntity" inverseName="channels" inverseEntity="MyInfoEntity"/>
|
||||
<fetchedProperty name="allPrivateMessages" optional="YES">
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="channel == $FETCH_SOURCE.index && toUser == nil AND isEmoji == false"/>
|
||||
</fetchedProperty>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="index"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="DetectionSensorConfigEntity" representedClassName="DetectionSensorConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="detectionTriggeredHigh" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="minimumBroadcastSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="monitorPin" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="name" optional="YES" attributeType="String"/>
|
||||
<attribute name="sendBell" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="stateBroadcastSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="usePullup" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<relationship name="detectionSensorConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="detectionSensorConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="DeviceConfigEntity" representedClassName="DeviceConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="buttonGpio" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="buzzerGpio" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="debugLogEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="disableTripleClick" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="doubleTapAsButtonPress" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="isManaged" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="ledHeartbeatEnabled" optional="YES" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="nodeInfoBroadcastSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="rebroadcastMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="role" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="serialEnabled" optional="YES" attributeType="Boolean" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="tzdef" optional="YES" attributeType="String"/>
|
||||
<relationship name="deviceConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="deviceConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="DeviceMetadataEntity" representedClassName="DeviceMetadataEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="canShutdown" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="deviceStateVersion" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="firmwareVersion" optional="YES" attributeType="String"/>
|
||||
<attribute name="hasBluetooth" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="hasEthernet" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="hasWifi" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="hwModel" optional="YES" attributeType="String"/>
|
||||
<attribute name="positionFlags" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="role" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="metadataNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="metadata" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="DisplayConfigEntity" representedClassName="DisplayConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="compassNorthTop" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="displayMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="flipScreen" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsFormat" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="headingBold" optional="YES" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="oledType" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="screenCarouselInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="screenOnSeconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="units" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="wakeOnTapOrMotion" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<relationship name="displayConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="displayConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="ExternalNotificationConfigEntity" representedClassName="ExternalNotificationConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="active" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertBell" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertBellBuzzer" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertBellVibra" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertMessage" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertMessageBuzzer" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertMessageVibra" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="nagTimeout" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="output" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="outputBuzzer" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="outputMilliseconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="outputVibra" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="useI2SAsBuzzer" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="usePWM" optional="YES" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<relationship name="externalNotificationConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="externalNotificationConfig" inverseEntity="NodeInfoEntity"/>
|
||||
<fetchedProperty name="fetchedProperty" optional="YES">
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="ExternalNotificationConfigEntity"/>
|
||||
</fetchedProperty>
|
||||
</entity>
|
||||
<entity name="LocationEntity" representedClassName="LocationEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="altitude" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="heading" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="id" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
<attribute name="latitudeI" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="longitudeI" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="speed" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="routeLocation" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="RouteEntity" inverseName="locations" inverseEntity="RouteEntity"/>
|
||||
</entity>
|
||||
<entity name="LoRaConfigEntity" representedClassName="LoRaConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="bandwidth" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="channelNum" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="codingRate" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="frequencyOffset" optional="YES" attributeType="Float" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="hopLimit" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ignoreMqtt" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="modemPreset" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="overrideDutyCycle" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="overrideFrequency" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="regionCode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="spreadFactor" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="sx126xRxBoostedGain" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="txEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="txPower" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="usePreset" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<relationship name="loRaConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="loRaConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="MessageEntity" representedClassName="MessageEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="ackError" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ackSNR" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="ackTimestamp" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="admin" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="adminDescription" optional="YES" attributeType="String"/>
|
||||
<attribute name="channel" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="isEmoji" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="messageId" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="messagePayload" optional="YES" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="messagePayloadMarkdown" optional="YES" attributeType="String"/>
|
||||
<attribute name="messageTimestamp" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="portNum" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<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="receivedTimestamp" optional="YES" attributeType="Integer 32" 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"/>
|
||||
<relationship name="fromUser" optional="YES" maxCount="1" deletionRule="Nullify" ordered="YES" destinationEntity="UserEntity" inverseName="sentMessages" inverseEntity="UserEntity"/>
|
||||
<relationship name="toUser" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="UserEntity" inverseName="receivedMessages" inverseEntity="UserEntity"/>
|
||||
<fetchedProperty name="tapbacks" optional="YES">
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="replyID == $FETCH_SOURCE.messageId AND isEmoji == true"/>
|
||||
</fetchedProperty>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="messageId"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="MQTTConfigEntity" representedClassName="MQTTConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="address" optional="YES" attributeType="String" maxValueString="30"/>
|
||||
<attribute name="enabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="encryptionEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="jsonEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="mapPositionPrecision" optional="YES" attributeType="Integer 32" defaultValueString="13" usesScalarValueType="YES"/>
|
||||
<attribute name="mapPublishIntervalSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="mapReportingEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="password" optional="YES" attributeType="String" maxValueString="30"/>
|
||||
<attribute name="proxyToClientEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="root" optional="YES" attributeType="String" defaultValueString="msh"/>
|
||||
<attribute name="tlsEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="username" optional="YES" attributeType="String" maxValueString="30"/>
|
||||
<relationship name="mqttConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="mqttConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="MyInfoEntity" representedClassName="MyInfoEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="adminIndex" optional="YES" attributeType="Integer 32" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="bleName" optional="YES" attributeType="String"/>
|
||||
<attribute name="minAppVersion" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="myNodeNum" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="peripheralId" optional="YES" attributeType="String"/>
|
||||
<attribute name="rebootCount" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="channels" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="ChannelEntity" inverseName="myInfoChannel" inverseEntity="ChannelEntity"/>
|
||||
<relationship name="myInfoNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="myInfo" inverseEntity="NodeInfoEntity"/>
|
||||
<fetchedProperty name="allMessages" optional="YES">
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="toUser == nil"/>
|
||||
</fetchedProperty>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="myNodeNum"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="NetworkConfigEntity" representedClassName="NetworkConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="dns" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ethEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="gateway" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ip" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ntpServer" optional="YES" attributeType="String"/>
|
||||
<attribute name="subnet" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="wifiEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="wifiMode" optional="YES" attributeType="Integer 32" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="wifiPsk" optional="YES" attributeType="String" minValueString="0" maxValueString="60"/>
|
||||
<attribute name="wifiSsid" optional="YES" attributeType="String" minValueString="0" maxValueString="30"/>
|
||||
<relationship name="networkConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="networkConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="NodeInfoEntity" representedClassName="NodeInfoEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="bleName" optional="YES" attributeType="String"/>
|
||||
<attribute name="channel" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="favorite" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="firstHeard" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="hopsAway" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="id" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="lastHeard" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="peripheralId" optional="YES" attributeType="String"/>
|
||||
<attribute name="rssi" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="viaMqtt" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<relationship name="ambientLightingConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="AmbientLightingConfigEntity" inverseName="ambientLightingConfigNode" inverseEntity="AmbientLightingConfigEntity"/>
|
||||
<relationship name="bluetoothConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="BluetoothConfigEntity" inverseName="bluetoothConfigNode" inverseEntity="BluetoothConfigEntity"/>
|
||||
<relationship name="cannedMessageConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="CannedMessageConfigEntity" inverseName="cannedMessagesConfigNode" inverseEntity="CannedMessageConfigEntity"/>
|
||||
<relationship name="detectionSensorConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="DetectionSensorConfigEntity" inverseName="detectionSensorConfigNode" inverseEntity="DetectionSensorConfigEntity"/>
|
||||
<relationship name="deviceConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="DeviceConfigEntity" inverseName="deviceConfigNode" inverseEntity="DeviceConfigEntity"/>
|
||||
<relationship name="displayConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="DisplayConfigEntity" inverseName="displayConfigNode" inverseEntity="DisplayConfigEntity"/>
|
||||
<relationship name="externalNotificationConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="ExternalNotificationConfigEntity" inverseName="externalNotificationConfigNode" inverseEntity="ExternalNotificationConfigEntity"/>
|
||||
<relationship name="loRaConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="LoRaConfigEntity" inverseName="loRaConfigNode" inverseEntity="LoRaConfigEntity"/>
|
||||
<relationship name="metadata" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DeviceMetadataEntity" inverseName="metadataNode" inverseEntity="DeviceMetadataEntity"/>
|
||||
<relationship name="mqttConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MQTTConfigEntity" inverseName="mqttConfigNode" inverseEntity="MQTTConfigEntity"/>
|
||||
<relationship name="myInfo" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MyInfoEntity" inverseName="myInfoNode" inverseEntity="MyInfoEntity"/>
|
||||
<relationship name="networkConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NetworkConfigEntity" inverseName="networkConfigNode" inverseEntity="NetworkConfigEntity"/>
|
||||
<relationship name="pax" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PaxCounterEntity" inverseName="paxNode" inverseEntity="PaxCounterEntity"/>
|
||||
<relationship name="paxCounterConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PaxCounterConfigEntity" inverseName="paxCounterConfigNode" inverseEntity="PaxCounterConfigEntity"/>
|
||||
<relationship name="positionConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PositionConfigEntity" inverseName="positionConfigNode" inverseEntity="PositionConfigEntity"/>
|
||||
<relationship name="positions" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PositionEntity" inverseName="nodePosition" inverseEntity="PositionEntity"/>
|
||||
<relationship name="powerConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PowerConfigEntity" inverseName="powerConfigNode" inverseEntity="PowerConfigEntity"/>
|
||||
<relationship name="rangeTestConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="RangeTestConfigEntity" inverseName="rangeTestConfigNode" inverseEntity="RangeTestConfigEntity"/>
|
||||
<relationship name="rtttlConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="RTTTLConfigEntity" inverseName="rtttlConfigNode" inverseEntity="RTTTLConfigEntity"/>
|
||||
<relationship name="serialConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="SerialConfigEntity" inverseName="serialConfigNode" inverseEntity="SerialConfigEntity"/>
|
||||
<relationship name="storeForwardConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="StoreForwardConfigEntity" inverseName="storeForwardConfigNode" inverseEntity="StoreForwardConfigEntity"/>
|
||||
<relationship name="telemetries" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TelemetryEntity" inverseName="nodeTelemetry" inverseEntity="TelemetryEntity"/>
|
||||
<relationship name="telemetryConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TelemetryConfigEntity" inverseName="telemetryConfigNode" inverseEntity="TelemetryConfigEntity"/>
|
||||
<relationship name="traceRoutes" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TraceRouteEntity" inverseName="node" inverseEntity="TraceRouteEntity"/>
|
||||
<relationship name="user" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="UserEntity" inverseName="userNode" inverseEntity="UserEntity"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="num"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="PaxCounterConfigEntity" representedClassName="PaxCounterConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="bleThreshold" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="updateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="wifiThreshold" optional="YES" attributeType="Integer 32" defaultValueString="-80" usesScalarValueType="YES"/>
|
||||
<relationship name="paxCounterConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="paxCounterConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="PaxCounterEntity" representedClassName="PaxCounterEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="ble" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="uptime" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="wifi" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="paxNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="pax" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="PositionConfigEntity" representedClassName="PositionConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="broadcastSmartMinimumDistance" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="broadcastSmartMinimumIntervalSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="deviceGpsEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="fixedPosition" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsAttemptTime" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsEnGpio" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="positionBroadcastSeconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="positionFlags" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="rxGpio" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="smartPositionEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="txGpio" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="positionConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="positionConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="PositionEntity" representedClassName="PositionEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="altitude" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="heading" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="latest" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="latitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="longitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="precisionBits" optional="YES" attributeType="Integer 32" defaultValueString="32" usesScalarValueType="YES"/>
|
||||
<attribute name="rssi" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="satsInView" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="seqNo" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="speed" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="nodePosition" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="positions" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="PowerConfigEntity" representedClassName="PowerConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="adcMultiplierOverride" optional="YES" attributeType="Float" usesScalarValueType="YES"/>
|
||||
<attribute name="deviceBatteryInaAddress" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="isPowerSaving" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="lsSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="minWakeSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="onBatteryShutdownAfterSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="waitBluetoothSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="powerConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="powerConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="RangeTestConfigEntity" representedClassName="RangeTestConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="save" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="sender" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
<relationship name="rangeTestConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="rangeTestConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="RouteEntity" representedClassName="RouteEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="color" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="distance" optional="YES" attributeType="Double" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="elevationGain" optional="YES" attributeType="Double" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="endDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="id" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="name" optional="YES" attributeType="String"/>
|
||||
<attribute name="notes" optional="YES" attributeType="String"/>
|
||||
<relationship name="locations" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="LocationEntity" inverseName="routeLocation" inverseEntity="LocationEntity"/>
|
||||
</entity>
|
||||
<entity name="RTTTLConfigEntity" representedClassName="RTTTLConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="ringtone" optional="YES" attributeType="String" maxValueString="228" defaultValueString=""/>
|
||||
<relationship name="rtttlConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="rtttlConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="SerialConfigEntity" representedClassName="SerialConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="baudRate" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="echo" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="mode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="overrideConsoleSerialPort" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="rxd" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="timeout" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="txd" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="serialConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="serialConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="StoreForwardConfigEntity" representedClassName="StoreForwardConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="enabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="heartbeat" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="historyReturnMax" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="historyReturnWindow" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="isRouter" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="lastHeartbeat" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="lastRequest" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="records" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="storeForwardConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="storeForwardConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="TelemetryConfigEntity" representedClassName="TelemetryConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="deviceUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentDisplayFahrenheit" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentMeasurementEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentScreenEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="powerMeasurementEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="powerScreenEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="powerUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="telemetryConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="telemetryConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="TelemetryEntity" representedClassName="TelemetryEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="airUtilTx" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="barometricPressure" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="batteryLevel" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="channelUtilization" optional="YES" attributeType="Float" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="current" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="gasResistance" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="iaq" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="metricsType" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="relativeHumidity" optional="YES" attributeType="Float" defaultValueString="0.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"/>
|
||||
<attribute name="temperature" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="uptimeSeconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="voltage" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<relationship name="nodeTelemetry" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="telemetries" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="TraceRouteEntity" representedClassName="TraceRouteEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="altitude" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="hasPositions" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="id" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="latitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="longitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="num" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="response" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="route" optional="YES" attributeType="Transformable" customClassName="[UInt32]"/>
|
||||
<attribute name="routeText" optional="YES" attributeType="String"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="hops" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TraceRouteHopEntity" inverseName="traceRoute" inverseEntity="TraceRouteHopEntity"/>
|
||||
<relationship name="node" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="traceRoutes" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="TraceRouteHopEntity" representedClassName="TraceRouteHopEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="altitude" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="latitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="longitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="name" optional="YES" attributeType="String"/>
|
||||
<attribute name="num" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="traceRoute" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TraceRouteEntity" inverseName="hops" inverseEntity="TraceRouteEntity"/>
|
||||
</entity>
|
||||
<entity name="UserEntity" representedClassName="UserEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="hwModel" attributeType="String"/>
|
||||
<attribute name="isLicensed" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="lastMessage" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="longName" attributeType="String"/>
|
||||
<attribute name="mute" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="numString" optional="YES" attributeType="String"/>
|
||||
<attribute name="role" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="shortName" attributeType="String"/>
|
||||
<attribute name="userId" attributeType="String"/>
|
||||
<relationship name="receivedMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="toUser" inverseEntity="MessageEntity"/>
|
||||
<relationship name="sentMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="fromUser" inverseEntity="MessageEntity"/>
|
||||
<relationship name="userNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="user" inverseEntity="NodeInfoEntity"/>
|
||||
<fetchedProperty name="adminMessages" optional="YES">
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="(fromUser.num == $FETCH_SOURCE.num) AND isEmoji == false AND admin = true"/>
|
||||
</fetchedProperty>
|
||||
<fetchedProperty name="allMessages" optional="YES">
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="((toUser.num == $FETCH_SOURCE.num) OR (fromUser.num == $FETCH_SOURCE.num)) AND toUser != nil AND fromUser != nil AND isEmoji == false AND admin = false AND portNum != 10 "/>
|
||||
</fetchedProperty>
|
||||
<fetchedProperty name="detectionSensorMessages" optional="YES">
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="(fromUser.num == $FETCH_SOURCE.num) AND portNum = 10"/>
|
||||
</fetchedProperty>
|
||||
</entity>
|
||||
<entity name="WaypointEntity" representedClassName="WaypointEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="created" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="expire" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="icon" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="id" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="lastUpdated" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="latitudeI" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="locked" attributeType="Integer 64" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="longDescription" optional="YES" attributeType="String" maxValueString="100"/>
|
||||
<attribute name="longitudeI" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="name" attributeType="String" minValueString="1" maxValueString="30"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="id"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
</model>
|
||||
|
|
@ -140,22 +140,22 @@ struct MeshtasticAppleApp: App {
|
|||
.onChange(of: scenePhase) { (newScenePhase) in
|
||||
switch newScenePhase {
|
||||
case .background:
|
||||
Logger.services.info("🍏 Scene is in the background")
|
||||
Logger.services.info("🎬 [App] Scene is in the background")
|
||||
do {
|
||||
|
||||
try persistenceController.container.viewContext.save()
|
||||
Logger.services.info("💾 Saved CoreData ViewContext when the app went to the background.")
|
||||
Logger.services.info("💾 [App] Saved CoreData ViewContext when the app went to the background.")
|
||||
|
||||
} catch {
|
||||
|
||||
Logger.services.error("💥 Failed to save viewContext when the app goes to the background.")
|
||||
Logger.services.error("💥 [App] Failed to save viewContext when the app goes to the background.")
|
||||
}
|
||||
case .inactive:
|
||||
Logger.services.info("🍏 Scene is inactive")
|
||||
Logger.services.info("🎬 [App] Scene is inactive")
|
||||
case .active:
|
||||
Logger.services.info("🍏 Scene is active")
|
||||
Logger.services.info("🎬 [App] Scene is active")
|
||||
@unknown default:
|
||||
Logger.services.error("🍎 Apple must have changed something")
|
||||
Logger.services.error("🍎 [App] Apple must have changed something")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import OSLog
|
|||
|
||||
class MeshtasticAppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, ObservableObject {
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
||||
Logger.services.info("🚀 Meshtstic Apple App launched!")
|
||||
Logger.services.info("🚀 [App] Meshtstic Apple App launched!")
|
||||
// Default User Default Values
|
||||
UserDefaults.standard.register(defaults: ["meshMapRecentering": true])
|
||||
UserDefaults.standard.register(defaults: ["meshMapShowNodeHistory": true])
|
||||
|
|
|
|||
|
|
@ -89,3 +89,170 @@ extension NSManagedObjectContext {
|
|||
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [self])
|
||||
}
|
||||
}
|
||||
|
||||
// Created by Tom Harrington on 5/12/20.
|
||||
// Copyright © 2020 Atomic Bird LLC. All rights reserved.
|
||||
// Gist from https://atomicbird.com/blog/core-data-back-up-store/
|
||||
//
|
||||
extension NSPersistentContainer {
|
||||
enum CopyPersistentStoreErrors: Error {
|
||||
case invalidDestination(String)
|
||||
case destinationError(String)
|
||||
case destinationNotRemoved(String)
|
||||
case copyStoreError(String)
|
||||
case invalidSource(String)
|
||||
}
|
||||
|
||||
/// Restore a persistent store for a URL `backupURL`.
|
||||
/// **Be very careful with this**. To restore a persistent store, the current persistent store must be removed from the container. When that happens, **all currently loaded Core Data objects** will become invalid. Using them after restoring will cause your app to crash. When calling this method you **must** ensure that you do not continue to use any previously fetched managed objects or existing fetched results controllers. **If this method does not throw, that does not mean your app is safe.** You need to take extra steps to prevent crashes. The details vary depending on the nature of your app.
|
||||
/// - Parameter backupURL: A file URL containing backup copies of all currently loaded persistent stores.
|
||||
/// - Throws: `CopyPersistentStoreError` in various situations.
|
||||
/// - Returns: Nothing. If no errors are thrown, the restore is complete.
|
||||
// func restorePersistentStore(from backupURL: URL) throws -> Void {
|
||||
// guard backupURL.isFileURL else {
|
||||
// throw CopyPersistentStoreErrors.invalidSource("Backup URL must be a file URL")
|
||||
// }
|
||||
//
|
||||
// for persistentStoreDescription in persistentStoreDescriptions {
|
||||
// guard let loadedStoreURL = persistentStoreDescription.url else {
|
||||
// continue
|
||||
// }
|
||||
// guard FileManager.default.fileExists(atPath: backupURL.path) else {
|
||||
// throw CopyPersistentStoreErrors.invalidSource("Missing backup store for \(backupURL)")
|
||||
// }
|
||||
// do {
|
||||
// let storeOptions = persistentStoreDescription.options
|
||||
// let configurationName = persistentStoreDescription.configuration
|
||||
// let storeType = persistentStoreDescription.type
|
||||
//
|
||||
// // Replace the current store with the backup copy. This has a side effect of removing the current store from the Core Data stack.
|
||||
// // When restoring, it's necessary to use the current persistent store coordinator.
|
||||
// try persistentStoreCoordinator.replacePersistentStore(at: loadedStoreURL, destinationOptions: storeOptions, withPersistentStoreFrom: backupURL, sourceOptions: storeOptions, ofType: storeType)
|
||||
// // Add the persistent store at the same location we've been using, because it was removed in the previous step.
|
||||
// try persistentStoreCoordinator.addPersistentStore(ofType: storeType, configurationName: configurationName, at: loadedStoreURL, options: storeOptions)
|
||||
// } catch {
|
||||
// throw CopyPersistentStoreErrors.copyStoreError("Could not restore: \(error.localizedDescription)")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
/// Restore backup persistent stores located in the directory referenced by `backupURL`.
|
||||
///
|
||||
/// **Be very careful with this**. To restore a persistent store, the current persistent store must be removed from the container. When that happens, **all currently loaded Core Data objects** will become invalid. Using them after restoring will cause your app to crash. When calling this method you **must** ensure that you do not continue to use any previously fetched managed objects or existing fetched results controllers. **If this method does not throw, that does not mean your app is safe.** You need to take extra steps to prevent crashes. The details vary depending on the nature of your app.
|
||||
/// - Parameter backupURL: A file URL containing backup copies of all currently loaded persistent stores.
|
||||
/// - Throws: `CopyPersistentStoreError` in various situations.
|
||||
/// - Returns: Nothing. If no errors are thrown, the restore is complete.
|
||||
func restorePersistentStore(from backupURL: URL) throws -> Void {
|
||||
guard backupURL.isFileURL else {
|
||||
throw CopyPersistentStoreErrors.invalidSource("Backup URL must be a file URL")
|
||||
}
|
||||
|
||||
var isDirectory: ObjCBool = false
|
||||
if FileManager.default.fileExists(atPath: backupURL.path, isDirectory: &isDirectory) {
|
||||
if !isDirectory.boolValue {
|
||||
throw CopyPersistentStoreErrors.invalidSource("Source URL must be a directory")
|
||||
}
|
||||
} else {
|
||||
throw CopyPersistentStoreErrors.invalidSource("Source URL must exist")
|
||||
}
|
||||
|
||||
for persistentStoreDescription in persistentStoreDescriptions {
|
||||
guard let loadedStoreURL = persistentStoreDescription.url else {
|
||||
continue
|
||||
}
|
||||
let backupStoreURL = backupURL.appendingPathComponent(loadedStoreURL.lastPathComponent)
|
||||
guard FileManager.default.fileExists(atPath: backupStoreURL.path) else {
|
||||
throw CopyPersistentStoreErrors.invalidSource("Missing backup store for \(backupStoreURL)")
|
||||
}
|
||||
do {
|
||||
let storeOptions = persistentStoreDescription.options
|
||||
let configurationName = persistentStoreDescription.configuration
|
||||
let storeType = persistentStoreDescription.type
|
||||
// Replace the current store with the backup copy. This has a side effect of removing the current store from the Core Data stack.
|
||||
// When restoring, it's necessary to use the current persistent store coordinator.
|
||||
try persistentStoreCoordinator.replacePersistentStore(at: loadedStoreURL, destinationOptions: storeOptions, withPersistentStoreFrom: backupStoreURL, sourceOptions: storeOptions, ofType: storeType)
|
||||
// Add the persistent store at the same location we've been using, because it was removed in the previous step.
|
||||
try persistentStoreCoordinator.addPersistentStore(ofType: storeType, configurationName: configurationName, at: loadedStoreURL, options: storeOptions)
|
||||
} catch {
|
||||
throw CopyPersistentStoreErrors.copyStoreError("Could not restore: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy all loaded persistent stores to a new directory. Each currently loaded file-based persistent store will be copied (including journal files, external binary storage, and anything else Core Data needs) into the destination directory to a persistent store with the same name and type as the existing store. In-memory stores, if any, are skipped.
|
||||
/// - Parameters:
|
||||
/// - destinationURL: Destination for new persistent store files. Must be a file URL. If `overwriting` is `false` and `destinationURL` exists, it must be a directory.
|
||||
/// - overwriting: If `true`, any existing copies of the persistent store will be replaced or updated. If `false`, existing copies will not be changed or remoted. When this is `false`, the destination persistent store file must not already exist.
|
||||
/// - Throws: `CopyPersistentStoreError`
|
||||
/// - Returns: Nothing. If no errors are thrown, all loaded persistent stores will be copied to the destination directory.
|
||||
func copyPersistentStores(to destinationURL: URL, overwriting: Bool = false) throws -> Void {
|
||||
|
||||
guard !destinationURL.relativeString.contains("/0/") else {
|
||||
throw CopyPersistentStoreErrors.invalidDestination("Invalid 0 Node Id")
|
||||
}
|
||||
|
||||
guard destinationURL.isFileURL else {
|
||||
throw CopyPersistentStoreErrors.invalidDestination("Destination URL must be a file URL")
|
||||
}
|
||||
// If the destination exists and we aren't overwriting it, then it must be a directory. (If we are overwriting, we'll remove it anyway, so it doesn't matter whether it's a directory).
|
||||
var isDirectory: ObjCBool = false
|
||||
if !overwriting && FileManager.default.fileExists(atPath: destinationURL.path, isDirectory: &isDirectory) {
|
||||
if !isDirectory.boolValue {
|
||||
throw CopyPersistentStoreErrors.invalidDestination("Destination URL must be a directory")
|
||||
}
|
||||
// Don't check if destination stores exist in the destination dir, that comes later on a per-store basis.
|
||||
}
|
||||
// If we're overwriting, remove the destination.
|
||||
if overwriting && FileManager.default.fileExists(atPath: destinationURL.path) {
|
||||
do {
|
||||
try FileManager.default.removeItem(at: destinationURL)
|
||||
} catch {
|
||||
throw CopyPersistentStoreErrors.destinationNotRemoved("Can't overwrite destination at \(destinationURL)")
|
||||
}
|
||||
}
|
||||
// Create the destination directory
|
||||
do {
|
||||
try FileManager.default.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil)
|
||||
} catch {
|
||||
throw CopyPersistentStoreErrors.destinationError("Could not create destination directory at \(destinationURL)")
|
||||
}
|
||||
|
||||
for persistentStoreDescription in persistentStoreDescriptions {
|
||||
guard let storeURL = persistentStoreDescription.url else {
|
||||
continue
|
||||
}
|
||||
guard persistentStoreDescription.type != NSInMemoryStoreType else {
|
||||
continue
|
||||
}
|
||||
let destinationStoreURL = destinationURL.appendingPathComponent(storeURL.lastPathComponent)
|
||||
|
||||
if !overwriting && FileManager.default.fileExists(atPath: destinationStoreURL.path) {
|
||||
// If the destination exists, the replacePersistentStore call will update it in place. That's fine unless we're not overwriting.
|
||||
throw CopyPersistentStoreErrors.destinationError("Destination already exists at \(destinationStoreURL)")
|
||||
}
|
||||
do {
|
||||
// Replace an existing backup, if any, with a new one with the same options and type. This doesn't affect the current Core Data stack.
|
||||
// The function name says "replace", but it works if there's nothing at the destination yet. In that case it creates a new persistent store.
|
||||
// Note that for backup, it doesn't matter if the persistent store coordinator is the one currently in use or a different one. It could be a class function, for this use.
|
||||
try persistentStoreCoordinator.replacePersistentStore(at: destinationStoreURL, destinationOptions: persistentStoreDescription.options, withPersistentStoreFrom: storeURL, sourceOptions: persistentStoreDescription.options, ofType: persistentStoreDescription.type)
|
||||
/// Cleanup extra files
|
||||
let directory = destinationStoreURL.deletingLastPathComponent()
|
||||
/// Delete -wal file
|
||||
do {
|
||||
try FileManager.default.removeItem(at: directory.appendingPathComponent("Meshtastic.sqlite-wal"))
|
||||
/// Delete -shm file
|
||||
do {
|
||||
try FileManager.default.removeItem(at: directory.appendingPathComponent("Meshtastic.sqlite-shm"))
|
||||
} catch {
|
||||
Logger.services.error("Error Deleting Meshtastic.sqlite-shm file \(error, privacy: .public)")
|
||||
}
|
||||
} catch {
|
||||
Logger.services.error("Error Deleting Meshtastic.sqlite-wal file \(error, privacy: .public)")
|
||||
}
|
||||
} catch {
|
||||
Logger.services.error("Error Deleting Meshtastic.sqlite file \(error, privacy: .public)")
|
||||
throw CopyPersistentStoreErrors.copyStoreError("\(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
// Copyright(c) Garth Vander Houwen 10/3/22.
|
||||
|
||||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
|
||||
public func clearPax(destNum: Int64, context: NSManagedObjectContext) -> Bool {
|
||||
|
|
@ -25,7 +26,7 @@ public func clearPax(destNum: Int64, context: NSManagedObjectContext) -> Bool {
|
|||
return false
|
||||
}
|
||||
} catch {
|
||||
Logger.data.error("Fetch NodeInfoEntity Error")
|
||||
Logger.data.error("💥 [NodeInfoEntity] fetch data error")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +49,7 @@ public func clearPositions(destNum: Int64, context: NSManagedObjectContext) -> B
|
|||
return false
|
||||
}
|
||||
} catch {
|
||||
Logger.data.error("Fetch NodeInfoEntity Error")
|
||||
Logger.data.error("💥 [NodeInfoEntity] fetch data error")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -71,7 +72,7 @@ public func clearTelemetry(destNum: Int64, metricsType: Int32, context: NSManage
|
|||
return false
|
||||
}
|
||||
} catch {
|
||||
Logger.data.error("Fetch NodeInfoEntity Error")
|
||||
Logger.data.error("💥 [NodeInfoEntity] fetch data error")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -128,7 +129,7 @@ public func clearCoreDataDatabase(context: NSManagedObjectContext, includeRoutes
|
|||
|
||||
func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.nodeinfo.received %@".localized, String(packet.from))
|
||||
let logString = String.localizedStringWithFormat("mesh.log.nodeinfo.received %@".localized, packet.from.toHex())
|
||||
MeshLogger.log("📟 \(logString)")
|
||||
|
||||
guard packet.from > 0 else { return }
|
||||
|
|
@ -194,7 +195,7 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
|
|||
} else {
|
||||
if packet.from > Int16.max {
|
||||
let newUser = createUser(num: Int64(packet.from), context: context)
|
||||
fetchedNode[0].user = newUser
|
||||
newNode.user = newUser
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -207,11 +208,11 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
|
|||
myInfoEntity.rebootCount = 0
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Saved a new myInfo for node number: \(String(packet.from))")
|
||||
Logger.data.info("💾 [MyInfoEntity] Saved a new myInfo for node number: \(packet.from.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Inserting New Core Data MyInfoEntity: \(nsError)")
|
||||
Logger.data.error("💥 [MyInfoEntity] Error Inserting New Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
newNode.myInfo = myInfoEntity
|
||||
|
||||
|
|
@ -264,15 +265,15 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
|
|||
}
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated NodeInfo from Node Info App Packet For: \(fetchedNode[0].num)")
|
||||
Logger.data.info("💾 [NodeInfoEntity] Updated from Node Info App Packet For: \(fetchedNode[0].num.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving NodeInfoEntity from NODEINFO_APP \(nsError)")
|
||||
Logger.data.error("💥 [NodeInfoEntity] Error Saving from NODEINFO_APP \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Logger.data.error("Error Fetching NodeInfoEntity for NODEINFO_APP")
|
||||
Logger.data.error("💥 [NodeInfoEntity] fetch data error for NODEINFO_APP")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -352,11 +353,11 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
|
|||
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Node Position Coordinates, SNR and Time from Position App Packet For: \(fetchedNode[0].num)")
|
||||
Logger.data.info("💾 Updated Node Position Coordinates from Position App Packet For: \(fetchedNode[0].num.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving NodeInfoEntity from POSITION_APP \(nsError)")
|
||||
Logger.data.error("💥 Error Saving NodeInfoEntity from POSITION_APP \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -364,16 +365,16 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
|
|||
if (try? NodeInfo(serializedData: packet.decoded.payload)) != nil {
|
||||
upsertNodeInfoPacket(packet: packet, context: context)
|
||||
} else {
|
||||
Logger.data.error("Empty POSITION_APP Packet: \((try? packet.jsonString()) ?? "JSON Decode Failure")")
|
||||
Logger.data.error("💥 Empty POSITION_APP Packet: \((try? packet.jsonString()) ?? "JSON Decode Failure", privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Logger.data.error("Error Deserializing POSITION_APP packet.")
|
||||
Logger.data.error("💥 Error Deserializing POSITION_APP packet.")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertBluetoothConfigPacket(config: Meshtastic.Config.BluetoothConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertBluetoothConfigPacket(config: Config.BluetoothConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.bluetooth.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("📶 \(logString)")
|
||||
|
|
@ -390,30 +391,32 @@ func upsertBluetoothConfigPacket(config: Meshtastic.Config.BluetoothConfig, node
|
|||
newBluetoothConfig.enabled = config.enabled
|
||||
newBluetoothConfig.mode = Int32(config.mode.rawValue)
|
||||
newBluetoothConfig.fixedPin = Int32(config.fixedPin)
|
||||
newBluetoothConfig.deviceLoggingEnabled = config.deviceLoggingEnabled
|
||||
fetchedNode[0].bluetoothConfig = newBluetoothConfig
|
||||
} else {
|
||||
fetchedNode[0].bluetoothConfig?.enabled = config.enabled
|
||||
fetchedNode[0].bluetoothConfig?.mode = Int32(config.mode.rawValue)
|
||||
fetchedNode[0].bluetoothConfig?.fixedPin = Int32(config.fixedPin)
|
||||
fetchedNode[0].bluetoothConfig?.deviceLoggingEnabled = config.deviceLoggingEnabled
|
||||
}
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Bluetooth Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [BluetoothConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data BluetoothConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [BluetoothConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Bluetooth Config")
|
||||
Logger.data.error("💥 [BluetoothConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Bluetooth Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data BluetoothConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [BluetoothConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertDeviceConfigPacket(config: Meshtastic.Config.DeviceConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertDeviceConfigPacket(config: Config.DeviceConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.device.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("📟 \(logString)")
|
||||
|
|
@ -453,22 +456,22 @@ func upsertDeviceConfigPacket(config: Meshtastic.Config.DeviceConfig, nodeNum: I
|
|||
}
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Device Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [DeviceConfigEntity] Updated Device Config for node number: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data DeviceConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [DeviceConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data DeviceConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [DeviceConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertDisplayConfigPacket(config: Meshtastic.Config.DisplayConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertDisplayConfigPacket(config: Config.DisplayConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.display.config %@".localized, String(nodeNum))
|
||||
let logString = String.localizedStringWithFormat("mesh.log.display.config %@".localized, nodeNum.toHex())
|
||||
MeshLogger.log("🖥️ \(logString)")
|
||||
|
||||
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
|
||||
|
|
@ -509,30 +512,30 @@ func upsertDisplayConfigPacket(config: Meshtastic.Config.DisplayConfig, nodeNum:
|
|||
do {
|
||||
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Display Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [DisplayConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
|
||||
} catch {
|
||||
|
||||
context.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data DisplayConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [DisplayConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Display Config")
|
||||
Logger.data.error("💥 [DisplayConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex()) unable to save Display Config")
|
||||
}
|
||||
|
||||
} catch {
|
||||
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data DisplayConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [DisplayConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertLoRaConfigPacket(config: Meshtastic.Config.LoRaConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertLoRaConfigPacket(config: Config.LoRaConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.lora.config %@".localized, String(nodeNum))
|
||||
let logString = String.localizedStringWithFormat("mesh.log.lora.config %@".localized, nodeNum.toHex())
|
||||
MeshLogger.log("📻 \(logString)")
|
||||
|
||||
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
|
||||
|
|
@ -580,22 +583,22 @@ func upsertLoRaConfigPacket(config: Meshtastic.Config.LoRaConfig, nodeNum: Int64
|
|||
}
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated LoRa Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [LoRaConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data LoRaConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [LoRaConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Lora Config")
|
||||
Logger.data.error("💥 [LoRaConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Lora Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data LoRaConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [LoRaConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertNetworkConfigPacket(config: Meshtastic.Config.NetworkConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertNetworkConfigPacket(config: Config.NetworkConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.network.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("🌐 \(logString)")
|
||||
|
|
@ -623,23 +626,23 @@ func upsertNetworkConfigPacket(config: Meshtastic.Config.NetworkConfig, nodeNum:
|
|||
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Network Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [NetworkConfigEntity] Updated Network Config for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data WiFiConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [NetworkConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Network Config")
|
||||
Logger.data.error("💥 [NetworkConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Network Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data NetworkConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [NetworkConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertPositionConfigPacket(config: Meshtastic.Config.PositionConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertPositionConfigPacket(config: Config.PositionConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.position.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("🗺️ \(logString)")
|
||||
|
|
@ -684,22 +687,22 @@ func upsertPositionConfigPacket(config: Meshtastic.Config.PositionConfig, nodeNu
|
|||
}
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Position Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [PositionConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data PositionConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [PositionConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Position Config")
|
||||
Logger.data.error("💥 [PositionConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Position Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data PositionConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [PositionConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertPowerConfigPacket(config: Meshtastic.Config.PowerConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertPowerConfigPacket(config: Config.PowerConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
let logString = String.localizedStringWithFormat("mesh.log.power.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("🗺️ \(logString)")
|
||||
|
||||
|
|
@ -731,22 +734,22 @@ func upsertPowerConfigPacket(config: Meshtastic.Config.PowerConfig, nodeNum: Int
|
|||
}
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Power Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [PowerConfigEntity] Updated Power Config for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data PowerConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [PowerConfigEntity] Error Updating Core Data PowerConfigEntity: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Power Config")
|
||||
Logger.data.error("💥 [PowerConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Power Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data PowerConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [PowerConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertAmbientLightingModuleConfigPacket(config: Meshtastic.ModuleConfig.AmbientLightingConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertAmbientLightingModuleConfigPacket(config: ModuleConfig.AmbientLightingConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.ambientlighting.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("🏮 \(logString)")
|
||||
|
|
@ -784,22 +787,22 @@ func upsertAmbientLightingModuleConfigPacket(config: Meshtastic.ModuleConfig.Amb
|
|||
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Ambient Lighting Module Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [AmbientLightingConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data AmbientLightingConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [AmbientLightingConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Ambient Lighting Module Config")
|
||||
Logger.data.error("💥 [AmbientLightingConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Ambient Lighting Module Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data AmbientLightingConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [AmbientLightingConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertCannedMessagesModuleConfigPacket(config: Meshtastic.ModuleConfig.CannedMessageConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertCannedMessagesModuleConfigPacket(config: ModuleConfig.CannedMessageConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.cannedmessage.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("🥫 \(logString)")
|
||||
|
|
@ -845,22 +848,22 @@ func upsertCannedMessagesModuleConfigPacket(config: Meshtastic.ModuleConfig.Cann
|
|||
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Canned Message Module Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [CannedMessageConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data CannedMessageConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [CannedMessageConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Canned Message Module Config")
|
||||
Logger.data.error("💥 [CannedMessageConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Canned Message Module Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data CannedMessageConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [CannedMessageConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertDetectionSensorModuleConfigPacket(config: Meshtastic.ModuleConfig.DetectionSensorConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertDetectionSensorModuleConfigPacket(config: ModuleConfig.DetectionSensorConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.detectionsensor.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("🕵️ \(logString)")
|
||||
|
|
@ -900,25 +903,25 @@ func upsertDetectionSensorModuleConfigPacket(config: Meshtastic.ModuleConfig.Det
|
|||
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Detection Sensor Module Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [DetectionSensorConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data DetectionSensorConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [DetectionSensorConfigEntity] Error Updating Core Data : \(nsError, privacy: .public)")
|
||||
}
|
||||
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Detection Sensor Module Config")
|
||||
Logger.data.error("💥 [DetectionSensorConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Detection Sensor Module Config")
|
||||
}
|
||||
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data DetectionSensorConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [DetectionSensorConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertExternalNotificationModuleConfigPacket(config: Meshtastic.ModuleConfig.ExternalNotificationConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertExternalNotificationModuleConfigPacket(config: ModuleConfig.ExternalNotificationConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.externalnotification.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("📣 \(logString)")
|
||||
|
|
@ -970,22 +973,22 @@ func upsertExternalNotificationModuleConfigPacket(config: Meshtastic.ModuleConfi
|
|||
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated External Notification Module Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [ExternalNotificationConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data ExternalNotificationConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [ExternalNotificationConfigEntity] Error Updating Core Data : \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save External Notification Module Config")
|
||||
Logger.data.error("💥 [ExternalNotificationConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save External Notification Module Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data ExternalNotificationConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [ExternalNotificationConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertPaxCounterModuleConfigPacket(config: Meshtastic.ModuleConfig.PaxcounterConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertPaxCounterModuleConfigPacket(config: ModuleConfig.PaxcounterConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.paxcounter.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("🧑🤝🧑 \(logString)")
|
||||
|
|
@ -1012,18 +1015,18 @@ func upsertPaxCounterModuleConfigPacket(config: Meshtastic.ModuleConfig.Paxcount
|
|||
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated PAX Counter Module Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [PaxCounterConfigEntity] Updated for node number: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data ExternalNotificationConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [PaxCounterConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save PAX Counter Module Config")
|
||||
Logger.data.error("💥 [PaxCounterConfigEntity] No Nodes found in local database matching node number \(nodeNum.toHex(), privacy: .public) unable to save PAX Counter Module Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data PaxCounterConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [PaxCounterConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1048,22 +1051,22 @@ func upsertRtttlConfigPacket(ringtone: String, nodeNum: Int64, context: NSManage
|
|||
}
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated RTTTL Ringtone Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [RtttlConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data RtttlConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [RtttlConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save RTTTL Ringtone Config")
|
||||
Logger.data.error("💥 [RtttlConfigEntity] No nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save RTTTL Ringtone Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data RtttlConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [RtttlConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertMqttModuleConfigPacket(config: Meshtastic.ModuleConfig.MQTTConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertMqttModuleConfigPacket(config: ModuleConfig.MQTTConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.mqtt.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("🌉 \(logString)")
|
||||
|
|
@ -1107,22 +1110,22 @@ func upsertMqttModuleConfigPacket(config: Meshtastic.ModuleConfig.MQTTConfig, no
|
|||
}
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated MQTT Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [MQTTConfigEntity] Updated for node number: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data MQTTConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [MQTTConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save MQTT Module Config")
|
||||
Logger.data.error("💥 [MQTTConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save MQTT Module Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data MQTTConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [MQTTConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertRangeTestModuleConfigPacket(config: Meshtastic.ModuleConfig.RangeTestConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertRangeTestModuleConfigPacket(config: ModuleConfig.RangeTestConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.rangetest.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("⛰️ \(logString)")
|
||||
|
|
@ -1147,22 +1150,22 @@ func upsertRangeTestModuleConfigPacket(config: Meshtastic.ModuleConfig.RangeTest
|
|||
}
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Range Test Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [RangeTestConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data RangeTestConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [RangeTestConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Range Test Module Config")
|
||||
Logger.data.error("💥 [RangeTestConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Range Test Module Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data RangeTestConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [RangeTestConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertSerialModuleConfigPacket(config: Meshtastic.ModuleConfig.SerialConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertSerialModuleConfigPacket(config: ModuleConfig.SerialConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.serial.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("🤖 \(logString)")
|
||||
|
|
@ -1199,29 +1202,25 @@ func upsertSerialModuleConfigPacket(config: Meshtastic.ModuleConfig.SerialConfig
|
|||
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Serial Module Config for node number: \(String(nodeNum))")
|
||||
|
||||
Logger.data.info("💾 [SerialConfigEntity]Updated Serial Module Config for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
|
||||
context.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data SerialConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [SerialConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Serial Module Config")
|
||||
Logger.data.error("💥 [SerialConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Serial Module Config")
|
||||
}
|
||||
|
||||
} catch {
|
||||
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data SerialConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [SerialConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertStoreForwardModuleConfigPacket(config: Meshtastic.ModuleConfig.StoreForwardConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertStoreForwardModuleConfigPacket(config: ModuleConfig.StoreForwardConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.storeforward.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("📬 \(logString)")
|
||||
|
|
@ -1253,22 +1252,22 @@ func upsertStoreForwardModuleConfigPacket(config: Meshtastic.ModuleConfig.StoreF
|
|||
}
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Store & Forward Module Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [StoreForwardConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data StoreForwardConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [StoreForwardConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Store & Forward Module Config")
|
||||
Logger.data.error("💥 [StoreForwardConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Store & Forward Module Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data DetectionSensorConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [StoreForwardConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertTelemetryModuleConfigPacket(config: Meshtastic.ModuleConfig.TelemetryConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertTelemetryModuleConfigPacket(config: ModuleConfig.TelemetryConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.telemetry.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("📈 \(logString)")
|
||||
|
|
@ -1307,20 +1306,20 @@ func upsertTelemetryModuleConfigPacket(config: Meshtastic.ModuleConfig.Telemetry
|
|||
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Telemetry Module Config for node number: \(String(nodeNum))")
|
||||
Logger.data.info("💾 [TelemetryConfigEntity] Updated Telemetry Module Config for node: \(nodeNum.toHex(), privacy: .public)")
|
||||
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Updating Core Data TelemetryConfigEntity: \(nsError)")
|
||||
Logger.data.error("💥 [TelemetryConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
|
||||
}
|
||||
|
||||
} else {
|
||||
Logger.data.error("No Nodes found in local database matching node number \(nodeNum) unable to save Telemetry Module Config")
|
||||
Logger.data.error("💥 [TelemetryConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Telemetry Module Config")
|
||||
}
|
||||
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Fetching node for core data TelemetryConfigEntity failed: \(nsError)")
|
||||
Logger.data.error("💥 [TelemetryConfigEntity] Fetching node for core data TelemetryConfigEntity failed: \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ struct Connect: View {
|
|||
@State var isUnsetRegion = false
|
||||
@State var invalidFirmwareVersion = false
|
||||
@State var liveActivityStarted = false
|
||||
@State var presentingSwitchPreferredPeripheral = false
|
||||
@State var selectedPeripherialId = ""
|
||||
|
||||
init () {
|
||||
|
|
@ -49,7 +48,7 @@ struct Connect: View {
|
|||
List {
|
||||
if bleManager.isSwitchedOn {
|
||||
Section(header: Text("connected.radio").font(.title)) {
|
||||
if bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.peripheral.state == .connected {
|
||||
if let connectedPeripheral = bleManager.connectedPeripheral, connectedPeripheral.peripheral.state == .connected {
|
||||
if #available(iOS 17.0, macOS 14.0, *) {
|
||||
TipView(BluetoothConnectionTip(), arrowEdge: .bottom)
|
||||
}
|
||||
|
|
@ -60,9 +59,9 @@ struct Connect: View {
|
|||
.padding(.trailing)
|
||||
VStack(alignment: .leading) {
|
||||
if node != nil {
|
||||
Text(bleManager.connectedPeripheral.longName).font(.title2)
|
||||
Text(connectedPeripheral.longName).font(.title2)
|
||||
}
|
||||
Text("ble.name").font(.callout)+Text(": \(bleManager.connectedPeripheral.peripheral.name ?? "unknown".localized)")
|
||||
Text("ble.name").font(.callout)+Text(": \(bleManager.connectedPeripheral?.peripheral.name ?? "unknown".localized)")
|
||||
.font(.callout).foregroundColor(Color.gray)
|
||||
if node != nil {
|
||||
Text("firmware.version").font(.callout)+Text(": \(node?.metadata?.firmwareVersion ?? "unknown".localized)")
|
||||
|
|
@ -91,7 +90,8 @@ struct Connect: View {
|
|||
.padding([.top, .bottom])
|
||||
.swipeActions {
|
||||
Button(role: .destructive) {
|
||||
if bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.peripheral.state == CBPeripheralState.connected {
|
||||
if let connectedPeripheral = bleManager.connectedPeripheral,
|
||||
connectedPeripheral.peripheral.state == .connected {
|
||||
bleManager.disconnectPeripheral(reconnect: false)
|
||||
}
|
||||
} label: {
|
||||
|
|
@ -121,7 +121,8 @@ struct Connect: View {
|
|||
Text("Num: \(String(node!.num))")
|
||||
Text("Short Name: \(node?.user?.shortName ?? "?")")
|
||||
Text("Long Name: \(node?.user?.longName ?? "unknown".localized)")
|
||||
Text("BLE RSSI: \(bleManager.connectedPeripheral.rssi)")
|
||||
Text("BLE RSSI: \(connectedPeripheral.rssi)")
|
||||
|
||||
Button {
|
||||
if !bleManager.sendShutdown(fromUser: node!.user!, toUser: node!.user!, adminIndex: node!.myInfo!.adminIndex) {
|
||||
Logger.mesh.error("Shutdown Failed")
|
||||
|
|
@ -210,11 +211,25 @@ struct Connect: View {
|
|||
}
|
||||
Button(action: {
|
||||
if UserDefaults.preferredPeripheralId.count > 0 && peripheral.peripheral.identifier.uuidString != UserDefaults.preferredPeripheralId {
|
||||
presentingSwitchPreferredPeripheral = true
|
||||
selectedPeripherialId = peripheral.peripheral.identifier.uuidString
|
||||
} else {
|
||||
self.bleManager.connectTo(peripheral: peripheral.peripheral)
|
||||
if let connectedPeripheral = bleManager.connectedPeripheral, connectedPeripheral.peripheral.state == CBPeripheralState.connected {
|
||||
bleManager.disconnectPeripheral()
|
||||
}
|
||||
let container = NSPersistentContainer(name: "Meshtastic")
|
||||
guard let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
|
||||
Logger.data.error("nil File path for back")
|
||||
return
|
||||
}
|
||||
do {
|
||||
try container.copyPersistentStores(to: url.appendingPathComponent("backup").appendingPathComponent("\(UserDefaults.preferredPeripheralNum)"), overwriting: true)
|
||||
clearCoreDataDatabase(context: context, includeRoutes: true)
|
||||
Logger.data.notice("🗂️ Made a core data backup to backup/\(UserDefaults.preferredPeripheralNum)")
|
||||
|
||||
} catch {
|
||||
Logger.data.error("🗂️ Core data backup copy error: \(error, privacy: .public)")
|
||||
}
|
||||
}
|
||||
UserDefaults.preferredPeripheralId = selectedPeripherialId
|
||||
self.bleManager.connectTo(peripheral: peripheral.peripheral)
|
||||
}) {
|
||||
Text(peripheral.name).font(.callout)
|
||||
}
|
||||
|
|
@ -225,23 +240,6 @@ struct Connect: View {
|
|||
}.padding([.bottom, .top])
|
||||
}
|
||||
}
|
||||
.confirmationDialog("Connecting to a new radio will clear all local app data on the phone.", isPresented: $presentingSwitchPreferredPeripheral, titleVisibility: .visible) {
|
||||
|
||||
Button("Connect to new radio?", role: .destructive) {
|
||||
UserDefaults.preferredPeripheralId = selectedPeripherialId
|
||||
UserDefaults.preferredPeripheralNum = 0
|
||||
if bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.peripheral.state == CBPeripheralState.connected {
|
||||
bleManager.disconnectPeripheral()
|
||||
}
|
||||
clearCoreDataDatabase(context: context, includeRoutes: false)
|
||||
|
||||
let radio = bleManager.peripherals.first(where: { $0.peripheral.identifier.uuidString == selectedPeripherialId })
|
||||
if radio != nil {
|
||||
bleManager.connectTo(peripheral: radio!.peripheral)
|
||||
}
|
||||
}
|
||||
}
|
||||
.textCase(nil)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -254,9 +252,9 @@ struct Connect: View {
|
|||
HStack(alignment: .center) {
|
||||
Spacer()
|
||||
#if targetEnvironment(macCatalyst)
|
||||
if bleManager.connectedPeripheral != nil {
|
||||
if let connectedPeripheral = bleManager.connectedPeripheral {
|
||||
Button(role: .destructive, action: {
|
||||
if bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.peripheral.state == CBPeripheralState.connected {
|
||||
if connectedPeripheral.peripheral.state == CBPeripheralState.connected {
|
||||
bleManager.disconnectPeripheral(reconnect: false)
|
||||
}
|
||||
}) {
|
||||
|
|
@ -285,10 +283,18 @@ struct Connect: View {
|
|||
.padding(.bottom, 10)
|
||||
}
|
||||
.navigationTitle("bluetooth")
|
||||
.navigationBarItems(leading: MeshtasticLogo(), trailing:
|
||||
ZStack {
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?", mqttProxyConnected: bleManager.mqttProxyConnected, mqttTopic: bleManager.mqttManager.topic)
|
||||
})
|
||||
.navigationBarItems(
|
||||
leading: MeshtasticLogo(),
|
||||
trailing: ZStack {
|
||||
ConnectedDevice(
|
||||
bluetoothOn: bleManager.isSwitchedOn,
|
||||
deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
name: bleManager.connectedPeripheral?.shortName ?? "?",
|
||||
mqttProxyConnected: bleManager.mqttProxyConnected,
|
||||
mqttTopic: bleManager.mqttManager.topic
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
.sheet(isPresented: $invalidFirmwareVersion, onDismiss: didDismissSheet) {
|
||||
InvalidVersion(minimumVersion: self.bleManager.minimumVersion, version: self.bleManager.connectedVersion)
|
||||
|
|
@ -306,18 +312,14 @@ struct Connect: View {
|
|||
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(bleManager.connectedPeripheral?.num ?? -1))
|
||||
|
||||
do {
|
||||
let fetchedNode = try context.fetch(fetchNodeInfoRequest)
|
||||
// Found a node, check it for a region
|
||||
if !fetchedNode.isEmpty {
|
||||
node = fetchedNode[0]
|
||||
if node!.loRaConfig != nil && node!.loRaConfig?.regionCode ?? 0 == RegionCodes.unset.rawValue {
|
||||
isUnsetRegion = true
|
||||
} else {
|
||||
isUnsetRegion = false
|
||||
}
|
||||
node = try context.fetch(fetchNodeInfoRequest).first
|
||||
if let loRaConfig = node?.loRaConfig, loRaConfig.regionCode == RegionCodes.unset.rawValue {
|
||||
isUnsetRegion = true
|
||||
} else {
|
||||
isUnsetRegion = false
|
||||
}
|
||||
} catch {
|
||||
|
||||
Logger.data.error("💥 Error fetching node info: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,25 +89,25 @@ class LocalMBTileOverlay: MKTileOverlay {
|
|||
}
|
||||
}
|
||||
|
||||
override func loadTile(at path: MKTileOverlayPath, result: @escaping (Data?, Error?) -> Void) {
|
||||
|
||||
let tileX = Int64(path.x)
|
||||
let tileY = Int64(path.y)
|
||||
let tileZ = Int64(path.z)
|
||||
let tileData = Expression<SQLite.Blob>("tile_data")
|
||||
let zoomLevel = Expression<Int64>("zoom_level")
|
||||
let tileColumn = Expression<Int64>("tile_column")
|
||||
let tileRow = Expression<Int64>("tile_row")
|
||||
|
||||
if let dataQuery = try? self.mb.pluck(Table("tiles").select(tileData).filter(zoomLevel == tileZ).filter(tileColumn == tileX).filter(tileRow == tileY)) {
|
||||
let data = Data(bytes: dataQuery[tileData].bytes, count: dataQuery[tileData].bytes.count)// dataQuery![tileData].bytes
|
||||
result(data, nil)
|
||||
} else {
|
||||
Logger.services.error("No tile here: x:\(tileX) y:\(tileY) z:\(tileZ)")
|
||||
let error = NSError(domain: "LocalMBTileOverlay", code: 1, userInfo: ["reason": "no_tile"])
|
||||
result(nil, error)
|
||||
}
|
||||
}
|
||||
// override func loadTile(at path: MKTileOverlayPath, result: @escaping (Data?, Error?) -> Void) {
|
||||
//
|
||||
// let tileX = Int64(path.x)
|
||||
// let tileY = Int64(path.y)
|
||||
// let tileZ = Int64(path.z)
|
||||
// let tileData = Expression<SQLite.Blob>("tile_data")
|
||||
// let zoomLevel = Expression<Int64>("zoom_level")
|
||||
// let tileColumn = Expression<Int64>("tile_column")
|
||||
// let tileRow = Expression<Int64>("tile_row")
|
||||
//
|
||||
// if let dataQuery = try? self.mb.pluck(Table("tiles").select(tileData).filter(zoomLevel == tileZ).filter(tileColumn == tileX).filter(tileRow == tileY)) {
|
||||
// let data = Data(bytes: dataQuery[tileData].bytes, count: dataQuery[tileData].bytes.count)// dataQuery![tileData].bytes
|
||||
// result(data, nil)
|
||||
// } else {
|
||||
// Logger.services.error("No tile here: x:\(tileX) y:\(tileY) z:\(tileZ)")
|
||||
// let error = NSError(domain: "LocalMBTileOverlay", code: 1, userInfo: ["reason": "no_tile"])
|
||||
// result(nil, error)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// public class CustomMapOverlaySource: MKTileOverlay {
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@
|
|||
// Copyright Garth Vander Houwen 1/10/23.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import CoreLocation
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct WaypointFormMapKit: View {
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@
|
|||
// Created by Garth Vander Houwen on 12/24/21.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct ChannelMessageList: View {
|
||||
@StateObject var appState = AppState.shared
|
||||
|
|
@ -115,7 +116,7 @@ struct ChannelMessageList: View {
|
|||
message.read = true
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("📖 Read message \(message.messageId) ")
|
||||
Logger.data.info("📖 [App] Read message \(message.messageId) ")
|
||||
appState.unreadChannelMessages = myInfo.unreadMessages
|
||||
UIApplication.shared.applicationIconBadgeNumber = appState.unreadChannelMessages + appState.unreadDirectMessages
|
||||
context.refresh(myInfo, mergeChanges: true)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct MessageText: View {
|
||||
static let linkBlue = Color(red: 0.4627, green: 0.8392, blue: 1) /* #76d6ff */
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ struct UserMessageList: View {
|
|||
message.read = true
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("📖 Read message \(message.messageId) ")
|
||||
Logger.data.info("📖 [App] Read message \(message.messageId) ")
|
||||
appState.unreadDirectMessages = user.unreadMessages
|
||||
UIApplication.shared.applicationIconBadgeNumber = appState.unreadChannelMessages + appState.unreadDirectMessages
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import SwiftUI
|
||||
import Charts
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
|
||||
struct DetectionSensorLog: View {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
// Copyright Garth Vander Houwen 1/10/23.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MapKit
|
||||
import CoreLocation
|
||||
import MapKit
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct WaypointForm: View {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
//
|
||||
// AdminMessageList.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Created by Garth Vander Houwen on 7/2/22.
|
||||
//
|
||||
/*
|
||||
Abstract:
|
||||
A view showing the details for a node.
|
||||
*/
|
||||
|
||||
import SwiftUI
|
||||
import MapKit
|
||||
import CoreLocation
|
||||
|
||||
struct AdminMessageList: View {
|
||||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
|
||||
var user: UserEntity?
|
||||
|
||||
var body: some View {
|
||||
let localeDateFormat = DateFormatter.dateFormat(fromTemplate: "yyMMddjmmssa", options: 0, locale: Locale.current)
|
||||
let localeTimeFormat = DateFormatter.dateFormat(fromTemplate: "h:mm:ss a", options: 0, locale: Locale.current)
|
||||
let dateFormatString = (localeDateFormat ?? "MM/dd/YY j:mm:ss a")
|
||||
let timeFormatString = (localeTimeFormat ?? "h:mm:ss a")
|
||||
|
||||
List {
|
||||
if user != nil {
|
||||
|
||||
ForEach( user!.adminMessageList.reversed() ) { am in
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
|
||||
Text("\(am.adminDescription ?? "unknown".localized)")
|
||||
.font(.caption)
|
||||
|
||||
Text("Sent \(Date(timeIntervalSince1970: TimeInterval(am.messageTimestamp)).formattedDate(format: dateFormatString))")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption2)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
let ackErrorVal = RoutingError(rawValue: Int(am.ackError))
|
||||
|
||||
if am.ackTimestamp > 0 {
|
||||
if am.realACK {
|
||||
|
||||
Text(ackErrorVal?.display ?? "Empty Ack Error")
|
||||
.foregroundColor(am.receivedACK ? .gray : .red)
|
||||
.font(.caption2)
|
||||
} else {
|
||||
Text("Implicit ACK from another node")
|
||||
.foregroundColor(.orange)
|
||||
.font(.caption2)
|
||||
}
|
||||
}
|
||||
|
||||
if am.receivedACK && am.ackTimestamp > 0 {
|
||||
Text(" \(Date(timeIntervalSince1970: TimeInterval(am.ackTimestamp)).formattedDate(format: timeFormatString))")
|
||||
.foregroundColor(am.realACK ? .gray : .orange)
|
||||
.font(.caption2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("admin.log")
|
||||
.navigationBarItems(trailing:
|
||||
ZStack {
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
|
||||
})
|
||||
.onAppear {
|
||||
if self.bleManager.context == nil {
|
||||
self.bleManager.context = context
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
156
Meshtastic/Views/Settings/AppData.swift
Normal file
156
Meshtastic/Views/Settings/AppData.swift
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
//
|
||||
// AppData.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Copyright(c) Garth Vander Houwen 6/8/24.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import OSLog
|
||||
import CoreData
|
||||
import Foundation
|
||||
|
||||
struct AppData: View {
|
||||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@State private var files = [URL]()
|
||||
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
|
||||
|
||||
var body: some View {
|
||||
|
||||
VStack {
|
||||
Button(action: {
|
||||
let container = NSPersistentContainer(name: "Meshtastic")
|
||||
guard let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
|
||||
Logger.data.error("nil File path for back")
|
||||
return
|
||||
}
|
||||
do {
|
||||
try container.copyPersistentStores(to: url.appendingPathComponent("backup").appendingPathComponent("\(UserDefaults.preferredPeripheralNum)"), overwriting: true)
|
||||
loadFiles()
|
||||
Logger.data.notice("🗂️ Made a core data backup to backup/\(UserDefaults.preferredPeripheralNum)")
|
||||
} catch {
|
||||
Logger.data.error("🗂️ Core data backup copy error: \(error, privacy: .public)")
|
||||
}
|
||||
}) {
|
||||
Label {
|
||||
Text("Backup Database")
|
||||
.font(idiom == .phone ? .callout : .title)
|
||||
} icon: {
|
||||
Image(systemName: "cylinder.split.1x2")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(idiom == .phone ? .callout : .title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
}
|
||||
List(files, id: \.self) { file in
|
||||
HStack {
|
||||
VStack(alignment: .leading ) {
|
||||
if file.pathExtension.contains("sqlite") {
|
||||
Label {
|
||||
Text("Node Core Data Backup \(file.pathComponents[(idiom == .phone || idiom == .pad) ? 9 : 10])/\(file.lastPathComponent) - \(file.creationDate?.formatted() ?? "") - \(file.fileSizeString)")
|
||||
.swipeActions {
|
||||
Button(role: .none) {
|
||||
bleManager.disconnectPeripheral(reconnect: false)
|
||||
let container = NSPersistentContainer(name: "Meshtastic")
|
||||
do {
|
||||
clearCoreDataDatabase(context: context, includeRoutes: true)
|
||||
try container.restorePersistentStore(from: file.absoluteURL)
|
||||
let request = MyInfoEntity.fetchRequest()
|
||||
try context.fetch(request)
|
||||
UserDefaults.preferredPeripheralId = ""
|
||||
UserDefaults.preferredPeripheralNum = Int(file.pathComponents[(idiom == .phone || idiom == .pad) ? 9 : 10]) ?? 0
|
||||
Logger.data.notice("🗂️ Restored a core data backup to backup/\(UserDefaults.preferredPeripheralNum, privacy: .public)")
|
||||
} catch {
|
||||
Logger.data.error("🗂️ Core data restore copy error: \(error, privacy: .public)")
|
||||
}
|
||||
} label: {
|
||||
Label("restore", systemImage: "arrow.counterclockwise")
|
||||
}
|
||||
Button(role: .destructive) {
|
||||
do {
|
||||
try FileManager.default.removeItem(at: file)
|
||||
} catch {
|
||||
Logger.services.error("🗑️ Delete file error: \(error, privacy: .public)")
|
||||
}
|
||||
} label: {
|
||||
Label("delete", systemImage: "trash")
|
||||
}
|
||||
}
|
||||
} icon: {
|
||||
Image(systemName: "cylinder.split.1x2")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(idiom == .phone ? .callout : .title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
} else {
|
||||
Label {
|
||||
Text("\(file.lastPathComponent) - \(file.creationDate?.formatted() ?? "") - \(file.fileSizeString)")
|
||||
.swipeActions {
|
||||
Button(role: .destructive) {
|
||||
do {
|
||||
try FileManager.default.removeItem(at: file)
|
||||
} catch {
|
||||
Logger.services.error("🗑️ Delete file error: \(error, privacy: .public)")
|
||||
}
|
||||
} label: {
|
||||
Label("delete", systemImage: "trash")
|
||||
}
|
||||
}
|
||||
} icon: {
|
||||
Image(systemName: "doc.text")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(idiom == .phone ? .callout : .title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
}
|
||||
}
|
||||
#if targetEnvironment(macCatalyst)
|
||||
Spacer()
|
||||
VStack(alignment: .trailing) {
|
||||
Button {
|
||||
do {
|
||||
try FileManager.default.removeItem(at: file)
|
||||
loadFiles()
|
||||
} catch {
|
||||
Logger.services.error("🗑️ Delete file error: \(error, privacy: .public)")
|
||||
}
|
||||
} label: {
|
||||
Label("", systemImage: "trash")
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
.navigationBarTitle("File Storage", displayMode: .inline)
|
||||
.onAppear(perform: {
|
||||
loadFiles()
|
||||
})
|
||||
.listStyle(.inset)
|
||||
}
|
||||
|
||||
private func loadFiles() {
|
||||
files = []
|
||||
guard let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
|
||||
Logger.data.error("🗂️ nil default document directory path for backup, core data backup failed.")
|
||||
return
|
||||
}
|
||||
if let enumerator = FileManager.default.enumerator(at: url, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) {
|
||||
for case let fileURL as URL in enumerator {
|
||||
do {
|
||||
let fileAttributes = try fileURL.resourceValues(forKeys: [.isRegularFileKey])
|
||||
if fileAttributes.isRegularFile! {
|
||||
files.append(fileURL)
|
||||
}
|
||||
} catch {
|
||||
Logger.services.error("📁 Load file: \(fileURL, privacy: .public) error: \(error, privacy: .public)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
234
Meshtastic/Views/Settings/AppLog.swift
Normal file
234
Meshtastic/Views/Settings/AppLog.swift
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
//
|
||||
// AppLog.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Created by Garth Vander Houwen on 6/4/24.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import OSLog
|
||||
|
||||
/// Needed for TableColumnForEach
|
||||
@available(iOS 17.4, *)
|
||||
struct AppLog: View {
|
||||
|
||||
@State private var logs: [OSLogEntryLog] = []
|
||||
@State private var sortOrder = [KeyPathComparator(\OSLogEntryLog.date, order: .reverse)]
|
||||
@State private var selection: OSLogEntry.ID?
|
||||
|
||||
@State private var selectedLog: OSLogEntryLog?
|
||||
@State private var presentingErrorDetails: Bool = false
|
||||
@State private var searchText = ""
|
||||
@State private var categories: Set<Int> = []
|
||||
@State private var levels: Set<Int> = []
|
||||
@State var isExporting = false
|
||||
@State var exportString = ""
|
||||
@State var isEditingFilters = false
|
||||
|
||||
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
|
||||
private let dateFormatStyle = Date.FormatStyle()
|
||||
.hour(.twoDigits(amPM: .omitted))
|
||||
.minute()
|
||||
.second()
|
||||
.secondFraction(.fractional(3))
|
||||
|
||||
var body: some View {
|
||||
|
||||
Table(logs, selection: $selection, sortOrder: $sortOrder) {
|
||||
if idiom != .phone {
|
||||
TableColumn("log.time") { value in
|
||||
Text(value.date.formatted(dateFormatStyle))
|
||||
}
|
||||
.width(min: 125, max: 150)
|
||||
TableColumn("log.category", value: \.category)
|
||||
.width(min: 125, max: 150)
|
||||
TableColumn("log.level") { value in
|
||||
Text(value.level.description)
|
||||
}
|
||||
.width(min: 75, max: 100)
|
||||
}
|
||||
TableColumn("log.message", value: \.composedMessage) { value in
|
||||
Text(value.composedMessage)
|
||||
.font(idiom == .phone ? .caption : .body)
|
||||
}
|
||||
.width(ideal: 200, max: .infinity)
|
||||
}
|
||||
.monospaced()
|
||||
|
||||
.safeAreaInset(edge: .bottom, alignment: .trailing) {
|
||||
HStack {
|
||||
Button(action: {
|
||||
withAnimation {
|
||||
isEditingFilters = !isEditingFilters
|
||||
}
|
||||
}) {
|
||||
Image(systemName: !isEditingFilters ? "line.3.horizontal.decrease.circle" : "line.3.horizontal.decrease.circle.fill")
|
||||
.padding(.vertical, 5)
|
||||
}
|
||||
.tint(Color(UIColor.secondarySystemBackground))
|
||||
.foregroundColor(.accentColor)
|
||||
.buttonStyle(.borderedProminent)
|
||||
|
||||
}
|
||||
.controlSize(.regular)
|
||||
.padding(5)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
.padding(.trailing, 5)
|
||||
.searchable(text: $searchText, placement: .navigationBarDrawer, prompt: "Search")
|
||||
.disabled(selection != nil)
|
||||
.overlay {
|
||||
if logs.isEmpty {
|
||||
ContentUnavailableView("No Logs Available", systemImage: "scroll")
|
||||
}
|
||||
}
|
||||
.refreshable {
|
||||
await logs = searchAppLogs()
|
||||
logs.sort(using: sortOrder)
|
||||
}
|
||||
.onChange(of: sortOrder) { _, sortOrder in
|
||||
withAnimation {
|
||||
logs.sort(using: sortOrder)
|
||||
}
|
||||
}
|
||||
.onChange(of: searchText) { _ in
|
||||
Task {
|
||||
await logs = searchAppLogs()
|
||||
logs.sort(using: sortOrder)
|
||||
}
|
||||
}
|
||||
.onChange(of: [categories]) { _ in
|
||||
Task {
|
||||
await logs = searchAppLogs()
|
||||
logs.sort(using: sortOrder)
|
||||
}
|
||||
}
|
||||
.onChange(of: [levels]) { _ in
|
||||
Task {
|
||||
await logs = searchAppLogs()
|
||||
logs.sort(using: sortOrder)
|
||||
}
|
||||
}
|
||||
.onChange(of: selection) { newSelection in
|
||||
presentingErrorDetails = true
|
||||
let log = logs.first {
|
||||
$0.id == newSelection
|
||||
}
|
||||
selectedLog = log
|
||||
}
|
||||
.sheet(isPresented: $isEditingFilters) {
|
||||
AppLogFilter(categories: $categories, levels: $levels)
|
||||
}
|
||||
.sheet(item: $selectedLog, onDismiss: didDismiss) { log in
|
||||
LogDetail(log: log)
|
||||
.padding()
|
||||
}
|
||||
.task {
|
||||
logs = await searchAppLogs()
|
||||
logs.sort(using: sortOrder)
|
||||
}
|
||||
.fileExporter(
|
||||
isPresented: $isExporting,
|
||||
document: CsvDocument(emptyCsv: exportString),
|
||||
contentType: .commaSeparatedText,
|
||||
defaultFilename: String("Meshtastic Application Logs"),
|
||||
onCompletion: { result in
|
||||
switch result {
|
||||
case .success:
|
||||
self.isExporting = false
|
||||
Logger.services.info("Application log download succeeded.")
|
||||
case .failure(let error):
|
||||
Logger.services.error("Application log download failed: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
)
|
||||
.navigationBarTitle("Debug Logs\(logs.isEmpty ? "" : " (\(logs.count))")", displayMode: .inline)
|
||||
.toolbar {
|
||||
#if targetEnvironment(macCatalyst)
|
||||
ToolbarItem(placement: .topBarLeading) {
|
||||
Button(action: {
|
||||
Task {
|
||||
await logs = searchAppLogs()
|
||||
logs.sort(using: sortOrder)
|
||||
}
|
||||
}) {
|
||||
Image(systemName: "arrow.clockwise.circle")
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if !logs.isEmpty {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button(action: {
|
||||
exportString = logToCsvFile(log: logs)
|
||||
isExporting = true
|
||||
}) {
|
||||
Image(systemName: "square.and.arrow.down")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func didDismiss() {
|
||||
selection = nil
|
||||
selectedLog = nil
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 17.4, *)
|
||||
extension AppLog {
|
||||
@MainActor
|
||||
private func searchAppLogs() async -> [OSLogEntryLog] {
|
||||
do {
|
||||
/// Case Insensitive Search Text Predicates
|
||||
let searchPredicates = ["composedMessage", "category", "subsystem", "process"].map { property in
|
||||
return NSPredicate(format: "%K CONTAINS[c] %@", property, searchText)
|
||||
}
|
||||
/// Create a compound predicate using each text search preicate as an OR
|
||||
let textSearchPredicate = NSCompoundPredicate(type: .or, subpredicates: searchPredicates)
|
||||
/// Create an array of predicates to hold our AND predicates
|
||||
var predicates: [NSPredicate] = []
|
||||
/// Subsystem Predicate
|
||||
let subsystemPredicate = NSPredicate(format: "subsystem IN %@", ["com.apple.SwiftUI", "com.apple.coredata", "gvh.MeshtasticClient"])
|
||||
predicates.append(subsystemPredicate)
|
||||
/// Categories
|
||||
if categories.count > 0 {
|
||||
var categoriesArray: [NSPredicate] = []
|
||||
for c in categories {
|
||||
let categoriesPredicate = NSPredicate(format: "category == %@", LogCategories(rawValue: c)?.description ?? "services")
|
||||
categoriesArray.append(categoriesPredicate)
|
||||
}
|
||||
let compoundPredicate = NSCompoundPredicate(type: .or, subpredicates: categoriesArray)
|
||||
predicates.append(compoundPredicate)
|
||||
}
|
||||
/// Log Levels
|
||||
if levels.count > 0 {
|
||||
var levelsArray: [NSPredicate] = []
|
||||
for l in levels {
|
||||
let levelsPredicate = NSPredicate(format: "messageType == %@", LogLevels(rawValue: l)?.level ?? "info")
|
||||
levelsArray.append(levelsPredicate)
|
||||
}
|
||||
let compoundPredicate = NSCompoundPredicate(type: .or, subpredicates: levelsArray)
|
||||
predicates.append(compoundPredicate)
|
||||
}
|
||||
if predicates.count > 0 || !searchText.isEmpty {
|
||||
if !searchText.isEmpty {
|
||||
let filterPredicates = NSCompoundPredicate(type: .and, subpredicates: predicates)
|
||||
let compoundPredicate = NSCompoundPredicate(type: .and, subpredicates: [textSearchPredicate, filterPredicates])
|
||||
let logs = try await Logger.fetch(predicateFormat: compoundPredicate.predicateFormat)
|
||||
return logs
|
||||
} else {
|
||||
let filterPredicates = NSCompoundPredicate(type: .and, subpredicates: predicates)
|
||||
let logs = try await Logger.fetch(predicateFormat: filterPredicates.predicateFormat)
|
||||
return logs
|
||||
}
|
||||
} else {
|
||||
let logs = try await Logger.fetch(predicateFormat: subsystemPredicate.predicateFormat)
|
||||
return logs
|
||||
}
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension OSLogEntry: Identifiable { }
|
||||
|
|
@ -76,6 +76,26 @@ struct AppSettings: View {
|
|||
) {
|
||||
Button("Erase all app data?", role: .destructive) {
|
||||
bleManager.disconnectPeripheral()
|
||||
/// Delete any database backups too
|
||||
if var url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
|
||||
url = url.appendingPathComponent("backup").appendingPathComponent(String(UserDefaults.preferredPeripheralNum))
|
||||
do {
|
||||
try FileManager.default.removeItem(at: url.appendingPathComponent("Meshtastic.sqlite"))
|
||||
/// Delete -shm file
|
||||
do {
|
||||
try FileManager.default.removeItem(at: url.appendingPathComponent("Meshtastic.sqlite-wal"))
|
||||
do {
|
||||
try FileManager.default.removeItem(at: url.appendingPathComponent("Meshtastic.sqlite-shm"))
|
||||
} catch {
|
||||
Logger.services.error("Error Deleting Meshtastic.sqlite-shm file \(error, privacy: .public)")
|
||||
}
|
||||
} catch {
|
||||
Logger.services.error("Error Deleting Meshtastic.sqlite-wal file \(error, privacy: .public)")
|
||||
}
|
||||
} catch {
|
||||
Logger.services.error("Error Deleting Meshtastic.sqlite file \(error, privacy: .public)")
|
||||
}
|
||||
}
|
||||
clearCoreDataDatabase(context: context, includeRoutes: true)
|
||||
context.refreshAllObjects()
|
||||
UserDefaults.standard.reset()
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
// Copyright(c) Garth Vander Houwen 4/8/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import CoreData
|
||||
import MapKit
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
#if canImport(TipKit)
|
||||
import TipKit
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@
|
|||
// Copyright (c) Garth Vander Houwen 8/18/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct BluetoothConfig: View {
|
||||
@Environment(\.managedObjectContext) var context
|
||||
|
|
@ -18,6 +19,7 @@ struct BluetoothConfig: View {
|
|||
@State var mode = 0
|
||||
@State var fixedPin = "123456"
|
||||
@State var shortPin = false
|
||||
@State var deviceLoggingEnabled = false
|
||||
var pinLength: Int = 6
|
||||
let numberFormatter: NumberFormatter = {
|
||||
let formatter = NumberFormatter()
|
||||
|
|
@ -68,18 +70,23 @@ struct BluetoothConfig: View {
|
|||
.foregroundColor(.red)
|
||||
}
|
||||
}
|
||||
Toggle(isOn: $deviceLoggingEnabled) {
|
||||
Label("Device Logging Enabled", systemImage: "ladybug")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
}
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.bluetoothConfig == nil)
|
||||
|
||||
SaveConfigButton(node: node, hasChanges: $hasChanges) {
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if connectedNode != nil {
|
||||
if let myNodeNum = bleManager.connectedPeripheral?.num,
|
||||
let connectedNode = getNodeInfo(id: myNodeNum, context: context) {
|
||||
var bc = Config.BluetoothConfig()
|
||||
bc.enabled = enabled
|
||||
bc.mode = BluetoothModes(rawValue: mode)?.protoEnumValue() ?? Config.BluetoothConfig.PairingMode.randomPin
|
||||
bc.fixedPin = UInt32(fixedPin) ?? 123456
|
||||
let adminMessageId = bleManager.saveBluetoothConfig(config: bc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
bc.deviceLoggingEnabled = deviceLoggingEnabled
|
||||
let adminMessageId = bleManager.saveBluetoothConfig(config: bc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
@ -90,21 +97,26 @@ struct BluetoothConfig: View {
|
|||
}
|
||||
|
||||
.navigationTitle("bluetooth.config")
|
||||
.navigationBarItems(trailing:
|
||||
ZStack {
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
|
||||
})
|
||||
.navigationBarItems(
|
||||
trailing: ZStack {
|
||||
ConnectedDevice(
|
||||
bluetoothOn: bleManager.isSwitchedOn,
|
||||
deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
name: bleManager.connectedPeripheral?.shortName ?? "?"
|
||||
)
|
||||
}
|
||||
)
|
||||
.onAppear {
|
||||
if self.bleManager.context == nil {
|
||||
self.bleManager.context = context
|
||||
}
|
||||
setBluetoothValues()
|
||||
// Need to request a BluetoothConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.bluetoothConfig == nil {
|
||||
if let connectedPeripheral = bleManager.connectedPeripheral, let node, node.bluetoothConfig == nil {
|
||||
Logger.mesh.info("empty bluetooth config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if node != nil && connectedNode != nil {
|
||||
_ = bleManager.requestBluetoothConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
|
||||
if let connectedNode {
|
||||
_ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -123,11 +135,17 @@ struct BluetoothConfig: View {
|
|||
if newFixedPin != String(node!.bluetoothConfig!.fixedPin) { hasChanges = true }
|
||||
}
|
||||
}
|
||||
.onChange(of: deviceLoggingEnabled) { newDeviceLogging in
|
||||
if node != nil && node!.bluetoothConfig != nil {
|
||||
if newDeviceLogging != node!.bluetoothConfig!.deviceLoggingEnabled { hasChanges = true }
|
||||
}
|
||||
}
|
||||
}
|
||||
func setBluetoothValues() {
|
||||
self.enabled = node?.bluetoothConfig?.enabled ?? true
|
||||
self.mode = Int(node?.bluetoothConfig?.mode ?? 0)
|
||||
self.fixedPin = String(node?.bluetoothConfig?.fixedPin ?? 123456)
|
||||
self.deviceLoggingEnabled = node?.bluetoothConfig?.deviceLoggingEnabled ?? false
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
//
|
||||
// Copyright (c) Garth Vander Houwen 6/13/22.
|
||||
//
|
||||
import SwiftUI
|
||||
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct DeviceConfig: View {
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@
|
|||
// Copyright (c) Garth Vander Houwen 6/7/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct DisplayConfig: View {
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import SwiftUI
|
||||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
|
||||
struct LoRaConfig: View {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
//
|
||||
// Copyright(c) Garth Vander Houwen 11/26/23
|
||||
//
|
||||
|
||||
import MeshtasticProtobufs
|
||||
import SwiftUI
|
||||
|
||||
@available(iOS 17.0, macOS 14.0, *)
|
||||
struct AmbientLightingConfig: View {
|
||||
@Environment(\.self) var environment
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
//
|
||||
// Copyright (c) Garth Vander Houwen 6/22/22.
|
||||
//
|
||||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct CannedMessagesConfig: View {
|
||||
@Environment(\.managedObjectContext) var context
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
//
|
||||
// Copyright(c) Garth Vander Houwen 8/16/23.
|
||||
//
|
||||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
enum DetectionSensorRole: String, CaseIterable, Equatable, Decodable {
|
||||
case sensor
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
//
|
||||
// Copyright (c) Garth Vander Houwen 6/22/22.
|
||||
//
|
||||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct ExternalNotificationConfig: View {
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@
|
|||
//
|
||||
// Copyright (c) Garth Vander Houwen 9/4/22.
|
||||
//
|
||||
import SwiftUI
|
||||
import CoreLocation
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct MQTTConfig: View {
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
// Copyright Garth Vander Houwen 2/25/24.
|
||||
//
|
||||
|
||||
import MeshtasticProtobufs
|
||||
import SwiftUI
|
||||
|
||||
struct PaxCounterConfig: View {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
//
|
||||
// Copyright (c) Garth Vander Houwen 6/13/22.
|
||||
//
|
||||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct RangeTestConfig: View {
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
//
|
||||
// Copyright (c) Garth Vander Houwen 6/22/22.
|
||||
//
|
||||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct SerialConfig: View {
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
//
|
||||
// Copyright(c) Garth Vander Houwen 8/26/23.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct StoreForwardConfig: View {
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
//
|
||||
// Copyright (c) Garth Vander Houwen 6/13/22.
|
||||
//
|
||||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct TelemetryConfig: View {
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
//
|
||||
// Copyright (c) Garth Vander Houwen 8/1/2022
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct NetworkConfig: View {
|
||||
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
import OSLog
|
||||
|
||||
struct PositionFlags: OptionSet {
|
||||
let rawValue: Int
|
||||
|
||||
static let Altitude = PositionFlags(rawValue: 1)
|
||||
static let AltitudeMsl = PositionFlags(rawValue: 2)
|
||||
static let GeoidalSeparation = PositionFlags(rawValue: 4)
|
||||
|
|
@ -28,12 +28,9 @@ struct PositionConfig: View {
|
|||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
|
||||
@State var hasChanges = false
|
||||
@State var hasFlagChanges = false
|
||||
|
||||
@State var smartPositionEnabled = true
|
||||
@State var deviceGpsEnabled = true
|
||||
@State var gpsMode = 0
|
||||
|
|
@ -72,301 +69,313 @@ struct PositionConfig: View {
|
|||
/// Intended for use with vehicle not walking speeds
|
||||
/// walking speeds are likely to be error prone like the compass
|
||||
@State var includeHeading = false
|
||||
|
||||
/// Minimum Version for fixed postion admin messages
|
||||
@State var minimumVersion = "2.3.3"
|
||||
@State private var supportedVersion = true
|
||||
@State private var showingSetFixedAlert = false
|
||||
// @State private var showingRemoveFixedAlert = false
|
||||
|
||||
@ViewBuilder
|
||||
var positionPacketSection: some View {
|
||||
Section(header: Text("Position Packet")) {
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Picker("Broadcast Interval", selection: $positionBroadcastSeconds) {
|
||||
ForEach(UpdateIntervals.allCases) { at in
|
||||
if at.rawValue >= 300 {
|
||||
Text(at.description)
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Text("The maximum interval that can elapse without a node broadcasting a position")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
|
||||
Toggle(isOn: $smartPositionEnabled) {
|
||||
Label("Smart Position", systemImage: "brain")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
if smartPositionEnabled {
|
||||
VStack(alignment: .leading) {
|
||||
Picker("Minimum Interval", selection: $broadcastSmartMinimumIntervalSecs) {
|
||||
ForEach(UpdateIntervals.allCases) { at in
|
||||
Text(at.description)
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Text("The fastest that position updates will be sent if the minimum distance has been satisfied")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
VStack(alignment: .leading) {
|
||||
Picker("Minimum Distance", selection: $broadcastSmartMinimumDistance) {
|
||||
ForEach(10..<151) {
|
||||
if $0 == 0 {
|
||||
Text("unset")
|
||||
} else {
|
||||
if $0.isMultiple(of: 5) {
|
||||
Text("\($0)")
|
||||
.tag($0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Text("The minimum distance change in meters to be considered for a smart position broadcast.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
var deviceGPSSection: some View {
|
||||
Section(header: Text("Device GPS")) {
|
||||
Picker("", selection: $gpsMode) {
|
||||
ForEach(GpsMode.allCases, id: \.self) { at in
|
||||
Text(at.description)
|
||||
.tag(at.id)
|
||||
|
||||
}
|
||||
}
|
||||
.pickerStyle(SegmentedPickerStyle())
|
||||
.padding(.top, 5)
|
||||
.padding(.bottom, 5)
|
||||
.disabled(fixedPosition && !(gpsMode == 1))
|
||||
if gpsMode == 1 {
|
||||
Text("Positions will be provided by your device GPS, if you select disabled or not present you can set a fixed position.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
VStack(alignment: .leading) {
|
||||
Picker("Update Interval", selection: $gpsUpdateInterval) {
|
||||
ForEach(GpsUpdateIntervals.allCases) { ui in
|
||||
Text(ui.description)
|
||||
}
|
||||
}
|
||||
Text("How often should we try to get a GPS position.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
}
|
||||
if (gpsMode != 1 && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? -1) || fixedPosition {
|
||||
VStack(alignment: .leading) {
|
||||
Toggle(isOn: $fixedPosition) {
|
||||
Label("Fixed Position", systemImage: "location.square.fill")
|
||||
if !(node?.positionConfig?.fixedPosition ?? false) {
|
||||
Text("Your current location will be set as the fixed position and broadcast over the mesh on the position interval.")
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
var positionFlagsSection: some View {
|
||||
Section(header: Text("Position Flags")) {
|
||||
|
||||
Text("Optional fields to include when assembling position messages. the more fields are included, the larger the message will be - leading to longer airtime and a higher risk of packet loss")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
|
||||
Toggle(isOn: $includeAltitude) {
|
||||
Label("Altitude", systemImage: "arrow.up")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
Toggle(isOn: $includeSatsinview) {
|
||||
Label("Number of satellites", systemImage: "skew")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
Toggle(isOn: $includeSeqNo) { // 64
|
||||
Label("Sequence number", systemImage: "number")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
Toggle(isOn: $includeTimestamp) { // 128
|
||||
Label("timestamp", systemImage: "clock")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
Toggle(isOn: $includeHeading) { // 128
|
||||
Label("Vehicle heading", systemImage: "location.circle")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
Toggle(isOn: $includeSpeed) { // 128
|
||||
|
||||
Label("Vehicle speed", systemImage: "speedometer")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
var advancedPositionFlagsSection: some View {
|
||||
Section(header: Text("Advanced Position Flags")) {
|
||||
|
||||
if includeAltitude {
|
||||
Toggle(isOn: $includeAltitudeMsl) {
|
||||
Label("Altitude is Mean Sea Level", systemImage: "arrow.up.to.line.compact")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
Toggle(isOn: $includeGeoidalSeparation) {
|
||||
Label("Altitude Geoidal Separation", systemImage: "globe.americas")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
|
||||
Toggle(isOn: $includeDop) {
|
||||
Text("Dilution of precision (DOP) PDOP used by default")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
if includeDop {
|
||||
Toggle(isOn: $includeHvdop) {
|
||||
Text("If DOP is set, use HDOP / VDOP values instead of PDOP")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
var advancedDeviceGPSSection: some View {
|
||||
Section(header: Text("Advanced Device GPS")) {
|
||||
Picker("GPS Receive GPIO", selection: $rxGpio) {
|
||||
ForEach(0..<49) {
|
||||
if $0 == 0 {
|
||||
Text("unset")
|
||||
} else {
|
||||
Text("Pin \($0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Picker("GPS Transmit GPIO", selection: $txGpio) {
|
||||
ForEach(0..<49) {
|
||||
if $0 == 0 {
|
||||
Text("unset")
|
||||
} else {
|
||||
Text("Pin \($0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Picker("GPS EN GPIO", selection: $gpsEnGpio) {
|
||||
ForEach(0..<49) {
|
||||
if $0 == 0 {
|
||||
Text("unset")
|
||||
} else {
|
||||
Text("Pin \($0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Text("(Re)define PIN_GPS_EN for your board.")
|
||||
.font(.caption)
|
||||
}
|
||||
}
|
||||
|
||||
var saveButton: some View {
|
||||
SaveConfigButton(node: node, hasChanges: $hasChanges) {
|
||||
if fixedPosition && !supportedVersion {
|
||||
_ = bleManager.sendPosition(channel: 0, destNum: node?.num ?? 0, wantResponse: true)
|
||||
}
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral!.num, context: context)
|
||||
|
||||
if connectedNode != nil {
|
||||
var pc = Config.PositionConfig()
|
||||
pc.positionBroadcastSmartEnabled = smartPositionEnabled
|
||||
pc.gpsEnabled = gpsMode == 1
|
||||
pc.gpsMode = Config.PositionConfig.GpsMode(rawValue: gpsMode) ?? Config.PositionConfig.GpsMode.notPresent
|
||||
pc.fixedPosition = fixedPosition
|
||||
pc.gpsUpdateInterval = UInt32(gpsUpdateInterval)
|
||||
pc.positionBroadcastSecs = UInt32(positionBroadcastSeconds)
|
||||
pc.broadcastSmartMinimumIntervalSecs = UInt32(broadcastSmartMinimumIntervalSecs)
|
||||
pc.broadcastSmartMinimumDistance = UInt32(broadcastSmartMinimumDistance)
|
||||
pc.rxGpio = UInt32(rxGpio)
|
||||
pc.txGpio = UInt32(txGpio)
|
||||
pc.gpsEnGpio = UInt32(gpsEnGpio)
|
||||
var pf: PositionFlags = []
|
||||
if includeAltitude { pf.insert(.Altitude) }
|
||||
if includeAltitudeMsl { pf.insert(.AltitudeMsl) }
|
||||
if includeGeoidalSeparation { pf.insert(.GeoidalSeparation) }
|
||||
if includeDop { pf.insert(.Dop) }
|
||||
if includeHvdop { pf.insert(.Hvdop) }
|
||||
if includeSatsinview { pf.insert(.Satsinview) }
|
||||
if includeSeqNo { pf.insert(.SeqNo) }
|
||||
if includeTimestamp { pf.insert(.Timestamp) }
|
||||
if includeSpeed { pf.insert(.Speed) }
|
||||
if includeHeading { pf.insert(.Heading) }
|
||||
pc.positionFlags = UInt32(pf.rawValue)
|
||||
let adminMessageId = bleManager.savePositionConfig(config: pc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Disable the button after a successful save
|
||||
hasChanges = false
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var setFixedAlertTitle: String {
|
||||
if node?.positionConfig?.fixedPosition == true {
|
||||
return "Remove Fixed Position"
|
||||
} else {
|
||||
return "Set Fixed Position"
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Form {
|
||||
ConfigHeader(title: "Position", config: \.positionConfig, node: node, onAppear: setPositionValues)
|
||||
|
||||
Section(header: Text("Position Packet")) {
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Picker("Broadcast Interval", selection: $positionBroadcastSeconds) {
|
||||
ForEach(UpdateIntervals.allCases) { at in
|
||||
if at.rawValue >= 300 {
|
||||
Text(at.description)
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Text("The maximum interval that can elapse without a node broadcasting a position")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
|
||||
Toggle(isOn: $smartPositionEnabled) {
|
||||
Label("Smart Position", systemImage: "brain")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
if smartPositionEnabled {
|
||||
VStack(alignment: .leading) {
|
||||
Picker("Minimum Interval", selection: $broadcastSmartMinimumIntervalSecs) {
|
||||
ForEach(UpdateIntervals.allCases) { at in
|
||||
Text(at.description)
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Text("The fastest that position updates will be sent if the minimum distance has been satisfied")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
VStack(alignment: .leading) {
|
||||
Picker("Minimum Distance", selection: $broadcastSmartMinimumDistance) {
|
||||
ForEach(10..<151) {
|
||||
if $0 == 0 {
|
||||
Text("unset")
|
||||
} else {
|
||||
if $0.isMultiple(of: 5) {
|
||||
Text("\($0)")
|
||||
.tag($0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Text("The minimum distance change in meters to be considered for a smart position broadcast.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
}
|
||||
}
|
||||
Section(header: Text("Device GPS")) {
|
||||
Picker("", selection: $gpsMode) {
|
||||
ForEach(GpsMode.allCases, id: \.self) { at in
|
||||
Text(at.description)
|
||||
.tag(at.id)
|
||||
}
|
||||
}
|
||||
.pickerStyle(SegmentedPickerStyle())
|
||||
.padding(.top, 5)
|
||||
.padding(.bottom, 5)
|
||||
if gpsMode == 1 {
|
||||
|
||||
Text("Positions will be provided by your device GPS, if you select disabled or not present you can set a fixed position.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
VStack(alignment: .leading) {
|
||||
Picker("Update Interval", selection: $gpsUpdateInterval) {
|
||||
ForEach(GpsUpdateIntervals.allCases) { ui in
|
||||
Text(ui.description)
|
||||
}
|
||||
}
|
||||
Text("How often should we try to get a GPS position.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
}
|
||||
if gpsMode != 1 && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? -1 {
|
||||
VStack(alignment: .leading) {
|
||||
Toggle(isOn: $fixedPosition) {
|
||||
Label("Fixed Position", systemImage: "location.square.fill")
|
||||
if !(node?.positionConfig?.fixedPosition ?? false) {
|
||||
Text("Your current location will be set as the fixed position and broadcast over the mesh on the position interval.")
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
}
|
||||
}
|
||||
Section(header: Text("Position Flags")) {
|
||||
|
||||
Text("Optional fields to include when assembling position messages. the more fields are included, the larger the message will be - leading to longer airtime and a higher risk of packet loss")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
|
||||
Toggle(isOn: $includeAltitude) {
|
||||
Label("Altitude", systemImage: "arrow.up")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
Toggle(isOn: $includeSatsinview) {
|
||||
Label("Number of satellites", systemImage: "skew")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
Toggle(isOn: $includeSeqNo) { // 64
|
||||
Label("Sequence number", systemImage: "number")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
Toggle(isOn: $includeTimestamp) { // 128
|
||||
Label("timestamp", systemImage: "clock")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
Toggle(isOn: $includeHeading) { // 128
|
||||
Label("Vehicle heading", systemImage: "location.circle")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
Toggle(isOn: $includeSpeed) { // 128
|
||||
|
||||
Label("Vehicle speed", systemImage: "speedometer")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
Section(header: Text("Advanced Position Flags")) {
|
||||
|
||||
if includeAltitude {
|
||||
Toggle(isOn: $includeAltitudeMsl) {
|
||||
Label("Altitude is Mean Sea Level", systemImage: "arrow.up.to.line.compact")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
Toggle(isOn: $includeGeoidalSeparation) {
|
||||
Label("Altitude Geoidal Separation", systemImage: "globe.americas")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
|
||||
Toggle(isOn: $includeDop) {
|
||||
Text("Dilution of precision (DOP) PDOP used by default")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
if includeDop {
|
||||
Toggle(isOn: $includeHvdop) {
|
||||
Text("If DOP is set use, HDOP / VDOP values instead of PDOP")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
}
|
||||
|
||||
positionPacketSection
|
||||
deviceGPSSection
|
||||
positionFlagsSection
|
||||
advancedPositionFlagsSection
|
||||
if gpsMode == 1 {
|
||||
Section(header: Text("Advanced Device GPS")) {
|
||||
Picker("GPS Receive GPIO", selection: $rxGpio) {
|
||||
ForEach(0..<49) {
|
||||
if $0 == 0 {
|
||||
Text("unset")
|
||||
} else {
|
||||
Text("Pin \($0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Picker("GPS Transmit GPIO", selection: $txGpio) {
|
||||
ForEach(0..<49) {
|
||||
if $0 == 0 {
|
||||
Text("unset")
|
||||
} else {
|
||||
Text("Pin \($0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Picker("GPS EN GPIO", selection: $gpsEnGpio) {
|
||||
ForEach(0..<49) {
|
||||
if $0 == 0 {
|
||||
Text("unset")
|
||||
} else {
|
||||
Text("Pin \($0)")
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
Text("(Re)define PIN_GPS_EN for your board.")
|
||||
.font(.caption)
|
||||
}
|
||||
advancedDeviceGPSSection
|
||||
}
|
||||
}
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.positionConfig == nil)
|
||||
.alert(node?.positionConfig?.fixedPosition ?? false ? "Remove Fixed Position" : "Set Fixed Position", isPresented: $showingSetFixedAlert) {
|
||||
.alert(setFixedAlertTitle, isPresented: $showingSetFixedAlert) {
|
||||
Button("Cancel", role: .cancel) {
|
||||
fixedPosition = !fixedPosition
|
||||
}
|
||||
if node?.positionConfig?.fixedPosition ?? false {
|
||||
Button("Remove", role: .destructive) {
|
||||
if !bleManager.removeFixedPosition(fromUser: node!.user!, channel: 0) {
|
||||
Logger.mesh.error("Remove Fixed Position Failed")
|
||||
}
|
||||
let mutablePositions = node?.positions?.mutableCopy() as? NSMutableOrderedSet
|
||||
mutablePositions?.removeAllObjects()
|
||||
node?.positions = mutablePositions
|
||||
node?.positionConfig?.fixedPosition = false
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Position Config with Fixed Position = false")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving Position Config Entity \(nsError)")
|
||||
}
|
||||
removeFixedPosition()
|
||||
}
|
||||
} else {
|
||||
Button("Set") {
|
||||
if !bleManager.setFixedPosition(fromUser: node!.user!, channel: 0) {
|
||||
Logger.mesh.error("Set Position Failed")
|
||||
}
|
||||
node?.positionConfig?.fixedPosition = true
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Position Config with Fixed Position = true")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving Position Config Entity \(nsError)")
|
||||
}
|
||||
setFixedPosition()
|
||||
}
|
||||
}
|
||||
} message: {
|
||||
Text(node?.positionConfig?.fixedPosition ?? false ? "This will disable fixed position and remove the currently set position." : "This will send a current position from your phone and enable fixed position.")
|
||||
}
|
||||
|
||||
SaveConfigButton(node: node, hasChanges: $hasChanges) {
|
||||
if fixedPosition && !supportedVersion {
|
||||
_ = bleManager.sendPosition(channel: 0, destNum: node?.num ?? 0, wantResponse: true)
|
||||
}
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
|
||||
if connectedNode != nil {
|
||||
var pc = Config.PositionConfig()
|
||||
pc.positionBroadcastSmartEnabled = smartPositionEnabled
|
||||
pc.gpsEnabled = gpsMode == 1
|
||||
pc.gpsMode = Config.PositionConfig.GpsMode(rawValue: gpsMode) ?? Config.PositionConfig.GpsMode.notPresent
|
||||
pc.fixedPosition = fixedPosition
|
||||
pc.gpsUpdateInterval = UInt32(gpsUpdateInterval)
|
||||
pc.positionBroadcastSecs = UInt32(positionBroadcastSeconds)
|
||||
pc.broadcastSmartMinimumIntervalSecs = UInt32(broadcastSmartMinimumIntervalSecs)
|
||||
pc.broadcastSmartMinimumDistance = UInt32(broadcastSmartMinimumDistance)
|
||||
pc.rxGpio = UInt32(rxGpio)
|
||||
pc.txGpio = UInt32(txGpio)
|
||||
pc.gpsEnGpio = UInt32(gpsEnGpio)
|
||||
var pf: PositionFlags = []
|
||||
if includeAltitude { pf.insert(.Altitude) }
|
||||
if includeAltitudeMsl { pf.insert(.AltitudeMsl) }
|
||||
if includeGeoidalSeparation { pf.insert(.GeoidalSeparation) }
|
||||
if includeDop { pf.insert(.Dop) }
|
||||
if includeHvdop { pf.insert(.Hvdop) }
|
||||
if includeSatsinview { pf.insert(.Satsinview) }
|
||||
if includeSeqNo { pf.insert(.SeqNo) }
|
||||
if includeTimestamp { pf.insert(.Timestamp) }
|
||||
if includeSpeed { pf.insert(.Speed) }
|
||||
if includeHeading { pf.insert(.Heading) }
|
||||
pc.positionFlags = UInt32(pf.rawValue)
|
||||
let adminMessageId = bleManager.savePositionConfig(config: pc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Disable the button after a successful save
|
||||
hasChanges = false
|
||||
goBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
saveButton
|
||||
}
|
||||
.navigationTitle("position.config")
|
||||
.navigationBarItems(trailing:
|
||||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
|
||||
})
|
||||
.navigationBarItems(
|
||||
trailing: ZStack {
|
||||
ConnectedDevice(
|
||||
bluetoothOn: bleManager.isSwitchedOn,
|
||||
deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
name: bleManager.connectedPeripheral?.shortName ?? "?"
|
||||
)
|
||||
}
|
||||
)
|
||||
.onAppear {
|
||||
if self.bleManager.context == nil {
|
||||
self.bleManager.context = context
|
||||
|
|
@ -374,133 +383,88 @@ struct PositionConfig: View {
|
|||
setPositionValues()
|
||||
supportedVersion = bleManager.connectedVersion == "0.0.0" || self.minimumVersion.compare(bleManager.connectedVersion, options: .numeric) == .orderedAscending || minimumVersion.compare(bleManager.connectedVersion, options: .numeric) == .orderedSame
|
||||
// Need to request a PositionConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.positionConfig == nil {
|
||||
if let connectedPeripheral = bleManager.connectedPeripheral, node?.positionConfig == nil {
|
||||
Logger.mesh.info("empty position config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if node != nil && connectedNode != nil {
|
||||
_ = bleManager.requestPositionConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
|
||||
if let node, let connectedNode {
|
||||
_ = bleManager.requestPositionConfig(
|
||||
fromUser: connectedNode.user!,
|
||||
toUser: node.user!,
|
||||
adminIndex: connectedNode.myInfo?.adminIndex ?? 0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: fixedPosition) { newFixed in
|
||||
if supportedVersion {
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
if let positionConfig = node?.positionConfig {
|
||||
/// Fixed Position is off to start
|
||||
if !node!.positionConfig!.fixedPosition && newFixed {
|
||||
if !positionConfig.fixedPosition && newFixed {
|
||||
showingSetFixedAlert = true
|
||||
} else if node!.positionConfig!.fixedPosition && !newFixed {
|
||||
} else if positionConfig.fixedPosition && !newFixed {
|
||||
/// Fixed Position is on to start
|
||||
showingSetFixedAlert = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: deviceGpsEnabled) { newDeviceGps in
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
if newDeviceGps != node!.positionConfig!.deviceGpsEnabled { hasChanges = true }
|
||||
}
|
||||
.onChange(of: gpsMode) { _ in
|
||||
handleChanges()
|
||||
}
|
||||
.onChange(of: gpsMode) { newGpsMode in
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
if newGpsMode != node!.positionConfig!.gpsMode { hasChanges = true }
|
||||
}
|
||||
.onChange(of: rxGpio) { _ in
|
||||
handleChanges()
|
||||
}
|
||||
.onChange(of: rxGpio) { newRxGpio in
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
if newRxGpio != node!.positionConfig!.rxGpio { hasChanges = true }
|
||||
}
|
||||
.onChange(of: txGpio) { _ in
|
||||
handleChanges()
|
||||
}
|
||||
.onChange(of: txGpio) { newTxGpio in
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
if newTxGpio != node!.positionConfig!.txGpio { hasChanges = true }
|
||||
}
|
||||
.onChange(of: gpsEnGpio) { _ in
|
||||
handleChanges()
|
||||
}
|
||||
.onChange(of: txGpio) { newGpsEnGpio in
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
if newGpsEnGpio != node!.positionConfig!.gpsEnGpio { hasChanges = true }
|
||||
}
|
||||
.onChange(of: smartPositionEnabled) { _ in
|
||||
handleChanges()
|
||||
}
|
||||
.onChange(of: smartPositionEnabled) { newSmartPositionEnabled in
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
if newSmartPositionEnabled != node!.positionConfig!.smartPositionEnabled { hasChanges = true }
|
||||
}
|
||||
.onChange(of: positionBroadcastSeconds) { _ in
|
||||
handleChanges()
|
||||
}
|
||||
.onChange(of: positionBroadcastSeconds) { newPositionBroadcastSeconds in
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
if newPositionBroadcastSeconds != node!.positionConfig!.positionBroadcastSeconds { hasChanges = true }
|
||||
}
|
||||
.onChange(of: broadcastSmartMinimumIntervalSecs) { _ in
|
||||
handleChanges()
|
||||
}
|
||||
.onChange(of: broadcastSmartMinimumIntervalSecs) { newBroadcastSmartMinimumIntervalSecs in
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
if newBroadcastSmartMinimumIntervalSecs != node!.positionConfig!.broadcastSmartMinimumIntervalSecs { hasChanges = true }
|
||||
}
|
||||
.onChange(of: broadcastSmartMinimumDistance) { _ in
|
||||
handleChanges()
|
||||
}
|
||||
.onChange(of: broadcastSmartMinimumDistance) { newBroadcastSmartMinimumDistance in
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
if newBroadcastSmartMinimumDistance != node!.positionConfig!.broadcastSmartMinimumDistance { hasChanges = true }
|
||||
}
|
||||
.onChange(of: gpsUpdateInterval) { _ in
|
||||
handleChanges()
|
||||
}
|
||||
.onChange(of: gpsUpdateInterval) { newGpsUpdateInterval in
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
if newGpsUpdateInterval != node!.positionConfig!.gpsUpdateInterval { hasChanges = true }
|
||||
}
|
||||
}
|
||||
.onChange(of: includeAltitude) { altFlag in
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
let existingValue = pf.contains(.Altitude)
|
||||
if existingValue != altFlag { hasChanges = true }
|
||||
}
|
||||
.onChange(of: includeAltitudeMsl) { altMslFlag in
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
let existingValue = pf.contains(.AltitudeMsl)
|
||||
if existingValue != altMslFlag { hasChanges = true }
|
||||
}
|
||||
.onChange(of: includeSatsinview) { satsFlag in
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
let existingValue = pf.contains(.Satsinview)
|
||||
if existingValue != satsFlag { hasChanges = true }
|
||||
}
|
||||
.onChange(of: includeSeqNo) { seqFlag in
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
let existingValue = pf.contains(.SeqNo)
|
||||
if existingValue != seqFlag { hasChanges = true }
|
||||
}
|
||||
.onChange(of: includeTimestamp) { timestampFlag in
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
let existingValue = pf.contains(.Timestamp)
|
||||
if existingValue != timestampFlag { hasChanges = true }
|
||||
}
|
||||
.onChange(of: includeTimestamp) { timestampFlag in
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
let existingValue = pf.contains(.Timestamp)
|
||||
if existingValue != timestampFlag { hasChanges = true }
|
||||
}
|
||||
.onChange(of: includeSpeed) { speedFlag in
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
let existingValue = pf.contains(.Speed)
|
||||
if existingValue != speedFlag { hasChanges = true }
|
||||
}
|
||||
.onChange(of: includeHeading) { headingFlag in
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
let existingValue = pf.contains(.Heading)
|
||||
if existingValue != headingFlag { hasChanges = true }
|
||||
}
|
||||
.onChange(of: includeGeoidalSeparation) { geoSepFlag in
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
let existingValue = pf.contains(.GeoidalSeparation)
|
||||
if existingValue != geoSepFlag { hasChanges = true }
|
||||
}
|
||||
.onChange(of: includeDop) { dopFlag in
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
let existingValue = pf.contains(.Dop)
|
||||
if existingValue != dopFlag { hasChanges = true }
|
||||
}
|
||||
.onChange(of: includeHvdop) { hvdopFlag in
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
let existingValue = pf.contains(.Hvdop)
|
||||
if existingValue != hvdopFlag { hasChanges = true }
|
||||
.onChange(of: positionFlags) { _ in
|
||||
handleChanges()
|
||||
}
|
||||
}
|
||||
|
||||
func handleChanges() {
|
||||
guard let positionConfig = node?.positionConfig else { return }
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
hasChanges = positionConfig.deviceGpsEnabled != deviceGpsEnabled ||
|
||||
positionConfig.gpsMode != gpsMode ||
|
||||
positionConfig.rxGpio != rxGpio ||
|
||||
positionConfig.txGpio != txGpio ||
|
||||
positionConfig.gpsEnGpio != gpsEnGpio ||
|
||||
positionConfig.smartPositionEnabled != smartPositionEnabled ||
|
||||
positionConfig.positionBroadcastSeconds != positionBroadcastSeconds ||
|
||||
positionConfig.broadcastSmartMinimumIntervalSecs != broadcastSmartMinimumIntervalSecs ||
|
||||
positionConfig.broadcastSmartMinimumDistance != broadcastSmartMinimumDistance ||
|
||||
positionConfig.gpsUpdateInterval != gpsUpdateInterval ||
|
||||
pf.contains(.Altitude) ||
|
||||
pf.contains(.AltitudeMsl) ||
|
||||
pf.contains(.Satsinview) ||
|
||||
pf.contains(.SeqNo) ||
|
||||
pf.contains(.Timestamp) ||
|
||||
pf.contains(.Speed) ||
|
||||
pf.contains(.Heading) ||
|
||||
pf.contains(.GeoidalSeparation) ||
|
||||
pf.contains(.Dop) ||
|
||||
pf.contains(.Hvdop)
|
||||
}
|
||||
|
||||
func setPositionValues() {
|
||||
self.smartPositionEnabled = node?.positionConfig?.smartPositionEnabled ?? true
|
||||
self.deviceGpsEnabled = node?.positionConfig?.deviceGpsEnabled ?? false
|
||||
|
|
@ -517,19 +481,54 @@ struct PositionConfig: View {
|
|||
self.broadcastSmartMinimumIntervalSecs = Int(node?.positionConfig?.broadcastSmartMinimumIntervalSecs ?? 30)
|
||||
self.broadcastSmartMinimumDistance = Int(node?.positionConfig?.broadcastSmartMinimumDistance ?? 50)
|
||||
self.positionFlags = Int(node?.positionConfig?.positionFlags ?? 3)
|
||||
|
||||
let pf = PositionFlags(rawValue: self.positionFlags)
|
||||
if pf.contains(.Altitude) { self.includeAltitude = true } else { self.includeAltitude = false }
|
||||
if pf.contains(.AltitudeMsl) { self.includeAltitudeMsl = true } else { self.includeAltitudeMsl = false }
|
||||
if pf.contains(.GeoidalSeparation) { self.includeGeoidalSeparation = true } else { self.includeGeoidalSeparation = false }
|
||||
if pf.contains(.Dop) { self.includeDop = true } else { self.includeDop = false }
|
||||
if pf.contains(.Hvdop) { self.includeHvdop = true } else { self.includeHvdop = false }
|
||||
if pf.contains(.Satsinview) { self.includeSatsinview = true } else { self.includeSatsinview = false }
|
||||
if pf.contains(.SeqNo) { self.includeSeqNo = true } else { self.includeSeqNo = false }
|
||||
if pf.contains(.Timestamp) { self.includeTimestamp = true } else { self.includeTimestamp = false }
|
||||
if pf.contains(.Speed) { self.includeSpeed = true } else { self.includeSpeed = false }
|
||||
if pf.contains(.Heading) { self.includeHeading = true } else { self.includeHeading = false }
|
||||
|
||||
self.includeAltitude = pf.contains(.Altitude)
|
||||
self.includeAltitudeMsl = pf.contains(.AltitudeMsl)
|
||||
self.includeGeoidalSeparation = pf.contains(.GeoidalSeparation)
|
||||
self.includeDop = pf.contains(.Dop)
|
||||
self.includeHvdop = pf.contains(.Hvdop)
|
||||
self.includeSatsinview = pf.contains(.Satsinview)
|
||||
self.includeSeqNo = pf.contains(.SeqNo)
|
||||
self.includeTimestamp = pf.contains(.Timestamp)
|
||||
self.includeSpeed = pf.contains(.Speed)
|
||||
self.includeHeading = pf.contains(.Heading)
|
||||
self.hasChanges = false
|
||||
}
|
||||
|
||||
private func setFixedPosition() {
|
||||
guard let nodeNum = bleManager.connectedPeripheral?.num,
|
||||
nodeNum > 0 else { return }
|
||||
if !bleManager.setFixedPosition(fromUser: node!.user!, channel: 0) {
|
||||
Logger.mesh.error("Set Position Failed")
|
||||
}
|
||||
node?.positionConfig?.fixedPosition = true
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Position Config with Fixed Position = true")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving Position Config Entity \(nsError)")
|
||||
}
|
||||
}
|
||||
|
||||
private func removeFixedPosition() {
|
||||
guard let nodeNum = bleManager.connectedPeripheral?.num,
|
||||
nodeNum > 0 else { return }
|
||||
if !bleManager.removeFixedPosition(fromUser: node!.user!, channel: 0) {
|
||||
Logger.mesh.error("Remove Fixed Position Failed")
|
||||
}
|
||||
let mutablePositions = node?.positions?.mutableCopy() as? NSMutableOrderedSet
|
||||
mutablePositions?.removeAllObjects()
|
||||
node?.positions = mutablePositions
|
||||
node?.positionConfig?.fixedPosition = false
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 Updated Position Config with Fixed Position = false")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("Error Saving Position Config Entity \(nsError)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import SwiftUI
|
||||
import MeshtasticProtobufs
|
||||
|
||||
struct PowerConfig: View {
|
||||
@Environment(\.managedObjectContext) private var context
|
||||
|
|
|
|||
134
Meshtastic/Views/Settings/Logs/AppLogFilter.swift
Normal file
134
Meshtastic/Views/Settings/Logs/AppLogFilter.swift
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
//
|
||||
// AppLogFilter.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Created by Garth Vander Houwen on 6/15/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
enum LogCategories: Int, CaseIterable, Identifiable {
|
||||
|
||||
case admin = 0
|
||||
case data = 1
|
||||
case mesh = 2
|
||||
case mqtt = 3
|
||||
case radio = 4
|
||||
case services = 5
|
||||
case stats = 6
|
||||
|
||||
var id: Int { self.rawValue }
|
||||
var description: String {
|
||||
switch self {
|
||||
|
||||
case .admin:
|
||||
return "🏛 Admin"
|
||||
case .data:
|
||||
return "🗄️ Data"
|
||||
case .mesh:
|
||||
return "🕸️ Mesh"
|
||||
case .mqtt:
|
||||
return "📱 MQTT"
|
||||
case .radio:
|
||||
return "📟 Radio"
|
||||
case .services:
|
||||
return "🍏 Services"
|
||||
case .stats:
|
||||
return "📊 Stats"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum LogLevels: Int, CaseIterable, Identifiable {
|
||||
|
||||
case debug = 0
|
||||
case info = 1
|
||||
case notice = 2
|
||||
case error = 3
|
||||
case fault = 4
|
||||
|
||||
var id: Int { self.rawValue }
|
||||
var level: String {
|
||||
switch self {
|
||||
case .debug:
|
||||
return "debug"
|
||||
case .info:
|
||||
return "info"
|
||||
case .notice:
|
||||
return "notice"
|
||||
case .error:
|
||||
return "error"
|
||||
case .fault:
|
||||
return "fault"
|
||||
}
|
||||
}
|
||||
var description: String {
|
||||
switch self {
|
||||
case .debug:
|
||||
return "🪲 Debug"
|
||||
case .info:
|
||||
return "ℹ️ Info"
|
||||
case .notice:
|
||||
return "⚠️ Notice"
|
||||
case .error:
|
||||
return "🚨 Error"
|
||||
case .fault:
|
||||
return "💥 Fault"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AppLogFilter: View {
|
||||
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
/// Filters
|
||||
var filterTitle = "App Log Filters"
|
||||
@Binding var categories: Set<Int>
|
||||
@Binding var levels: Set<Int>
|
||||
@State var editMode = EditMode.active /// the edit mode
|
||||
|
||||
var body: some View {
|
||||
|
||||
NavigationStack {
|
||||
Form {
|
||||
Section(header: Text("Categories")) {
|
||||
VStack {
|
||||
List(LogCategories.allCases, selection: $categories) { cat in
|
||||
Text(cat.description)
|
||||
}
|
||||
.listStyle(.plain)
|
||||
.environment(\.editMode, $editMode) /// bind it here!
|
||||
.frame(minHeight: 300, maxHeight: .infinity)
|
||||
}
|
||||
}
|
||||
Section(header: Text("Log Levels")) {
|
||||
VStack {
|
||||
List(LogLevels.allCases, selection: $levels) { level in
|
||||
Text(level.description)
|
||||
}
|
||||
.listStyle(.plain)
|
||||
.environment(\.editMode, $editMode) /// bind it here!
|
||||
.frame(minHeight: 210, maxHeight: .infinity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if targetEnvironment(macCatalyst)
|
||||
Spacer()
|
||||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Label("close", systemImage: "xmark")
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
.padding(.bottom)
|
||||
#endif
|
||||
}
|
||||
.presentationDetents([.fraction(1.0)])
|
||||
.presentationDragIndicator(.visible)
|
||||
}
|
||||
}
|
||||
154
Meshtastic/Views/Settings/Logs/LogDetail.swift
Normal file
154
Meshtastic/Views/Settings/Logs/LogDetail.swift
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
//
|
||||
// LogDetail.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Copyright(c) Garth Vander Houwen 6/5/24.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MapKit
|
||||
import OSLog
|
||||
|
||||
struct LogDetail: View {
|
||||
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
|
||||
var log: OSLogEntryLog
|
||||
var font: Font = .title2
|
||||
private let dateFormatStyle = Date.FormatStyle()
|
||||
.day(.defaultDigits)
|
||||
.month(.defaultDigits)
|
||||
.year(.twoDigits)
|
||||
.hour(.twoDigits(amPM: .omitted))
|
||||
.minute()
|
||||
.second()
|
||||
.secondFraction(.fractional(3))
|
||||
|
||||
var body: some View {
|
||||
|
||||
VStack {
|
||||
HStack {
|
||||
Text("OS Log Entry Details")
|
||||
.font(.largeTitle)
|
||||
}
|
||||
Divider()
|
||||
HStack(alignment: .top) {
|
||||
VStack(alignment: .leading) {
|
||||
List {
|
||||
/// Time
|
||||
Label {
|
||||
Text("log.time".localized + ":")
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
.frame(width: idiom == .phone ? 115 : 190, alignment: .trailing)
|
||||
Text(log.date.formatted(dateFormatStyle))
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
} icon: {
|
||||
Image(systemName: "timer")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(idiom == .phone ? .callout : .title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
.listSectionSeparator(.hidden, edges: .top)
|
||||
.listSectionSeparator(.visible, edges: .bottom)
|
||||
/// Subsystem
|
||||
Label {
|
||||
Text("log.subsystem".localized + ":")
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
.frame(width: idiom == .phone ? 115 : 190, alignment: .trailing)
|
||||
Text(log.subsystem)
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
} icon: {
|
||||
Image(systemName: "gear")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
.listRowSeparator(.visible)
|
||||
/// Process
|
||||
Label {
|
||||
Text("log.process".localized + ":")
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
.frame(width: idiom == .phone ? 115 : 190, alignment: .trailing)
|
||||
Text(log.process)
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
} icon: {
|
||||
Image(systemName: "tag")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
.listRowSeparator(.visible)
|
||||
/// Category
|
||||
Label {
|
||||
Text("log.category".localized + ":")
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
.frame(width: idiom == .phone ? 115 : 190, alignment: .trailing)
|
||||
Text(log.category)
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
} icon: {
|
||||
Image(systemName: "square.grid.2x2")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
.listRowSeparator(.visible)
|
||||
/// Level
|
||||
Label {
|
||||
Text("log.level".localized + ":")
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
.frame(width: idiom == .phone ? 115 : 190, alignment: .trailing)
|
||||
Text(log.level.description)
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
} icon: {
|
||||
Image(systemName: "stairs")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
.listRowSeparator(.visible)
|
||||
/// message
|
||||
Label {
|
||||
Text("log.message".localized + ":")
|
||||
.font(idiom == .phone ? .caption : .title)
|
||||
.frame(width: idiom == .phone ? 115 : 190, alignment: .trailing)
|
||||
Text(log.composedMessage)
|
||||
.textSelection(.enabled)
|
||||
.font(idiom == .phone ? .body : .title)
|
||||
.padding(.bottom, 5)
|
||||
} icon: {
|
||||
Image(systemName: "text.bubble")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(idiom == .phone ? .callout : .title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.listRowSeparator(.hidden)
|
||||
|
||||
}
|
||||
.listStyle(.plain)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.top)
|
||||
#if targetEnvironment(macCatalyst)
|
||||
Spacer()
|
||||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Label("close", systemImage: "xmark")
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
.padding(.bottom)
|
||||
#endif
|
||||
}
|
||||
.monospaced()
|
||||
.presentationDetents([.fraction(0.75), .fraction(0.85), .fraction(1.0)])
|
||||
.presentationDragIndicator(.visible)
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ struct MeshLog: View {
|
|||
let url = logFile!
|
||||
logs.removeAll()
|
||||
var lineCount = 0
|
||||
let lineLimit = 5000
|
||||
let lineLimit = 1000
|
||||
// Get the number of lines
|
||||
for try await _ in url.lines {
|
||||
lineCount += 1
|
||||
|
|
@ -41,6 +41,7 @@ struct MeshLog: View {
|
|||
// Stop adding logs when an error is thrown
|
||||
}
|
||||
}
|
||||
.listStyle(.plain)
|
||||
.fileExporter(
|
||||
isPresented: $isExporting,
|
||||
document: document,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ struct Settings: View {
|
|||
case meshLog
|
||||
case adminMessageLog
|
||||
case about
|
||||
case appLog
|
||||
case appData
|
||||
}
|
||||
var body: some View {
|
||||
NavigationSplitView {
|
||||
|
|
@ -412,18 +414,33 @@ struct Settings: View {
|
|||
}
|
||||
}
|
||||
.tag(SettingsSidebar.meshLog)
|
||||
if #available (iOS 17.4, *) {
|
||||
NavigationLink {
|
||||
AppLog()
|
||||
} label: {
|
||||
Label {
|
||||
Text("Debug Logs")
|
||||
} icon: {
|
||||
Image(systemName: "stethoscope")
|
||||
}
|
||||
}
|
||||
.tag(SettingsSidebar.appLog)
|
||||
}
|
||||
}
|
||||
#if DEBUG
|
||||
Section(header: Text("Developers")) {
|
||||
NavigationLink {
|
||||
let connectedNode = nodes.first(where: { $0.num == preferredNodeNum })
|
||||
AdminMessageList(user: connectedNode?.user)
|
||||
AppData()
|
||||
} label: {
|
||||
Label {
|
||||
Text("admin.log")
|
||||
Text("App Files")
|
||||
} icon: {
|
||||
Image(systemName: "building.columns")
|
||||
Image(systemName: "folder")
|
||||
}
|
||||
}
|
||||
.tag(SettingsSidebar.adminMessageLog)
|
||||
.tag(SettingsSidebar.appData)
|
||||
}
|
||||
#endif
|
||||
Section(header: Text("Firmware")) {
|
||||
NavigationLink {
|
||||
Firmware(node: nodes.first(where: { $0.num == preferredNodeNum }))
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
import SwiftUI
|
||||
import CoreData
|
||||
import CoreImage.CIFilterBuiltins
|
||||
import MeshtasticProtobufs
|
||||
|
||||
#if canImport(TipKit)
|
||||
import TipKit
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
//
|
||||
// Copyright (c) Garth Vander Houwen 6/27/22.
|
||||
//
|
||||
import SwiftUI
|
||||
import CoreData
|
||||
import MeshtasticProtobufs
|
||||
import SwiftUI
|
||||
|
||||
struct UserConfig: View {
|
||||
|
||||
|
|
@ -51,7 +52,7 @@ struct UserConfig: View {
|
|||
.onChange(of: longName, perform: { _ in
|
||||
let totalBytes = longName.utf8.count
|
||||
// Only mess with the value if it is too big
|
||||
if totalBytes > (isLicensed ? 8 : 36) {
|
||||
if totalBytes > (isLicensed ? 6 : 36) {
|
||||
longName = String(longName.dropLast())
|
||||
}
|
||||
})
|
||||
|
|
|
|||
8
MeshtasticProtobufs/.gitignore
vendored
Normal file
8
MeshtasticProtobufs/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
.DS_Store
|
||||
/.build
|
||||
/Packages
|
||||
xcuserdata/
|
||||
DerivedData/
|
||||
.swiftpm/configuration/registries.json
|
||||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
|
||||
.netrc
|
||||
24
MeshtasticProtobufs/Package.swift
Normal file
24
MeshtasticProtobufs/Package.swift
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// swift-tools-version: 5.10
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "MeshtasticProtobufs",
|
||||
products: [
|
||||
.library(
|
||||
name: "MeshtasticProtobufs",
|
||||
targets: ["MeshtasticProtobufs"]
|
||||
),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.19.0"),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "MeshtasticProtobufs",
|
||||
dependencies: [
|
||||
.product(name: "SwiftProtobuf", package: "swift-protobuf")
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
@ -24,19 +24,19 @@ 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)
|
||||
struct AdminMessage {
|
||||
public struct AdminMessage {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
var payloadVariant: AdminMessage.OneOf_PayloadVariant? = nil
|
||||
public var payloadVariant: AdminMessage.OneOf_PayloadVariant? = nil
|
||||
|
||||
///
|
||||
/// 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)
|
||||
var getChannelRequest: UInt32 {
|
||||
public var getChannelRequest: UInt32 {
|
||||
get {
|
||||
if case .getChannelRequest(let v)? = payloadVariant {return v}
|
||||
return 0
|
||||
|
|
@ -46,7 +46,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
var getChannelResponse: Channel {
|
||||
public var getChannelResponse: Channel {
|
||||
get {
|
||||
if case .getChannelResponse(let v)? = payloadVariant {return v}
|
||||
return Channel()
|
||||
|
|
@ -56,7 +56,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Send the current owner data in the response to this message.
|
||||
var getOwnerRequest: Bool {
|
||||
public var getOwnerRequest: Bool {
|
||||
get {
|
||||
if case .getOwnerRequest(let v)? = payloadVariant {return v}
|
||||
return false
|
||||
|
|
@ -66,7 +66,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
var getOwnerResponse: User {
|
||||
public var getOwnerResponse: User {
|
||||
get {
|
||||
if case .getOwnerResponse(let v)? = payloadVariant {return v}
|
||||
return User()
|
||||
|
|
@ -76,7 +76,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Ask for the following config data to be sent
|
||||
var getConfigRequest: AdminMessage.ConfigType {
|
||||
public var getConfigRequest: AdminMessage.ConfigType {
|
||||
get {
|
||||
if case .getConfigRequest(let v)? = payloadVariant {return v}
|
||||
return .deviceConfig
|
||||
|
|
@ -86,7 +86,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Send the current Config in the response to this message.
|
||||
var getConfigResponse: Config {
|
||||
public var getConfigResponse: Config {
|
||||
get {
|
||||
if case .getConfigResponse(let v)? = payloadVariant {return v}
|
||||
return Config()
|
||||
|
|
@ -96,7 +96,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Ask for the following config data to be sent
|
||||
var getModuleConfigRequest: AdminMessage.ModuleConfigType {
|
||||
public var getModuleConfigRequest: AdminMessage.ModuleConfigType {
|
||||
get {
|
||||
if case .getModuleConfigRequest(let v)? = payloadVariant {return v}
|
||||
return .mqttConfig
|
||||
|
|
@ -106,7 +106,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Send the current Config in the response to this message.
|
||||
var getModuleConfigResponse: ModuleConfig {
|
||||
public var getModuleConfigResponse: ModuleConfig {
|
||||
get {
|
||||
if case .getModuleConfigResponse(let v)? = payloadVariant {return v}
|
||||
return ModuleConfig()
|
||||
|
|
@ -116,7 +116,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Get the Canned Message Module messages in the response to this message.
|
||||
var getCannedMessageModuleMessagesRequest: Bool {
|
||||
public var getCannedMessageModuleMessagesRequest: Bool {
|
||||
get {
|
||||
if case .getCannedMessageModuleMessagesRequest(let v)? = payloadVariant {return v}
|
||||
return false
|
||||
|
|
@ -126,7 +126,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Get the Canned Message Module messages in the response to this message.
|
||||
var getCannedMessageModuleMessagesResponse: String {
|
||||
public var getCannedMessageModuleMessagesResponse: String {
|
||||
get {
|
||||
if case .getCannedMessageModuleMessagesResponse(let v)? = payloadVariant {return v}
|
||||
return String()
|
||||
|
|
@ -136,7 +136,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Request the node to send device metadata (firmware, protobuf version, etc)
|
||||
var getDeviceMetadataRequest: Bool {
|
||||
public var getDeviceMetadataRequest: Bool {
|
||||
get {
|
||||
if case .getDeviceMetadataRequest(let v)? = payloadVariant {return v}
|
||||
return false
|
||||
|
|
@ -146,7 +146,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Device metadata response
|
||||
var getDeviceMetadataResponse: DeviceMetadata {
|
||||
public var getDeviceMetadataResponse: DeviceMetadata {
|
||||
get {
|
||||
if case .getDeviceMetadataResponse(let v)? = payloadVariant {return v}
|
||||
return DeviceMetadata()
|
||||
|
|
@ -156,7 +156,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Get the Ringtone in the response to this message.
|
||||
var getRingtoneRequest: Bool {
|
||||
public var getRingtoneRequest: Bool {
|
||||
get {
|
||||
if case .getRingtoneRequest(let v)? = payloadVariant {return v}
|
||||
return false
|
||||
|
|
@ -166,7 +166,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Get the Ringtone in the response to this message.
|
||||
var getRingtoneResponse: String {
|
||||
public var getRingtoneResponse: String {
|
||||
get {
|
||||
if case .getRingtoneResponse(let v)? = payloadVariant {return v}
|
||||
return String()
|
||||
|
|
@ -176,7 +176,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Request the node to send it's connection status
|
||||
var getDeviceConnectionStatusRequest: Bool {
|
||||
public var getDeviceConnectionStatusRequest: Bool {
|
||||
get {
|
||||
if case .getDeviceConnectionStatusRequest(let v)? = payloadVariant {return v}
|
||||
return false
|
||||
|
|
@ -186,7 +186,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Device connection status response
|
||||
var getDeviceConnectionStatusResponse: DeviceConnectionStatus {
|
||||
public var getDeviceConnectionStatusResponse: DeviceConnectionStatus {
|
||||
get {
|
||||
if case .getDeviceConnectionStatusResponse(let v)? = payloadVariant {return v}
|
||||
return DeviceConnectionStatus()
|
||||
|
|
@ -196,7 +196,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Setup a node for licensed amateur (ham) radio operation
|
||||
var setHamMode: HamParameters {
|
||||
public var setHamMode: HamParameters {
|
||||
get {
|
||||
if case .setHamMode(let v)? = payloadVariant {return v}
|
||||
return HamParameters()
|
||||
|
|
@ -206,7 +206,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Get the mesh's nodes with their available gpio pins for RemoteHardware module use
|
||||
var getNodeRemoteHardwarePinsRequest: Bool {
|
||||
public var getNodeRemoteHardwarePinsRequest: Bool {
|
||||
get {
|
||||
if case .getNodeRemoteHardwarePinsRequest(let v)? = payloadVariant {return v}
|
||||
return false
|
||||
|
|
@ -216,7 +216,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Respond with the mesh's nodes with their available gpio pins for RemoteHardware module use
|
||||
var getNodeRemoteHardwarePinsResponse: NodeRemoteHardwarePinsResponse {
|
||||
public var getNodeRemoteHardwarePinsResponse: NodeRemoteHardwarePinsResponse {
|
||||
get {
|
||||
if case .getNodeRemoteHardwarePinsResponse(let v)? = payloadVariant {return v}
|
||||
return NodeRemoteHardwarePinsResponse()
|
||||
|
|
@ -227,7 +227,7 @@ struct AdminMessage {
|
|||
///
|
||||
/// Enter (UF2) DFU mode
|
||||
/// Only implemented on NRF52 currently
|
||||
var enterDfuModeRequest: Bool {
|
||||
public var enterDfuModeRequest: Bool {
|
||||
get {
|
||||
if case .enterDfuModeRequest(let v)? = payloadVariant {return v}
|
||||
return false
|
||||
|
|
@ -237,7 +237,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Delete the file by the specified path from the device
|
||||
var deleteFileRequest: String {
|
||||
public var deleteFileRequest: String {
|
||||
get {
|
||||
if case .deleteFileRequest(let v)? = payloadVariant {return v}
|
||||
return String()
|
||||
|
|
@ -245,9 +245,19 @@ struct AdminMessage {
|
|||
set {payloadVariant = .deleteFileRequest(newValue)}
|
||||
}
|
||||
|
||||
///
|
||||
/// Set zero and offset for scale chips
|
||||
public var setScale: UInt32 {
|
||||
get {
|
||||
if case .setScale(let v)? = payloadVariant {return v}
|
||||
return 0
|
||||
}
|
||||
set {payloadVariant = .setScale(newValue)}
|
||||
}
|
||||
|
||||
///
|
||||
/// Set the owner for this node
|
||||
var setOwner: User {
|
||||
public var setOwner: User {
|
||||
get {
|
||||
if case .setOwner(let v)? = payloadVariant {return v}
|
||||
return User()
|
||||
|
|
@ -261,7 +271,7 @@ struct AdminMessage {
|
|||
/// The other records are secondary channels.
|
||||
/// Note: only one channel can be marked as primary.
|
||||
/// If the client sets a particular channel to be primary, the previous channel will be set to SECONDARY automatically.
|
||||
var setChannel: Channel {
|
||||
public var setChannel: Channel {
|
||||
get {
|
||||
if case .setChannel(let v)? = payloadVariant {return v}
|
||||
return Channel()
|
||||
|
|
@ -271,7 +281,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Set the current Config
|
||||
var setConfig: Config {
|
||||
public var setConfig: Config {
|
||||
get {
|
||||
if case .setConfig(let v)? = payloadVariant {return v}
|
||||
return Config()
|
||||
|
|
@ -281,7 +291,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Set the current Config
|
||||
var setModuleConfig: ModuleConfig {
|
||||
public var setModuleConfig: ModuleConfig {
|
||||
get {
|
||||
if case .setModuleConfig(let v)? = payloadVariant {return v}
|
||||
return ModuleConfig()
|
||||
|
|
@ -291,7 +301,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Set the Canned Message Module messages text.
|
||||
var setCannedMessageModuleMessages: String {
|
||||
public var setCannedMessageModuleMessages: String {
|
||||
get {
|
||||
if case .setCannedMessageModuleMessages(let v)? = payloadVariant {return v}
|
||||
return String()
|
||||
|
|
@ -301,7 +311,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Set the ringtone for ExternalNotification.
|
||||
var setRingtoneMessage: String {
|
||||
public var setRingtoneMessage: String {
|
||||
get {
|
||||
if case .setRingtoneMessage(let v)? = payloadVariant {return v}
|
||||
return String()
|
||||
|
|
@ -311,7 +321,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Remove the node by the specified node-num from the NodeDB on the device
|
||||
var removeByNodenum: UInt32 {
|
||||
public var removeByNodenum: UInt32 {
|
||||
get {
|
||||
if case .removeByNodenum(let v)? = payloadVariant {return v}
|
||||
return 0
|
||||
|
|
@ -321,7 +331,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Set specified node-num to be favorited on the NodeDB on the device
|
||||
var setFavoriteNode: UInt32 {
|
||||
public var setFavoriteNode: UInt32 {
|
||||
get {
|
||||
if case .setFavoriteNode(let v)? = payloadVariant {return v}
|
||||
return 0
|
||||
|
|
@ -331,7 +341,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Set specified node-num to be un-favorited on the NodeDB on the device
|
||||
var removeFavoriteNode: UInt32 {
|
||||
public var removeFavoriteNode: UInt32 {
|
||||
get {
|
||||
if case .removeFavoriteNode(let v)? = payloadVariant {return v}
|
||||
return 0
|
||||
|
|
@ -341,7 +351,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Set fixed position data on the node and then set the position.fixed_position = true
|
||||
var setFixedPosition: Position {
|
||||
public var setFixedPosition: Position {
|
||||
get {
|
||||
if case .setFixedPosition(let v)? = payloadVariant {return v}
|
||||
return Position()
|
||||
|
|
@ -351,7 +361,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Clear fixed position coordinates and then set position.fixed_position = false
|
||||
var removeFixedPosition: Bool {
|
||||
public var removeFixedPosition: Bool {
|
||||
get {
|
||||
if case .removeFixedPosition(let v)? = payloadVariant {return v}
|
||||
return false
|
||||
|
|
@ -362,7 +372,7 @@ struct AdminMessage {
|
|||
///
|
||||
/// Begins an edit transaction for config, module config, owner, and channel settings changes
|
||||
/// This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings)
|
||||
var beginEditSettings: Bool {
|
||||
public var beginEditSettings: Bool {
|
||||
get {
|
||||
if case .beginEditSettings(let v)? = payloadVariant {return v}
|
||||
return false
|
||||
|
|
@ -372,7 +382,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Commits an open transaction for any edits made to config, module config, owner, and channel settings
|
||||
var commitEditSettings: Bool {
|
||||
public var commitEditSettings: Bool {
|
||||
get {
|
||||
if case .commitEditSettings(let v)? = payloadVariant {return v}
|
||||
return false
|
||||
|
|
@ -383,7 +393,7 @@ struct AdminMessage {
|
|||
///
|
||||
/// Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
|
||||
/// Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth.
|
||||
var rebootOtaSeconds: Int32 {
|
||||
public var rebootOtaSeconds: Int32 {
|
||||
get {
|
||||
if case .rebootOtaSeconds(let v)? = payloadVariant {return v}
|
||||
return 0
|
||||
|
|
@ -394,7 +404,7 @@ struct AdminMessage {
|
|||
///
|
||||
/// This message is only supported for the simulator Portduino build.
|
||||
/// If received the simulator will exit successfully.
|
||||
var exitSimulator: Bool {
|
||||
public var exitSimulator: Bool {
|
||||
get {
|
||||
if case .exitSimulator(let v)? = payloadVariant {return v}
|
||||
return false
|
||||
|
|
@ -404,7 +414,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Tell the node to reboot in this many seconds (or <0 to cancel reboot)
|
||||
var rebootSeconds: Int32 {
|
||||
public var rebootSeconds: Int32 {
|
||||
get {
|
||||
if case .rebootSeconds(let v)? = payloadVariant {return v}
|
||||
return 0
|
||||
|
|
@ -414,7 +424,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Tell the node to shutdown in this many seconds (or <0 to cancel shutdown)
|
||||
var shutdownSeconds: Int32 {
|
||||
public var shutdownSeconds: Int32 {
|
||||
get {
|
||||
if case .shutdownSeconds(let v)? = payloadVariant {return v}
|
||||
return 0
|
||||
|
|
@ -424,7 +434,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Tell the node to factory reset, all device settings will be returned to factory defaults.
|
||||
var factoryReset: Int32 {
|
||||
public var factoryReset: Int32 {
|
||||
get {
|
||||
if case .factoryReset(let v)? = payloadVariant {return v}
|
||||
return 0
|
||||
|
|
@ -434,7 +444,7 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// Tell the node to reset the nodedb.
|
||||
var nodedbReset: Int32 {
|
||||
public var nodedbReset: Int32 {
|
||||
get {
|
||||
if case .nodedbReset(let v)? = payloadVariant {return v}
|
||||
return 0
|
||||
|
|
@ -442,11 +452,11 @@ struct AdminMessage {
|
|||
set {payloadVariant = .nodedbReset(newValue)}
|
||||
}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
enum OneOf_PayloadVariant: Equatable {
|
||||
public enum OneOf_PayloadVariant: Equatable {
|
||||
///
|
||||
/// 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)
|
||||
|
|
@ -513,6 +523,9 @@ struct AdminMessage {
|
|||
/// Delete the file by the specified path from the device
|
||||
case deleteFileRequest(String)
|
||||
///
|
||||
/// Set zero and offset for scale chips
|
||||
case setScale(UInt32)
|
||||
///
|
||||
/// Set the owner for this node
|
||||
case setOwner(User)
|
||||
///
|
||||
|
|
@ -578,7 +591,7 @@ struct AdminMessage {
|
|||
case nodedbReset(Int32)
|
||||
|
||||
#if !swift(>=4.1)
|
||||
static func ==(lhs: AdminMessage.OneOf_PayloadVariant, rhs: AdminMessage.OneOf_PayloadVariant) -> Bool {
|
||||
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
|
||||
|
|
@ -667,6 +680,10 @@ struct AdminMessage {
|
|||
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 (.setOwner, .setOwner): return {
|
||||
guard case .setOwner(let l) = lhs, case .setOwner(let r) = rhs else { preconditionFailure() }
|
||||
return l == r
|
||||
|
|
@ -751,8 +768,8 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
enum ConfigType: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
public enum ConfigType: SwiftProtobuf.Enum {
|
||||
public typealias RawValue = Int
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
|
|
@ -783,11 +800,11 @@ struct AdminMessage {
|
|||
case bluetoothConfig // = 6
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
public init() {
|
||||
self = .deviceConfig
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
public init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .deviceConfig
|
||||
case 1: self = .positionConfig
|
||||
|
|
@ -800,7 +817,7 @@ struct AdminMessage {
|
|||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
public var rawValue: Int {
|
||||
switch self {
|
||||
case .deviceConfig: return 0
|
||||
case .positionConfig: return 1
|
||||
|
|
@ -817,8 +834,8 @@ struct AdminMessage {
|
|||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
enum ModuleConfigType: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
public enum ModuleConfigType: SwiftProtobuf.Enum {
|
||||
public typealias RawValue = Int
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
|
|
@ -873,11 +890,11 @@ struct AdminMessage {
|
|||
case paxcounterConfig // = 12
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
public init() {
|
||||
self = .mqttConfig
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
public init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .mqttConfig
|
||||
case 1: self = .serialConfig
|
||||
|
|
@ -896,7 +913,7 @@ struct AdminMessage {
|
|||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
public var rawValue: Int {
|
||||
switch self {
|
||||
case .mqttConfig: return 0
|
||||
case .serialConfig: return 1
|
||||
|
|
@ -917,14 +934,14 @@ struct AdminMessage {
|
|||
|
||||
}
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
#if swift(>=4.2)
|
||||
|
||||
extension AdminMessage.ConfigType: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static let allCases: [AdminMessage.ConfigType] = [
|
||||
public static let allCases: [AdminMessage.ConfigType] = [
|
||||
.deviceConfig,
|
||||
.positionConfig,
|
||||
.powerConfig,
|
||||
|
|
@ -937,7 +954,7 @@ extension AdminMessage.ConfigType: CaseIterable {
|
|||
|
||||
extension AdminMessage.ModuleConfigType: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static let allCases: [AdminMessage.ModuleConfigType] = [
|
||||
public static let allCases: [AdminMessage.ModuleConfigType] = [
|
||||
.mqttConfig,
|
||||
.serialConfig,
|
||||
.extnotifConfig,
|
||||
|
|
@ -958,48 +975,48 @@ extension AdminMessage.ModuleConfigType: CaseIterable {
|
|||
|
||||
///
|
||||
/// Parameters for setting up Meshtastic for ameteur radio usage
|
||||
struct HamParameters {
|
||||
public struct HamParameters {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Amateur radio call sign, eg. KD2ABC
|
||||
var callSign: String = String()
|
||||
public var callSign: String = String()
|
||||
|
||||
///
|
||||
/// Transmit power in dBm at the LoRA transceiver, not including any amplification
|
||||
var txPower: Int32 = 0
|
||||
public var txPower: Int32 = 0
|
||||
|
||||
///
|
||||
/// The selected frequency of LoRA operation
|
||||
/// Please respect your local laws, regulations, and band plans.
|
||||
/// Ensure your radio is capable of operating of the selected frequency before setting this.
|
||||
var frequency: Float = 0
|
||||
public var frequency: Float = 0
|
||||
|
||||
///
|
||||
/// Optional short name of user
|
||||
var shortName: String = String()
|
||||
public var shortName: String = String()
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
///
|
||||
/// Response envelope for node_remote_hardware_pins
|
||||
struct NodeRemoteHardwarePinsResponse {
|
||||
public struct NodeRemoteHardwarePinsResponse {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Nodes and their respective remote hardware GPIO pins
|
||||
var nodeRemoteHardwarePins: [NodeRemoteHardwarePin] = []
|
||||
public var nodeRemoteHardwarePins: [NodeRemoteHardwarePin] = []
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
#if swift(>=5.5) && canImport(_Concurrency)
|
||||
|
|
@ -1016,8 +1033,8 @@ extension NodeRemoteHardwarePinsResponse: @unchecked Sendable {}
|
|||
fileprivate let _protobuf_package = "meshtastic"
|
||||
|
||||
extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".AdminMessage"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let protoMessageName: String = _protobuf_package + ".AdminMessage"
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "get_channel_request"),
|
||||
2: .standard(proto: "get_channel_response"),
|
||||
3: .standard(proto: "get_owner_request"),
|
||||
|
|
@ -1039,6 +1056,7 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
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"),
|
||||
32: .standard(proto: "set_owner"),
|
||||
33: .standard(proto: "set_channel"),
|
||||
34: .standard(proto: "set_config"),
|
||||
|
|
@ -1060,7 +1078,7 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
100: .standard(proto: "nodedb_reset"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -1274,6 +1292,14 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
self.payloadVariant = .deleteFileRequest(v)
|
||||
}
|
||||
}()
|
||||
case 23: try {
|
||||
var v: UInt32?
|
||||
try decoder.decodeSingularUInt32Field(value: &v)
|
||||
if let v = v {
|
||||
if self.payloadVariant != nil {try decoder.handleConflictingOneOf()}
|
||||
self.payloadVariant = .setScale(v)
|
||||
}
|
||||
}()
|
||||
case 32: try {
|
||||
var v: User?
|
||||
var hadOneofValue = false
|
||||
|
|
@ -1456,7 +1482,7 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
|
|
@ -1546,6 +1572,10 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
guard case .deleteFileRequest(let v)? = self.payloadVariant else { preconditionFailure() }
|
||||
try visitor.visitSingularStringField(value: v, fieldNumber: 22)
|
||||
}()
|
||||
case .setScale?: try {
|
||||
guard case .setScale(let v)? = self.payloadVariant else { preconditionFailure() }
|
||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 23)
|
||||
}()
|
||||
case .setOwner?: try {
|
||||
guard case .setOwner(let v)? = self.payloadVariant else { preconditionFailure() }
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 32)
|
||||
|
|
@ -1627,7 +1657,7 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: AdminMessage, rhs: AdminMessage) -> Bool {
|
||||
public static func ==(lhs: AdminMessage, rhs: AdminMessage) -> Bool {
|
||||
if lhs.payloadVariant != rhs.payloadVariant {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
|
|
@ -1635,7 +1665,7 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
}
|
||||
|
||||
extension AdminMessage.ConfigType: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "DEVICE_CONFIG"),
|
||||
1: .same(proto: "POSITION_CONFIG"),
|
||||
2: .same(proto: "POWER_CONFIG"),
|
||||
|
|
@ -1647,7 +1677,7 @@ extension AdminMessage.ConfigType: SwiftProtobuf._ProtoNameProviding {
|
|||
}
|
||||
|
||||
extension AdminMessage.ModuleConfigType: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "MQTT_CONFIG"),
|
||||
1: .same(proto: "SERIAL_CONFIG"),
|
||||
2: .same(proto: "EXTNOTIF_CONFIG"),
|
||||
|
|
@ -1665,15 +1695,15 @@ extension AdminMessage.ModuleConfigType: SwiftProtobuf._ProtoNameProviding {
|
|||
}
|
||||
|
||||
extension HamParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".HamParameters"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -1688,7 +1718,7 @@ extension HamParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if !self.callSign.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.callSign, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -1704,7 +1734,7 @@ extension HamParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: HamParameters, rhs: HamParameters) -> Bool {
|
||||
public static func ==(lhs: HamParameters, rhs: HamParameters) -> Bool {
|
||||
if lhs.callSign != rhs.callSign {return false}
|
||||
if lhs.txPower != rhs.txPower {return false}
|
||||
if lhs.frequency != rhs.frequency {return false}
|
||||
|
|
@ -1715,12 +1745,12 @@ extension HamParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa
|
|||
}
|
||||
|
||||
extension NodeRemoteHardwarePinsResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".NodeRemoteHardwarePinsResponse"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let protoMessageName: String = _protobuf_package + ".NodeRemoteHardwarePinsResponse"
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "node_remote_hardware_pins"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -1732,14 +1762,14 @@ extension NodeRemoteHardwarePinsResponse: SwiftProtobuf.Message, SwiftProtobuf._
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if !self.nodeRemoteHardwarePins.isEmpty {
|
||||
try visitor.visitRepeatedMessageField(value: self.nodeRemoteHardwarePins, fieldNumber: 1)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: NodeRemoteHardwarePinsResponse, rhs: NodeRemoteHardwarePinsResponse) -> Bool {
|
||||
public static func ==(lhs: NodeRemoteHardwarePinsResponse, rhs: NodeRemoteHardwarePinsResponse) -> Bool {
|
||||
if lhs.nodeRemoteHardwarePins != rhs.nodeRemoteHardwarePins {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
|
|
@ -26,32 +26,32 @@ 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
|
||||
struct ChannelSet {
|
||||
public struct ChannelSet {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Channel list with settings
|
||||
var settings: [ChannelSettings] {
|
||||
public var settings: [ChannelSettings] {
|
||||
get {return _storage._settings}
|
||||
set {_uniqueStorage()._settings = newValue}
|
||||
}
|
||||
|
||||
///
|
||||
/// LoRa config
|
||||
var loraConfig: Config.LoRaConfig {
|
||||
public var loraConfig: Config.LoRaConfig {
|
||||
get {return _storage._loraConfig ?? Config.LoRaConfig()}
|
||||
set {_uniqueStorage()._loraConfig = newValue}
|
||||
}
|
||||
/// Returns true if `loraConfig` has been explicitly set.
|
||||
var hasLoraConfig: Bool {return _storage._loraConfig != nil}
|
||||
public var hasLoraConfig: Bool {return _storage._loraConfig != nil}
|
||||
/// Clears the value of `loraConfig`. Subsequent reads from it will return its default value.
|
||||
mutating func clearLoraConfig() {_uniqueStorage()._loraConfig = nil}
|
||||
public mutating func clearLoraConfig() {_uniqueStorage()._loraConfig = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _storage = _StorageClass.defaultInstance
|
||||
}
|
||||
|
|
@ -65,8 +65,8 @@ extension ChannelSet: @unchecked Sendable {}
|
|||
fileprivate let _protobuf_package = "meshtastic"
|
||||
|
||||
extension ChannelSet: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".ChannelSet"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let protoMessageName: String = _protobuf_package + ".ChannelSet"
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "settings"),
|
||||
2: .standard(proto: "lora_config"),
|
||||
]
|
||||
|
|
@ -100,7 +100,7 @@ extension ChannelSet: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
|
|||
return _storage
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
_ = _uniqueStorage()
|
||||
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
@ -116,7 +116,7 @@ extension ChannelSet: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
|
|
@ -132,7 +132,7 @@ extension ChannelSet: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: ChannelSet, rhs: ChannelSet) -> Bool {
|
||||
public static func ==(lhs: ChannelSet, rhs: ChannelSet) -> Bool {
|
||||
if lhs._storage !== rhs._storage {
|
||||
let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in
|
||||
let _storage = _args.0
|
||||
|
|
@ -20,8 +20,8 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
|
|||
typealias Version = _2
|
||||
}
|
||||
|
||||
enum Team: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
public enum Team: SwiftProtobuf.Enum {
|
||||
public typealias RawValue = Int
|
||||
|
||||
///
|
||||
/// Unspecifed
|
||||
|
|
@ -84,11 +84,11 @@ enum Team: SwiftProtobuf.Enum {
|
|||
case brown // = 14
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
public init() {
|
||||
self = .unspecifedColor
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
public init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .unspecifedColor
|
||||
case 1: self = .white
|
||||
|
|
@ -109,7 +109,7 @@ enum Team: SwiftProtobuf.Enum {
|
|||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
public var rawValue: Int {
|
||||
switch self {
|
||||
case .unspecifedColor: return 0
|
||||
case .white: return 1
|
||||
|
|
@ -136,7 +136,7 @@ enum Team: SwiftProtobuf.Enum {
|
|||
|
||||
extension Team: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static let allCases: [Team] = [
|
||||
public static let allCases: [Team] = [
|
||||
.unspecifedColor,
|
||||
.white,
|
||||
.yellow,
|
||||
|
|
@ -159,8 +159,8 @@ extension Team: CaseIterable {
|
|||
|
||||
///
|
||||
/// Role of the group member
|
||||
enum MemberRole: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
public enum MemberRole: SwiftProtobuf.Enum {
|
||||
public typealias RawValue = Int
|
||||
|
||||
///
|
||||
/// Unspecifed
|
||||
|
|
@ -199,11 +199,11 @@ enum MemberRole: SwiftProtobuf.Enum {
|
|||
case k9 // = 8
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
public init() {
|
||||
self = .unspecifed
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
public init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .unspecifed
|
||||
case 1: self = .teamMember
|
||||
|
|
@ -218,7 +218,7 @@ enum MemberRole: SwiftProtobuf.Enum {
|
|||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
public var rawValue: Int {
|
||||
switch self {
|
||||
case .unspecifed: return 0
|
||||
case .teamMember: return 1
|
||||
|
|
@ -239,7 +239,7 @@ enum MemberRole: SwiftProtobuf.Enum {
|
|||
|
||||
extension MemberRole: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static let allCases: [MemberRole] = [
|
||||
public static let allCases: [MemberRole] = [
|
||||
.unspecifed,
|
||||
.teamMember,
|
||||
.teamLead,
|
||||
|
|
@ -256,55 +256,55 @@ extension MemberRole: CaseIterable {
|
|||
|
||||
///
|
||||
/// Packets for the official ATAK Plugin
|
||||
struct TAKPacket {
|
||||
public struct TAKPacket {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Are the payloads strings compressed for LoRA transport?
|
||||
var isCompressed: Bool = false
|
||||
public var isCompressed: Bool = false
|
||||
|
||||
///
|
||||
/// The contact / callsign for ATAK user
|
||||
var contact: Contact {
|
||||
public var contact: Contact {
|
||||
get {return _contact ?? Contact()}
|
||||
set {_contact = newValue}
|
||||
}
|
||||
/// Returns true if `contact` has been explicitly set.
|
||||
var hasContact: Bool {return self._contact != nil}
|
||||
public var hasContact: Bool {return self._contact != nil}
|
||||
/// Clears the value of `contact`. Subsequent reads from it will return its default value.
|
||||
mutating func clearContact() {self._contact = nil}
|
||||
public mutating func clearContact() {self._contact = nil}
|
||||
|
||||
///
|
||||
/// The group for ATAK user
|
||||
var group: Group {
|
||||
public var group: Group {
|
||||
get {return _group ?? Group()}
|
||||
set {_group = newValue}
|
||||
}
|
||||
/// Returns true if `group` has been explicitly set.
|
||||
var hasGroup: Bool {return self._group != nil}
|
||||
public var hasGroup: Bool {return self._group != nil}
|
||||
/// Clears the value of `group`. Subsequent reads from it will return its default value.
|
||||
mutating func clearGroup() {self._group = nil}
|
||||
public mutating func clearGroup() {self._group = nil}
|
||||
|
||||
///
|
||||
/// The status of the ATAK EUD
|
||||
var status: Status {
|
||||
public var status: Status {
|
||||
get {return _status ?? Status()}
|
||||
set {_status = newValue}
|
||||
}
|
||||
/// Returns true if `status` has been explicitly set.
|
||||
var hasStatus: Bool {return self._status != nil}
|
||||
public var hasStatus: Bool {return self._status != nil}
|
||||
/// Clears the value of `status`. Subsequent reads from it will return its default value.
|
||||
mutating func clearStatus() {self._status = nil}
|
||||
public mutating func clearStatus() {self._status = nil}
|
||||
|
||||
///
|
||||
/// The payload of the packet
|
||||
var payloadVariant: TAKPacket.OneOf_PayloadVariant? = nil
|
||||
public var payloadVariant: TAKPacket.OneOf_PayloadVariant? = nil
|
||||
|
||||
///
|
||||
/// TAK position report
|
||||
var pli: PLI {
|
||||
public var pli: PLI {
|
||||
get {
|
||||
if case .pli(let v)? = payloadVariant {return v}
|
||||
return PLI()
|
||||
|
|
@ -314,7 +314,7 @@ struct TAKPacket {
|
|||
|
||||
///
|
||||
/// ATAK GeoChat message
|
||||
var chat: GeoChat {
|
||||
public var chat: GeoChat {
|
||||
get {
|
||||
if case .chat(let v)? = payloadVariant {return v}
|
||||
return GeoChat()
|
||||
|
|
@ -322,11 +322,11 @@ struct TAKPacket {
|
|||
set {payloadVariant = .chat(newValue)}
|
||||
}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
///
|
||||
/// The payload of the packet
|
||||
enum OneOf_PayloadVariant: Equatable {
|
||||
public enum OneOf_PayloadVariant: Equatable {
|
||||
///
|
||||
/// TAK position report
|
||||
case pli(PLI)
|
||||
|
|
@ -335,7 +335,7 @@ struct TAKPacket {
|
|||
case chat(GeoChat)
|
||||
|
||||
#if !swift(>=4.1)
|
||||
static func ==(lhs: TAKPacket.OneOf_PayloadVariant, rhs: TAKPacket.OneOf_PayloadVariant) -> Bool {
|
||||
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
|
||||
|
|
@ -354,7 +354,7 @@ struct TAKPacket {
|
|||
#endif
|
||||
}
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _contact: Contact? = nil
|
||||
fileprivate var _group: Group? = nil
|
||||
|
|
@ -363,40 +363,40 @@ struct TAKPacket {
|
|||
|
||||
///
|
||||
/// ATAK GeoChat message
|
||||
struct GeoChat {
|
||||
public struct GeoChat {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// The text message
|
||||
var message: String = String()
|
||||
public var message: String = String()
|
||||
|
||||
///
|
||||
/// Uid recipient of the message
|
||||
var to: String {
|
||||
public var to: String {
|
||||
get {return _to ?? String()}
|
||||
set {_to = newValue}
|
||||
}
|
||||
/// Returns true if `to` has been explicitly set.
|
||||
var hasTo: Bool {return self._to != nil}
|
||||
public var hasTo: Bool {return self._to != nil}
|
||||
/// Clears the value of `to`. Subsequent reads from it will return its default value.
|
||||
mutating func clearTo() {self._to = nil}
|
||||
public mutating func clearTo() {self._to = nil}
|
||||
|
||||
///
|
||||
/// Callsign of the recipient for the message
|
||||
var toCallsign: String {
|
||||
public var toCallsign: String {
|
||||
get {return _toCallsign ?? String()}
|
||||
set {_toCallsign = newValue}
|
||||
}
|
||||
/// Returns true if `toCallsign` has been explicitly set.
|
||||
var hasToCallsign: Bool {return self._toCallsign != nil}
|
||||
public var hasToCallsign: Bool {return self._toCallsign != nil}
|
||||
/// Clears the value of `toCallsign`. Subsequent reads from it will return its default value.
|
||||
mutating func clearToCallsign() {self._toCallsign = nil}
|
||||
public mutating func clearToCallsign() {self._toCallsign = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _to: String? = nil
|
||||
fileprivate var _toCallsign: String? = nil
|
||||
|
|
@ -405,66 +405,66 @@ struct GeoChat {
|
|||
///
|
||||
/// ATAK Group
|
||||
/// <__group role='Team Member' name='Cyan'/>
|
||||
struct Group {
|
||||
public struct Group {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Role of the group member
|
||||
var role: MemberRole = .unspecifed
|
||||
public var role: MemberRole = .unspecifed
|
||||
|
||||
///
|
||||
/// Team (color)
|
||||
/// Default Cyan
|
||||
var team: Team = .unspecifedColor
|
||||
public var team: Team = .unspecifedColor
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
///
|
||||
/// ATAK EUD Status
|
||||
/// <status battery='100' />
|
||||
struct Status {
|
||||
public struct Status {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Battery level
|
||||
var battery: UInt32 = 0
|
||||
public var battery: UInt32 = 0
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
///
|
||||
/// ATAK Contact
|
||||
/// <contact endpoint='0.0.0.0:4242:tcp' phone='+12345678' callsign='FALKE'/>
|
||||
struct Contact {
|
||||
public struct Contact {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Callsign
|
||||
var callsign: String = String()
|
||||
public var callsign: String = String()
|
||||
|
||||
///
|
||||
/// Device callsign
|
||||
var deviceCallsign: String = String()
|
||||
public var deviceCallsign: String = String()
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
///
|
||||
/// Position Location Information from ATAK
|
||||
struct PLI {
|
||||
public struct PLI {
|
||||
// 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.
|
||||
|
|
@ -472,28 +472,28 @@ struct PLI {
|
|||
///
|
||||
/// The new preferred location encoding, multiply by 1e-7 to get degrees
|
||||
/// in floating point
|
||||
var latitudeI: Int32 = 0
|
||||
public var latitudeI: Int32 = 0
|
||||
|
||||
///
|
||||
/// The new preferred location encoding, multiply by 1e-7 to get degrees
|
||||
/// in floating point
|
||||
var longitudeI: Int32 = 0
|
||||
public var longitudeI: Int32 = 0
|
||||
|
||||
///
|
||||
/// Altitude (ATAK prefers HAE)
|
||||
var altitude: Int32 = 0
|
||||
public var altitude: Int32 = 0
|
||||
|
||||
///
|
||||
/// Speed
|
||||
var speed: UInt32 = 0
|
||||
public var speed: UInt32 = 0
|
||||
|
||||
///
|
||||
/// Course in degrees
|
||||
var course: UInt32 = 0
|
||||
public var course: UInt32 = 0
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
#if swift(>=5.5) && canImport(_Concurrency)
|
||||
|
|
@ -513,7 +513,7 @@ extension PLI: @unchecked Sendable {}
|
|||
fileprivate let _protobuf_package = "meshtastic"
|
||||
|
||||
extension Team: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "Unspecifed_Color"),
|
||||
1: .same(proto: "White"),
|
||||
2: .same(proto: "Yellow"),
|
||||
|
|
@ -533,7 +533,7 @@ extension Team: SwiftProtobuf._ProtoNameProviding {
|
|||
}
|
||||
|
||||
extension MemberRole: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "Unspecifed"),
|
||||
1: .same(proto: "TeamMember"),
|
||||
2: .same(proto: "TeamLead"),
|
||||
|
|
@ -547,8 +547,8 @@ extension MemberRole: SwiftProtobuf._ProtoNameProviding {
|
|||
}
|
||||
|
||||
extension TAKPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".TAKPacket"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
|
|
@ -557,7 +557,7 @@ extension TAKPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
|
|||
6: .same(proto: "chat"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -598,7 +598,7 @@ extension TAKPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
|
|
@ -629,7 +629,7 @@ extension TAKPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: TAKPacket, rhs: TAKPacket) -> Bool {
|
||||
public static func ==(lhs: TAKPacket, rhs: TAKPacket) -> Bool {
|
||||
if lhs.isCompressed != rhs.isCompressed {return false}
|
||||
if lhs._contact != rhs._contact {return false}
|
||||
if lhs._group != rhs._group {return false}
|
||||
|
|
@ -641,14 +641,14 @@ extension TAKPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
|
|||
}
|
||||
|
||||
extension GeoChat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".GeoChat"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -662,7 +662,7 @@ extension GeoChat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
|
|
@ -679,7 +679,7 @@ extension GeoChat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: GeoChat, rhs: GeoChat) -> Bool {
|
||||
public static func ==(lhs: GeoChat, rhs: GeoChat) -> Bool {
|
||||
if lhs.message != rhs.message {return false}
|
||||
if lhs._to != rhs._to {return false}
|
||||
if lhs._toCallsign != rhs._toCallsign {return false}
|
||||
|
|
@ -689,13 +689,13 @@ extension GeoChat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
}
|
||||
|
||||
extension Group: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".Group"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let protoMessageName: String = _protobuf_package + ".Group"
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "role"),
|
||||
2: .same(proto: "team"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -708,7 +708,7 @@ extension Group: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if self.role != .unspecifed {
|
||||
try visitor.visitSingularEnumField(value: self.role, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -718,7 +718,7 @@ extension Group: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Group, rhs: Group) -> Bool {
|
||||
public static func ==(lhs: Group, rhs: Group) -> Bool {
|
||||
if lhs.role != rhs.role {return false}
|
||||
if lhs.team != rhs.team {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
|
|
@ -727,12 +727,12 @@ extension Group: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase
|
|||
}
|
||||
|
||||
extension Status: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".Status"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let protoMessageName: String = _protobuf_package + ".Status"
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "battery"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -744,14 +744,14 @@ extension Status: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if self.battery != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.battery, fieldNumber: 1)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Status, rhs: Status) -> Bool {
|
||||
public static func ==(lhs: Status, rhs: Status) -> Bool {
|
||||
if lhs.battery != rhs.battery {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
|
|
@ -759,13 +759,13 @@ extension Status: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas
|
|||
}
|
||||
|
||||
extension Contact: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".Contact"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let protoMessageName: String = _protobuf_package + ".Contact"
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "callsign"),
|
||||
2: .standard(proto: "device_callsign"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -778,7 +778,7 @@ extension Contact: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if !self.callsign.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.callsign, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -788,7 +788,7 @@ extension Contact: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Contact, rhs: Contact) -> Bool {
|
||||
public static func ==(lhs: Contact, rhs: Contact) -> Bool {
|
||||
if lhs.callsign != rhs.callsign {return false}
|
||||
if lhs.deviceCallsign != rhs.deviceCallsign {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
|
|
@ -797,8 +797,8 @@ extension Contact: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
}
|
||||
|
||||
extension PLI: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".PLI"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
|
|
@ -806,7 +806,7 @@ extension PLI: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase,
|
|||
5: .same(proto: "course"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -822,7 +822,7 @@ extension PLI: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase,
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if self.latitudeI != 0 {
|
||||
try visitor.visitSingularSFixed32Field(value: self.latitudeI, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -841,7 +841,7 @@ extension PLI: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase,
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: PLI, rhs: PLI) -> Bool {
|
||||
public static func ==(lhs: PLI, rhs: PLI) -> Bool {
|
||||
if lhs.latitudeI != rhs.latitudeI {return false}
|
||||
if lhs.longitudeI != rhs.longitudeI {return false}
|
||||
if lhs.altitude != rhs.altitude {return false}
|
||||
|
|
@ -22,18 +22,18 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
|
|||
|
||||
///
|
||||
/// Canned message module configuration.
|
||||
struct CannedMessageModuleConfig {
|
||||
public struct CannedMessageModuleConfig {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
///
|
||||
/// Predefined messages for canned message module separated by '|' characters.
|
||||
var messages: String = String()
|
||||
public var messages: String = String()
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
#if swift(>=5.5) && canImport(_Concurrency)
|
||||
|
|
@ -45,12 +45,12 @@ extension CannedMessageModuleConfig: @unchecked Sendable {}
|
|||
fileprivate let _protobuf_package = "meshtastic"
|
||||
|
||||
extension CannedMessageModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".CannedMessageModuleConfig"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let protoMessageName: String = _protobuf_package + ".CannedMessageModuleConfig"
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "messages"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -62,14 +62,14 @@ extension CannedMessageModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._Messa
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if !self.messages.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.messages, fieldNumber: 1)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: CannedMessageModuleConfig, rhs: CannedMessageModuleConfig) -> Bool {
|
||||
public static func ==(lhs: CannedMessageModuleConfig, rhs: CannedMessageModuleConfig) -> Bool {
|
||||
if lhs.messages != rhs.messages {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
|
|
@ -36,14 +36,14 @@ 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
|
||||
struct ChannelSettings {
|
||||
public struct ChannelSettings {
|
||||
// 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
|
||||
var channelNum: UInt32 = 0
|
||||
public var channelNum: UInt32 = 0
|
||||
|
||||
///
|
||||
/// A simple pre-shared key for now for crypto.
|
||||
|
|
@ -56,7 +56,7 @@ struct ChannelSettings {
|
|||
/// `1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01}
|
||||
/// `2` through 10 = The default channel key, except with 1 through 9 added to the last byte.
|
||||
/// Shown to user as simple1 through 10
|
||||
var psk: Data = Data()
|
||||
public var psk: Data = Data()
|
||||
|
||||
///
|
||||
/// A SHORT name that will be packed into the URL.
|
||||
|
|
@ -67,7 +67,7 @@ struct ChannelSettings {
|
|||
/// In user interfaces it should be rendered as a local language translation of "X".
|
||||
/// For channel_num hashing empty string will be treated as "X".
|
||||
/// Where "X" is selected based on the English words listed above for ModemPreset
|
||||
var name: String = String()
|
||||
public var name: String = String()
|
||||
|
||||
///
|
||||
/// Used to construct a globally unique channel ID.
|
||||
|
|
@ -81,58 +81,58 @@ struct ChannelSettings {
|
|||
/// Those channels do not have a numeric id included in the settings, but instead it is pulled from
|
||||
/// a table of well known IDs.
|
||||
/// (see Well Known Channels FIXME)
|
||||
var id: UInt32 = 0
|
||||
public var id: UInt32 = 0
|
||||
|
||||
///
|
||||
/// If true, messages on the mesh will be sent to the *public* internet by any gateway ndoe
|
||||
var uplinkEnabled: Bool = false
|
||||
public var uplinkEnabled: Bool = false
|
||||
|
||||
///
|
||||
/// If true, messages seen on the internet will be forwarded to the local mesh.
|
||||
var downlinkEnabled: Bool = false
|
||||
public var downlinkEnabled: Bool = false
|
||||
|
||||
///
|
||||
/// Per-channel module settings.
|
||||
var moduleSettings: ModuleSettings {
|
||||
public var moduleSettings: ModuleSettings {
|
||||
get {return _moduleSettings ?? ModuleSettings()}
|
||||
set {_moduleSettings = newValue}
|
||||
}
|
||||
/// Returns true if `moduleSettings` has been explicitly set.
|
||||
var hasModuleSettings: Bool {return self._moduleSettings != nil}
|
||||
public var hasModuleSettings: Bool {return self._moduleSettings != nil}
|
||||
/// Clears the value of `moduleSettings`. Subsequent reads from it will return its default value.
|
||||
mutating func clearModuleSettings() {self._moduleSettings = nil}
|
||||
public mutating func clearModuleSettings() {self._moduleSettings = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _moduleSettings: ModuleSettings? = nil
|
||||
}
|
||||
|
||||
///
|
||||
/// This message is specifically for modules to store per-channel configuration data.
|
||||
struct ModuleSettings {
|
||||
public struct ModuleSettings {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Bits of precision for the location sent in position packets.
|
||||
var positionPrecision: UInt32 = 0
|
||||
public var positionPrecision: UInt32 = 0
|
||||
|
||||
///
|
||||
/// Controls whether or not the phone / clients should mute the current channel
|
||||
/// Useful for noisy public channels you don't necessarily want to disable
|
||||
var isClientMuted: Bool = false
|
||||
public var isClientMuted: Bool = false
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
///
|
||||
/// A pair of a channel number, mode and the (sharable) settings for that channel
|
||||
struct Channel {
|
||||
public struct Channel {
|
||||
// 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.
|
||||
|
|
@ -141,24 +141,24 @@ struct Channel {
|
|||
/// The index of this channel in the channel table (from 0 to MAX_NUM_CHANNELS-1)
|
||||
/// (Someday - not currently implemented) An index of -1 could be used to mean "set by name",
|
||||
/// in which case the target node will find and set the channel by settings.name.
|
||||
var index: Int32 = 0
|
||||
public var index: Int32 = 0
|
||||
|
||||
///
|
||||
/// The new settings, or NULL to disable that channel
|
||||
var settings: ChannelSettings {
|
||||
public var settings: ChannelSettings {
|
||||
get {return _settings ?? ChannelSettings()}
|
||||
set {_settings = newValue}
|
||||
}
|
||||
/// Returns true if `settings` has been explicitly set.
|
||||
var hasSettings: Bool {return self._settings != nil}
|
||||
public var hasSettings: Bool {return self._settings != nil}
|
||||
/// Clears the value of `settings`. Subsequent reads from it will return its default value.
|
||||
mutating func clearSettings() {self._settings = nil}
|
||||
public mutating func clearSettings() {self._settings = nil}
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
var role: Channel.Role = .disabled
|
||||
public var role: Channel.Role = .disabled
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
///
|
||||
/// How this channel is being used (or not).
|
||||
|
|
@ -170,8 +170,8 @@ 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)
|
||||
enum Role: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
public enum Role: SwiftProtobuf.Enum {
|
||||
public typealias RawValue = Int
|
||||
|
||||
///
|
||||
/// This channel is not in use right now
|
||||
|
|
@ -187,11 +187,11 @@ struct Channel {
|
|||
case secondary // = 2
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
public init() {
|
||||
self = .disabled
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
public init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .disabled
|
||||
case 1: self = .primary
|
||||
|
|
@ -200,7 +200,7 @@ struct Channel {
|
|||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
public var rawValue: Int {
|
||||
switch self {
|
||||
case .disabled: return 0
|
||||
case .primary: return 1
|
||||
|
|
@ -211,7 +211,7 @@ struct Channel {
|
|||
|
||||
}
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _settings: ChannelSettings? = nil
|
||||
}
|
||||
|
|
@ -220,7 +220,7 @@ struct Channel {
|
|||
|
||||
extension Channel.Role: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static let allCases: [Channel.Role] = [
|
||||
public static let allCases: [Channel.Role] = [
|
||||
.disabled,
|
||||
.primary,
|
||||
.secondary,
|
||||
|
|
@ -241,8 +241,8 @@ extension Channel.Role: @unchecked Sendable {}
|
|||
fileprivate let _protobuf_package = "meshtastic"
|
||||
|
||||
extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".ChannelSettings"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
|
|
@ -252,7 +252,7 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen
|
|||
7: .standard(proto: "module_settings"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -270,7 +270,7 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
|
|
@ -299,7 +299,7 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: ChannelSettings, rhs: ChannelSettings) -> Bool {
|
||||
public static func ==(lhs: ChannelSettings, rhs: ChannelSettings) -> Bool {
|
||||
if lhs.channelNum != rhs.channelNum {return false}
|
||||
if lhs.psk != rhs.psk {return false}
|
||||
if lhs.name != rhs.name {return false}
|
||||
|
|
@ -313,13 +313,13 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen
|
|||
}
|
||||
|
||||
extension ModuleSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".ModuleSettings"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -332,7 +332,7 @@ extension ModuleSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if self.positionPrecision != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.positionPrecision, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -342,7 +342,7 @@ extension ModuleSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: ModuleSettings, rhs: ModuleSettings) -> Bool {
|
||||
public static func ==(lhs: ModuleSettings, rhs: ModuleSettings) -> Bool {
|
||||
if lhs.positionPrecision != rhs.positionPrecision {return false}
|
||||
if lhs.isClientMuted != rhs.isClientMuted {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
|
|
@ -351,14 +351,14 @@ extension ModuleSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
|
|||
}
|
||||
|
||||
extension Channel: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".Channel"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -372,7 +372,7 @@ extension Channel: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
|
|
@ -389,7 +389,7 @@ extension Channel: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Channel, rhs: Channel) -> Bool {
|
||||
public static func ==(lhs: Channel, rhs: Channel) -> Bool {
|
||||
if lhs.index != rhs.index {return false}
|
||||
if lhs._settings != rhs._settings {return false}
|
||||
if lhs.role != rhs.role {return false}
|
||||
|
|
@ -399,7 +399,7 @@ extension Channel: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
|
|||
}
|
||||
|
||||
extension Channel.Role: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "DISABLED"),
|
||||
1: .same(proto: "PRIMARY"),
|
||||
2: .same(proto: "SECONDARY"),
|
||||
|
|
@ -23,69 +23,69 @@ 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.
|
||||
struct DeviceProfile {
|
||||
public struct DeviceProfile {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Long name for the node
|
||||
var longName: String {
|
||||
public var longName: String {
|
||||
get {return _longName ?? String()}
|
||||
set {_longName = newValue}
|
||||
}
|
||||
/// Returns true if `longName` has been explicitly set.
|
||||
var hasLongName: Bool {return self._longName != nil}
|
||||
public var hasLongName: Bool {return self._longName != nil}
|
||||
/// Clears the value of `longName`. Subsequent reads from it will return its default value.
|
||||
mutating func clearLongName() {self._longName = nil}
|
||||
public mutating func clearLongName() {self._longName = nil}
|
||||
|
||||
///
|
||||
/// Short name of the node
|
||||
var shortName: String {
|
||||
public var shortName: String {
|
||||
get {return _shortName ?? String()}
|
||||
set {_shortName = newValue}
|
||||
}
|
||||
/// Returns true if `shortName` has been explicitly set.
|
||||
var hasShortName: Bool {return self._shortName != nil}
|
||||
public var hasShortName: Bool {return self._shortName != nil}
|
||||
/// Clears the value of `shortName`. Subsequent reads from it will return its default value.
|
||||
mutating func clearShortName() {self._shortName = nil}
|
||||
public mutating func clearShortName() {self._shortName = nil}
|
||||
|
||||
///
|
||||
/// The url of the channels from our node
|
||||
var channelURL: String {
|
||||
public var channelURL: String {
|
||||
get {return _channelURL ?? String()}
|
||||
set {_channelURL = newValue}
|
||||
}
|
||||
/// Returns true if `channelURL` has been explicitly set.
|
||||
var hasChannelURL: Bool {return self._channelURL != nil}
|
||||
public var hasChannelURL: Bool {return self._channelURL != nil}
|
||||
/// Clears the value of `channelURL`. Subsequent reads from it will return its default value.
|
||||
mutating func clearChannelURL() {self._channelURL = nil}
|
||||
public mutating func clearChannelURL() {self._channelURL = nil}
|
||||
|
||||
///
|
||||
/// The Config of the node
|
||||
var config: LocalConfig {
|
||||
public var config: LocalConfig {
|
||||
get {return _config ?? LocalConfig()}
|
||||
set {_config = newValue}
|
||||
}
|
||||
/// Returns true if `config` has been explicitly set.
|
||||
var hasConfig: Bool {return self._config != nil}
|
||||
public var hasConfig: Bool {return self._config != nil}
|
||||
/// Clears the value of `config`. Subsequent reads from it will return its default value.
|
||||
mutating func clearConfig() {self._config = nil}
|
||||
public mutating func clearConfig() {self._config = nil}
|
||||
|
||||
///
|
||||
/// The ModuleConfig of the node
|
||||
var moduleConfig: LocalModuleConfig {
|
||||
public var moduleConfig: LocalModuleConfig {
|
||||
get {return _moduleConfig ?? LocalModuleConfig()}
|
||||
set {_moduleConfig = newValue}
|
||||
}
|
||||
/// Returns true if `moduleConfig` has been explicitly set.
|
||||
var hasModuleConfig: Bool {return self._moduleConfig != nil}
|
||||
public var hasModuleConfig: Bool {return self._moduleConfig != nil}
|
||||
/// Clears the value of `moduleConfig`. Subsequent reads from it will return its default value.
|
||||
mutating func clearModuleConfig() {self._moduleConfig = nil}
|
||||
public mutating func clearModuleConfig() {self._moduleConfig = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _longName: String? = nil
|
||||
fileprivate var _shortName: String? = nil
|
||||
|
|
@ -103,8 +103,8 @@ extension DeviceProfile: @unchecked Sendable {}
|
|||
fileprivate let _protobuf_package = "meshtastic"
|
||||
|
||||
extension DeviceProfile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".DeviceProfile"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
|
|
@ -112,7 +112,7 @@ extension DeviceProfile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa
|
|||
5: .standard(proto: "module_config"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -128,7 +128,7 @@ extension DeviceProfile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
|
|
@ -151,7 +151,7 @@ extension DeviceProfile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: DeviceProfile, rhs: DeviceProfile) -> Bool {
|
||||
public static func ==(lhs: DeviceProfile, rhs: DeviceProfile) -> Bool {
|
||||
if lhs._longName != rhs._longName {return false}
|
||||
if lhs._shortName != rhs._shortName {return false}
|
||||
if lhs._channelURL != rhs._channelURL {return false}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -20,58 +20,58 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
|
|||
typealias Version = _2
|
||||
}
|
||||
|
||||
struct DeviceConnectionStatus {
|
||||
public struct DeviceConnectionStatus {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// WiFi Status
|
||||
var wifi: WifiConnectionStatus {
|
||||
public var wifi: WifiConnectionStatus {
|
||||
get {return _wifi ?? WifiConnectionStatus()}
|
||||
set {_wifi = newValue}
|
||||
}
|
||||
/// Returns true if `wifi` has been explicitly set.
|
||||
var hasWifi: Bool {return self._wifi != nil}
|
||||
public var hasWifi: Bool {return self._wifi != nil}
|
||||
/// Clears the value of `wifi`. Subsequent reads from it will return its default value.
|
||||
mutating func clearWifi() {self._wifi = nil}
|
||||
public mutating func clearWifi() {self._wifi = nil}
|
||||
|
||||
///
|
||||
/// WiFi Status
|
||||
var ethernet: EthernetConnectionStatus {
|
||||
public var ethernet: EthernetConnectionStatus {
|
||||
get {return _ethernet ?? EthernetConnectionStatus()}
|
||||
set {_ethernet = newValue}
|
||||
}
|
||||
/// Returns true if `ethernet` has been explicitly set.
|
||||
var hasEthernet: Bool {return self._ethernet != nil}
|
||||
public var hasEthernet: Bool {return self._ethernet != nil}
|
||||
/// Clears the value of `ethernet`. Subsequent reads from it will return its default value.
|
||||
mutating func clearEthernet() {self._ethernet = nil}
|
||||
public mutating func clearEthernet() {self._ethernet = nil}
|
||||
|
||||
///
|
||||
/// Bluetooth Status
|
||||
var bluetooth: BluetoothConnectionStatus {
|
||||
public var bluetooth: BluetoothConnectionStatus {
|
||||
get {return _bluetooth ?? BluetoothConnectionStatus()}
|
||||
set {_bluetooth = newValue}
|
||||
}
|
||||
/// Returns true if `bluetooth` has been explicitly set.
|
||||
var hasBluetooth: Bool {return self._bluetooth != nil}
|
||||
public var hasBluetooth: Bool {return self._bluetooth != nil}
|
||||
/// Clears the value of `bluetooth`. Subsequent reads from it will return its default value.
|
||||
mutating func clearBluetooth() {self._bluetooth = nil}
|
||||
public mutating func clearBluetooth() {self._bluetooth = nil}
|
||||
|
||||
///
|
||||
/// Serial Status
|
||||
var serial: SerialConnectionStatus {
|
||||
public var serial: SerialConnectionStatus {
|
||||
get {return _serial ?? SerialConnectionStatus()}
|
||||
set {_serial = newValue}
|
||||
}
|
||||
/// Returns true if `serial` has been explicitly set.
|
||||
var hasSerial: Bool {return self._serial != nil}
|
||||
public var hasSerial: Bool {return self._serial != nil}
|
||||
/// Clears the value of `serial`. Subsequent reads from it will return its default value.
|
||||
mutating func clearSerial() {self._serial = nil}
|
||||
public mutating func clearSerial() {self._serial = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _wifi: WifiConnectionStatus? = nil
|
||||
fileprivate var _ethernet: EthernetConnectionStatus? = nil
|
||||
|
|
@ -81,132 +81,132 @@ struct DeviceConnectionStatus {
|
|||
|
||||
///
|
||||
/// WiFi connection status
|
||||
struct WifiConnectionStatus {
|
||||
public struct WifiConnectionStatus {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Connection status
|
||||
var status: NetworkConnectionStatus {
|
||||
public var status: NetworkConnectionStatus {
|
||||
get {return _status ?? NetworkConnectionStatus()}
|
||||
set {_status = newValue}
|
||||
}
|
||||
/// Returns true if `status` has been explicitly set.
|
||||
var hasStatus: Bool {return self._status != nil}
|
||||
public var hasStatus: Bool {return self._status != nil}
|
||||
/// Clears the value of `status`. Subsequent reads from it will return its default value.
|
||||
mutating func clearStatus() {self._status = nil}
|
||||
public mutating func clearStatus() {self._status = nil}
|
||||
|
||||
///
|
||||
/// WiFi access point SSID
|
||||
var ssid: String = String()
|
||||
public var ssid: String = String()
|
||||
|
||||
///
|
||||
/// RSSI of wireless connection
|
||||
var rssi: Int32 = 0
|
||||
public var rssi: Int32 = 0
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _status: NetworkConnectionStatus? = nil
|
||||
}
|
||||
|
||||
///
|
||||
/// Ethernet connection status
|
||||
struct EthernetConnectionStatus {
|
||||
public struct EthernetConnectionStatus {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Connection status
|
||||
var status: NetworkConnectionStatus {
|
||||
public var status: NetworkConnectionStatus {
|
||||
get {return _status ?? NetworkConnectionStatus()}
|
||||
set {_status = newValue}
|
||||
}
|
||||
/// Returns true if `status` has been explicitly set.
|
||||
var hasStatus: Bool {return self._status != nil}
|
||||
public var hasStatus: Bool {return self._status != nil}
|
||||
/// Clears the value of `status`. Subsequent reads from it will return its default value.
|
||||
mutating func clearStatus() {self._status = nil}
|
||||
public mutating func clearStatus() {self._status = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _status: NetworkConnectionStatus? = nil
|
||||
}
|
||||
|
||||
///
|
||||
/// Ethernet or WiFi connection status
|
||||
struct NetworkConnectionStatus {
|
||||
public struct NetworkConnectionStatus {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// IP address of device
|
||||
var ipAddress: UInt32 = 0
|
||||
public var ipAddress: UInt32 = 0
|
||||
|
||||
///
|
||||
/// Whether the device has an active connection or not
|
||||
var isConnected: Bool = false
|
||||
public var isConnected: Bool = false
|
||||
|
||||
///
|
||||
/// Whether the device has an active connection to an MQTT broker or not
|
||||
var isMqttConnected: Bool = false
|
||||
public var isMqttConnected: Bool = false
|
||||
|
||||
///
|
||||
/// Whether the device is actively remote syslogging or not
|
||||
var isSyslogConnected: Bool = false
|
||||
public var isSyslogConnected: Bool = false
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
///
|
||||
/// Bluetooth connection status
|
||||
struct BluetoothConnectionStatus {
|
||||
public struct BluetoothConnectionStatus {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// The pairing PIN for bluetooth
|
||||
var pin: UInt32 = 0
|
||||
public var pin: UInt32 = 0
|
||||
|
||||
///
|
||||
/// RSSI of bluetooth connection
|
||||
var rssi: Int32 = 0
|
||||
public var rssi: Int32 = 0
|
||||
|
||||
///
|
||||
/// Whether the device has an active connection or not
|
||||
var isConnected: Bool = false
|
||||
public var isConnected: Bool = false
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
///
|
||||
/// Serial connection status
|
||||
struct SerialConnectionStatus {
|
||||
public struct SerialConnectionStatus {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Serial baud rate
|
||||
var baud: UInt32 = 0
|
||||
public var baud: UInt32 = 0
|
||||
|
||||
///
|
||||
/// Whether the device has an active connection or not
|
||||
var isConnected: Bool = false
|
||||
public var isConnected: Bool = false
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
#if swift(>=5.5) && canImport(_Concurrency)
|
||||
|
|
@ -223,15 +223,15 @@ extension SerialConnectionStatus: @unchecked Sendable {}
|
|||
fileprivate let _protobuf_package = "meshtastic"
|
||||
|
||||
extension DeviceConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".DeviceConnectionStatus"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -246,7 +246,7 @@ extension DeviceConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageI
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
|
|
@ -266,7 +266,7 @@ extension DeviceConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageI
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: DeviceConnectionStatus, rhs: DeviceConnectionStatus) -> Bool {
|
||||
public static func ==(lhs: DeviceConnectionStatus, rhs: DeviceConnectionStatus) -> Bool {
|
||||
if lhs._wifi != rhs._wifi {return false}
|
||||
if lhs._ethernet != rhs._ethernet {return false}
|
||||
if lhs._bluetooth != rhs._bluetooth {return false}
|
||||
|
|
@ -277,14 +277,14 @@ extension DeviceConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageI
|
|||
}
|
||||
|
||||
extension WifiConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".WifiConnectionStatus"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -298,7 +298,7 @@ extension WifiConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
|
|
@ -315,7 +315,7 @@ extension WifiConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: WifiConnectionStatus, rhs: WifiConnectionStatus) -> Bool {
|
||||
public static func ==(lhs: WifiConnectionStatus, rhs: WifiConnectionStatus) -> Bool {
|
||||
if lhs._status != rhs._status {return false}
|
||||
if lhs.ssid != rhs.ssid {return false}
|
||||
if lhs.rssi != rhs.rssi {return false}
|
||||
|
|
@ -325,12 +325,12 @@ extension WifiConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
|
|||
}
|
||||
|
||||
extension EthernetConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".EthernetConnectionStatus"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let protoMessageName: String = _protobuf_package + ".EthernetConnectionStatus"
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "status"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -342,7 +342,7 @@ extension EthernetConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Messag
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
|
|
@ -353,7 +353,7 @@ extension EthernetConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Messag
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: EthernetConnectionStatus, rhs: EthernetConnectionStatus) -> Bool {
|
||||
public static func ==(lhs: EthernetConnectionStatus, rhs: EthernetConnectionStatus) -> Bool {
|
||||
if lhs._status != rhs._status {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
|
|
@ -361,15 +361,15 @@ extension EthernetConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Messag
|
|||
}
|
||||
|
||||
extension NetworkConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".NetworkConnectionStatus"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -384,7 +384,7 @@ extension NetworkConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Message
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if self.ipAddress != 0 {
|
||||
try visitor.visitSingularFixed32Field(value: self.ipAddress, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -400,7 +400,7 @@ extension NetworkConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Message
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: NetworkConnectionStatus, rhs: NetworkConnectionStatus) -> Bool {
|
||||
public static func ==(lhs: NetworkConnectionStatus, rhs: NetworkConnectionStatus) -> Bool {
|
||||
if lhs.ipAddress != rhs.ipAddress {return false}
|
||||
if lhs.isConnected != rhs.isConnected {return false}
|
||||
if lhs.isMqttConnected != rhs.isMqttConnected {return false}
|
||||
|
|
@ -411,14 +411,14 @@ extension NetworkConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Message
|
|||
}
|
||||
|
||||
extension BluetoothConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".BluetoothConnectionStatus"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -432,7 +432,7 @@ extension BluetoothConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Messa
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if self.pin != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.pin, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -445,7 +445,7 @@ extension BluetoothConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Messa
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: BluetoothConnectionStatus, rhs: BluetoothConnectionStatus) -> Bool {
|
||||
public static func ==(lhs: BluetoothConnectionStatus, rhs: BluetoothConnectionStatus) -> Bool {
|
||||
if lhs.pin != rhs.pin {return false}
|
||||
if lhs.rssi != rhs.rssi {return false}
|
||||
if lhs.isConnected != rhs.isConnected {return false}
|
||||
|
|
@ -455,13 +455,13 @@ extension BluetoothConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Messa
|
|||
}
|
||||
|
||||
extension SerialConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".SerialConnectionStatus"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let protoMessageName: String = _protobuf_package + ".SerialConnectionStatus"
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "baud"),
|
||||
2: .standard(proto: "is_connected"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -474,7 +474,7 @@ extension SerialConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageI
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if self.baud != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.baud, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -484,7 +484,7 @@ extension SerialConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageI
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: SerialConnectionStatus, rhs: SerialConnectionStatus) -> Bool {
|
||||
public static func ==(lhs: SerialConnectionStatus, rhs: SerialConnectionStatus) -> Bool {
|
||||
if lhs.baud != rhs.baud {return false}
|
||||
if lhs.isConnected != rhs.isConnected {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
|
|
@ -22,8 +22,8 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
|
|||
|
||||
///
|
||||
/// Font sizes for the device screen
|
||||
enum ScreenFonts: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
public enum ScreenFonts: SwiftProtobuf.Enum {
|
||||
public typealias RawValue = Int
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
|
|
@ -38,11 +38,11 @@ enum ScreenFonts: SwiftProtobuf.Enum {
|
|||
case fontLarge // = 2
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
public init() {
|
||||
self = .fontSmall
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
public init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .fontSmall
|
||||
case 1: self = .fontMedium
|
||||
|
|
@ -51,7 +51,7 @@ enum ScreenFonts: SwiftProtobuf.Enum {
|
|||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
public var rawValue: Int {
|
||||
switch self {
|
||||
case .fontSmall: return 0
|
||||
case .fontMedium: return 1
|
||||
|
|
@ -66,7 +66,7 @@ enum ScreenFonts: SwiftProtobuf.Enum {
|
|||
|
||||
extension ScreenFonts: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static let allCases: [ScreenFonts] = [
|
||||
public static let allCases: [ScreenFonts] = [
|
||||
.fontSmall,
|
||||
.fontMedium,
|
||||
.fontLarge,
|
||||
|
|
@ -77,7 +77,7 @@ extension ScreenFonts: CaseIterable {
|
|||
|
||||
///
|
||||
/// Position with static location information only for NodeDBLite
|
||||
struct PositionLite {
|
||||
public struct PositionLite {
|
||||
// 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.
|
||||
|
|
@ -85,15 +85,15 @@ struct PositionLite {
|
|||
///
|
||||
/// The new preferred location encoding, multiply by 1e-7 to get degrees
|
||||
/// in floating point
|
||||
var latitudeI: Int32 = 0
|
||||
public var latitudeI: Int32 = 0
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
var longitudeI: Int32 = 0
|
||||
public var longitudeI: Int32 = 0
|
||||
|
||||
///
|
||||
/// In meters above MSL (but see issue #359)
|
||||
var altitude: Int32 = 0
|
||||
public var altitude: Int32 = 0
|
||||
|
||||
///
|
||||
/// This is usually not sent over the mesh (to save space), but it is sent
|
||||
|
|
@ -101,95 +101,95 @@ struct PositionLite {
|
|||
/// the mesh (because there are devices on the mesh without GPS), it will only
|
||||
/// be sent by devices which has a hardware GPS clock.
|
||||
/// seconds since 1970
|
||||
var time: UInt32 = 0
|
||||
public var time: UInt32 = 0
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
var locationSource: Position.LocSource = .locUnset
|
||||
public var locationSource: Position.LocSource = .locUnset
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
struct NodeInfoLite {
|
||||
public struct NodeInfoLite {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// The node number
|
||||
var num: UInt32 {
|
||||
public var num: UInt32 {
|
||||
get {return _storage._num}
|
||||
set {_uniqueStorage()._num = newValue}
|
||||
}
|
||||
|
||||
///
|
||||
/// The user info for this node
|
||||
var user: User {
|
||||
public var user: User {
|
||||
get {return _storage._user ?? User()}
|
||||
set {_uniqueStorage()._user = newValue}
|
||||
}
|
||||
/// Returns true if `user` has been explicitly set.
|
||||
var hasUser: Bool {return _storage._user != nil}
|
||||
public var hasUser: Bool {return _storage._user != nil}
|
||||
/// Clears the value of `user`. Subsequent reads from it will return its default value.
|
||||
mutating func clearUser() {_uniqueStorage()._user = nil}
|
||||
public mutating func clearUser() {_uniqueStorage()._user = nil}
|
||||
|
||||
///
|
||||
/// This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true.
|
||||
/// Position.time now indicates the last time we received a POSITION from that node.
|
||||
var position: PositionLite {
|
||||
public var position: PositionLite {
|
||||
get {return _storage._position ?? PositionLite()}
|
||||
set {_uniqueStorage()._position = newValue}
|
||||
}
|
||||
/// Returns true if `position` has been explicitly set.
|
||||
var hasPosition: Bool {return _storage._position != nil}
|
||||
public var hasPosition: Bool {return _storage._position != nil}
|
||||
/// Clears the value of `position`. Subsequent reads from it will return its default value.
|
||||
mutating func clearPosition() {_uniqueStorage()._position = nil}
|
||||
public mutating func clearPosition() {_uniqueStorage()._position = nil}
|
||||
|
||||
///
|
||||
/// Returns the Signal-to-noise ratio (SNR) of the last received message,
|
||||
/// as measured by the receiver. Return SNR of the last received message in dB
|
||||
var snr: Float {
|
||||
public var snr: Float {
|
||||
get {return _storage._snr}
|
||||
set {_uniqueStorage()._snr = newValue}
|
||||
}
|
||||
|
||||
///
|
||||
/// Set to indicate the last time we received a packet from this node
|
||||
var lastHeard: UInt32 {
|
||||
public var lastHeard: UInt32 {
|
||||
get {return _storage._lastHeard}
|
||||
set {_uniqueStorage()._lastHeard = newValue}
|
||||
}
|
||||
|
||||
///
|
||||
/// The latest device metrics for the node.
|
||||
var deviceMetrics: DeviceMetrics {
|
||||
public var deviceMetrics: DeviceMetrics {
|
||||
get {return _storage._deviceMetrics ?? DeviceMetrics()}
|
||||
set {_uniqueStorage()._deviceMetrics = newValue}
|
||||
}
|
||||
/// Returns true if `deviceMetrics` has been explicitly set.
|
||||
var hasDeviceMetrics: Bool {return _storage._deviceMetrics != nil}
|
||||
public var hasDeviceMetrics: Bool {return _storage._deviceMetrics != nil}
|
||||
/// Clears the value of `deviceMetrics`. Subsequent reads from it will return its default value.
|
||||
mutating func clearDeviceMetrics() {_uniqueStorage()._deviceMetrics = nil}
|
||||
public mutating func clearDeviceMetrics() {_uniqueStorage()._deviceMetrics = nil}
|
||||
|
||||
///
|
||||
/// local channel index we heard that node on. Only populated if its not the default channel.
|
||||
var channel: UInt32 {
|
||||
public var channel: UInt32 {
|
||||
get {return _storage._channel}
|
||||
set {_uniqueStorage()._channel = newValue}
|
||||
}
|
||||
|
||||
///
|
||||
/// True if we witnessed the node over MQTT instead of LoRA transport
|
||||
var viaMqtt: Bool {
|
||||
public var viaMqtt: Bool {
|
||||
get {return _storage._viaMqtt}
|
||||
set {_uniqueStorage()._viaMqtt = newValue}
|
||||
}
|
||||
|
||||
///
|
||||
/// Number of hops away from us this node is (0 if adjacent)
|
||||
var hopsAway: UInt32 {
|
||||
public var hopsAway: UInt32 {
|
||||
get {return _storage._hopsAway}
|
||||
set {_uniqueStorage()._hopsAway = newValue}
|
||||
}
|
||||
|
|
@ -197,14 +197,14 @@ struct NodeInfoLite {
|
|||
///
|
||||
/// True if node is in our favorites list
|
||||
/// Persists between NodeDB internal clean ups
|
||||
var isFavorite: Bool {
|
||||
public var isFavorite: Bool {
|
||||
get {return _storage._isFavorite}
|
||||
set {_uniqueStorage()._isFavorite = newValue}
|
||||
}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _storage = _StorageClass.defaultInstance
|
||||
}
|
||||
|
|
@ -215,36 +215,36 @@ 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
|
||||
struct DeviceState {
|
||||
public struct DeviceState {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// Read only settings/info about this node
|
||||
var myNode: MyNodeInfo {
|
||||
public var myNode: MyNodeInfo {
|
||||
get {return _storage._myNode ?? MyNodeInfo()}
|
||||
set {_uniqueStorage()._myNode = newValue}
|
||||
}
|
||||
/// Returns true if `myNode` has been explicitly set.
|
||||
var hasMyNode: Bool {return _storage._myNode != nil}
|
||||
public var hasMyNode: Bool {return _storage._myNode != nil}
|
||||
/// Clears the value of `myNode`. Subsequent reads from it will return its default value.
|
||||
mutating func clearMyNode() {_uniqueStorage()._myNode = nil}
|
||||
public mutating func clearMyNode() {_uniqueStorage()._myNode = nil}
|
||||
|
||||
///
|
||||
/// My owner info
|
||||
var owner: User {
|
||||
public var owner: User {
|
||||
get {return _storage._owner ?? User()}
|
||||
set {_uniqueStorage()._owner = newValue}
|
||||
}
|
||||
/// Returns true if `owner` has been explicitly set.
|
||||
var hasOwner: Bool {return _storage._owner != nil}
|
||||
public var hasOwner: Bool {return _storage._owner != nil}
|
||||
/// Clears the value of `owner`. Subsequent reads from it will return its default value.
|
||||
mutating func clearOwner() {_uniqueStorage()._owner = nil}
|
||||
public mutating func clearOwner() {_uniqueStorage()._owner = nil}
|
||||
|
||||
///
|
||||
/// Received packets saved for delivery to the phone
|
||||
var receiveQueue: [MeshPacket] {
|
||||
public var receiveQueue: [MeshPacket] {
|
||||
get {return _storage._receiveQueue}
|
||||
set {_uniqueStorage()._receiveQueue = newValue}
|
||||
}
|
||||
|
|
@ -253,7 +253,7 @@ struct DeviceState {
|
|||
/// A version integer used to invalidate old save files when we make
|
||||
/// incompatible changes This integer is set at build time and is private to
|
||||
/// NodeDB.cpp in the device code.
|
||||
var version: UInt32 {
|
||||
public var version: UInt32 {
|
||||
get {return _storage._version}
|
||||
set {_uniqueStorage()._version = newValue}
|
||||
}
|
||||
|
|
@ -262,27 +262,27 @@ struct DeviceState {
|
|||
/// We keep the last received text message (only) stored in the device flash,
|
||||
/// so we can show it on the screen.
|
||||
/// Might be null
|
||||
var rxTextMessage: MeshPacket {
|
||||
public var rxTextMessage: MeshPacket {
|
||||
get {return _storage._rxTextMessage ?? MeshPacket()}
|
||||
set {_uniqueStorage()._rxTextMessage = newValue}
|
||||
}
|
||||
/// Returns true if `rxTextMessage` has been explicitly set.
|
||||
var hasRxTextMessage: Bool {return _storage._rxTextMessage != nil}
|
||||
public var hasRxTextMessage: Bool {return _storage._rxTextMessage != nil}
|
||||
/// Clears the value of `rxTextMessage`. Subsequent reads from it will return its default value.
|
||||
mutating func clearRxTextMessage() {_uniqueStorage()._rxTextMessage = nil}
|
||||
public mutating func clearRxTextMessage() {_uniqueStorage()._rxTextMessage = nil}
|
||||
|
||||
///
|
||||
/// Used only during development.
|
||||
/// Indicates developer is testing and changes should never be saved to flash.
|
||||
/// Deprecated in 2.3.1
|
||||
var noSave: Bool {
|
||||
public var noSave: Bool {
|
||||
get {return _storage._noSave}
|
||||
set {_uniqueStorage()._noSave = newValue}
|
||||
}
|
||||
|
||||
///
|
||||
/// Some GPS receivers seem to have bogus settings from the factory, so we always do one factory reset.
|
||||
var didGpsReset: Bool {
|
||||
public var didGpsReset: Bool {
|
||||
get {return _storage._didGpsReset}
|
||||
set {_uniqueStorage()._didGpsReset = newValue}
|
||||
}
|
||||
|
|
@ -291,115 +291,115 @@ struct DeviceState {
|
|||
/// We keep the last received waypoint stored in the device flash,
|
||||
/// so we can show it on the screen.
|
||||
/// Might be null
|
||||
var rxWaypoint: MeshPacket {
|
||||
public var rxWaypoint: MeshPacket {
|
||||
get {return _storage._rxWaypoint ?? MeshPacket()}
|
||||
set {_uniqueStorage()._rxWaypoint = newValue}
|
||||
}
|
||||
/// Returns true if `rxWaypoint` has been explicitly set.
|
||||
var hasRxWaypoint: Bool {return _storage._rxWaypoint != nil}
|
||||
public var hasRxWaypoint: Bool {return _storage._rxWaypoint != nil}
|
||||
/// Clears the value of `rxWaypoint`. Subsequent reads from it will return its default value.
|
||||
mutating func clearRxWaypoint() {_uniqueStorage()._rxWaypoint = nil}
|
||||
public mutating func clearRxWaypoint() {_uniqueStorage()._rxWaypoint = nil}
|
||||
|
||||
///
|
||||
/// The mesh's nodes with their available gpio pins for RemoteHardware module
|
||||
var nodeRemoteHardwarePins: [NodeRemoteHardwarePin] {
|
||||
public var nodeRemoteHardwarePins: [NodeRemoteHardwarePin] {
|
||||
get {return _storage._nodeRemoteHardwarePins}
|
||||
set {_uniqueStorage()._nodeRemoteHardwarePins = newValue}
|
||||
}
|
||||
|
||||
///
|
||||
/// New lite version of NodeDB to decrease memory footprint
|
||||
var nodeDbLite: [NodeInfoLite] {
|
||||
public var nodeDbLite: [NodeInfoLite] {
|
||||
get {return _storage._nodeDbLite}
|
||||
set {_uniqueStorage()._nodeDbLite = newValue}
|
||||
}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _storage = _StorageClass.defaultInstance
|
||||
}
|
||||
|
||||
///
|
||||
/// The on-disk saved channels
|
||||
struct ChannelFile {
|
||||
public struct ChannelFile {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// The channels our node knows about
|
||||
var channels: [Channel] = []
|
||||
public var channels: [Channel] = []
|
||||
|
||||
///
|
||||
/// A version integer used to invalidate old save files when we make
|
||||
/// incompatible changes This integer is set at build time and is private to
|
||||
/// NodeDB.cpp in the device code.
|
||||
var version: UInt32 = 0
|
||||
public var version: UInt32 = 0
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
///
|
||||
/// This can be used for customizing the firmware distribution. If populated,
|
||||
/// show a secondary bootup screen with custom logo and text for 2.5 seconds.
|
||||
struct OEMStore {
|
||||
public struct OEMStore {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// The Logo width in Px
|
||||
var oemIconWidth: UInt32 = 0
|
||||
public var oemIconWidth: UInt32 = 0
|
||||
|
||||
///
|
||||
/// The Logo height in Px
|
||||
var oemIconHeight: UInt32 = 0
|
||||
public var oemIconHeight: UInt32 = 0
|
||||
|
||||
///
|
||||
/// The Logo in XBM bytechar format
|
||||
var oemIconBits: Data = Data()
|
||||
public var oemIconBits: Data = Data()
|
||||
|
||||
///
|
||||
/// Use this font for the OEM text.
|
||||
var oemFont: ScreenFonts = .fontSmall
|
||||
public var oemFont: ScreenFonts = .fontSmall
|
||||
|
||||
///
|
||||
/// Use this font for the OEM text.
|
||||
var oemText: String = String()
|
||||
public var oemText: String = String()
|
||||
|
||||
///
|
||||
/// The default device encryption key, 16 or 32 byte
|
||||
var oemAesKey: Data = Data()
|
||||
public var oemAesKey: Data = Data()
|
||||
|
||||
///
|
||||
/// A Preset LocalConfig to apply during factory reset
|
||||
var oemLocalConfig: LocalConfig {
|
||||
public var oemLocalConfig: LocalConfig {
|
||||
get {return _oemLocalConfig ?? LocalConfig()}
|
||||
set {_oemLocalConfig = newValue}
|
||||
}
|
||||
/// Returns true if `oemLocalConfig` has been explicitly set.
|
||||
var hasOemLocalConfig: Bool {return self._oemLocalConfig != nil}
|
||||
public var hasOemLocalConfig: Bool {return self._oemLocalConfig != nil}
|
||||
/// Clears the value of `oemLocalConfig`. Subsequent reads from it will return its default value.
|
||||
mutating func clearOemLocalConfig() {self._oemLocalConfig = nil}
|
||||
public mutating func clearOemLocalConfig() {self._oemLocalConfig = nil}
|
||||
|
||||
///
|
||||
/// A Preset LocalModuleConfig to apply during factory reset
|
||||
var oemLocalModuleConfig: LocalModuleConfig {
|
||||
public var oemLocalModuleConfig: LocalModuleConfig {
|
||||
get {return _oemLocalModuleConfig ?? LocalModuleConfig()}
|
||||
set {_oemLocalModuleConfig = newValue}
|
||||
}
|
||||
/// Returns true if `oemLocalModuleConfig` has been explicitly set.
|
||||
var hasOemLocalModuleConfig: Bool {return self._oemLocalModuleConfig != nil}
|
||||
public var hasOemLocalModuleConfig: Bool {return self._oemLocalModuleConfig != nil}
|
||||
/// Clears the value of `oemLocalModuleConfig`. Subsequent reads from it will return its default value.
|
||||
mutating func clearOemLocalModuleConfig() {self._oemLocalModuleConfig = nil}
|
||||
public mutating func clearOemLocalModuleConfig() {self._oemLocalModuleConfig = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _oemLocalConfig: LocalConfig? = nil
|
||||
fileprivate var _oemLocalModuleConfig: LocalModuleConfig? = nil
|
||||
|
|
@ -419,7 +419,7 @@ extension OEMStore: @unchecked Sendable {}
|
|||
fileprivate let _protobuf_package = "meshtastic"
|
||||
|
||||
extension ScreenFonts: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "FONT_SMALL"),
|
||||
1: .same(proto: "FONT_MEDIUM"),
|
||||
2: .same(proto: "FONT_LARGE"),
|
||||
|
|
@ -427,8 +427,8 @@ extension ScreenFonts: SwiftProtobuf._ProtoNameProviding {
|
|||
}
|
||||
|
||||
extension PositionLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".PositionLite"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
|
|
@ -436,7 +436,7 @@ extension PositionLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
5: .standard(proto: "location_source"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -452,7 +452,7 @@ extension PositionLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if self.latitudeI != 0 {
|
||||
try visitor.visitSingularSFixed32Field(value: self.latitudeI, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -471,7 +471,7 @@ extension PositionLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: PositionLite, rhs: PositionLite) -> Bool {
|
||||
public static func ==(lhs: PositionLite, rhs: PositionLite) -> Bool {
|
||||
if lhs.latitudeI != rhs.latitudeI {return false}
|
||||
if lhs.longitudeI != rhs.longitudeI {return false}
|
||||
if lhs.altitude != rhs.altitude {return false}
|
||||
|
|
@ -483,8 +483,8 @@ extension PositionLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
}
|
||||
|
||||
extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".NodeInfoLite"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
|
|
@ -542,7 +542,7 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
return _storage
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
_ = _uniqueStorage()
|
||||
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
@ -566,7 +566,7 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
|
|
@ -606,7 +606,7 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: NodeInfoLite, rhs: NodeInfoLite) -> Bool {
|
||||
public static func ==(lhs: NodeInfoLite, rhs: NodeInfoLite) -> Bool {
|
||||
if lhs._storage !== rhs._storage {
|
||||
let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in
|
||||
let _storage = _args.0
|
||||
|
|
@ -631,8 +631,8 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
|
|||
}
|
||||
|
||||
extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".DeviceState"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
|
|
@ -690,7 +690,7 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
return _storage
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
_ = _uniqueStorage()
|
||||
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
@ -714,7 +714,7 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
|
|
@ -754,7 +754,7 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: DeviceState, rhs: DeviceState) -> Bool {
|
||||
public static func ==(lhs: DeviceState, rhs: DeviceState) -> Bool {
|
||||
if lhs._storage !== rhs._storage {
|
||||
let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in
|
||||
let _storage = _args.0
|
||||
|
|
@ -779,13 +779,13 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
}
|
||||
|
||||
extension ChannelFile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".ChannelFile"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let protoMessageName: String = _protobuf_package + ".ChannelFile"
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "channels"),
|
||||
2: .same(proto: "version"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -798,7 +798,7 @@ extension ChannelFile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if !self.channels.isEmpty {
|
||||
try visitor.visitRepeatedMessageField(value: self.channels, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -808,7 +808,7 @@ extension ChannelFile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: ChannelFile, rhs: ChannelFile) -> Bool {
|
||||
public static func ==(lhs: ChannelFile, rhs: ChannelFile) -> Bool {
|
||||
if lhs.channels != rhs.channels {return false}
|
||||
if lhs.version != rhs.version {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
|
|
@ -817,8 +817,8 @@ extension ChannelFile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
}
|
||||
|
||||
extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".OEMStore"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
public static let protoMessageName: String = _protobuf_package + ".OEMStore"
|
||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "oem_icon_width"),
|
||||
2: .standard(proto: "oem_icon_height"),
|
||||
3: .standard(proto: "oem_icon_bits"),
|
||||
|
|
@ -829,7 +829,7 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
8: .standard(proto: "oem_local_module_config"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -848,7 +848,7 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
|
|
@ -880,7 +880,7 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: OEMStore, rhs: OEMStore) -> Bool {
|
||||
public static func ==(lhs: OEMStore, rhs: OEMStore) -> Bool {
|
||||
if lhs.oemIconWidth != rhs.oemIconWidth {return false}
|
||||
if lhs.oemIconHeight != rhs.oemIconHeight {return false}
|
||||
if lhs.oemIconBits != rhs.oemIconBits {return false}
|
||||
|
|
@ -20,264 +20,264 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
|
|||
typealias Version = _2
|
||||
}
|
||||
|
||||
struct LocalConfig {
|
||||
public struct LocalConfig {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Device
|
||||
var device: Config.DeviceConfig {
|
||||
public var device: Config.DeviceConfig {
|
||||
get {return _storage._device ?? Config.DeviceConfig()}
|
||||
set {_uniqueStorage()._device = newValue}
|
||||
}
|
||||
/// Returns true if `device` has been explicitly set.
|
||||
var hasDevice: Bool {return _storage._device != nil}
|
||||
public var hasDevice: Bool {return _storage._device != nil}
|
||||
/// Clears the value of `device`. Subsequent reads from it will return its default value.
|
||||
mutating func clearDevice() {_uniqueStorage()._device = nil}
|
||||
public mutating func clearDevice() {_uniqueStorage()._device = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the GPS Position
|
||||
var position: Config.PositionConfig {
|
||||
public var position: Config.PositionConfig {
|
||||
get {return _storage._position ?? Config.PositionConfig()}
|
||||
set {_uniqueStorage()._position = newValue}
|
||||
}
|
||||
/// Returns true if `position` has been explicitly set.
|
||||
var hasPosition: Bool {return _storage._position != nil}
|
||||
public var hasPosition: Bool {return _storage._position != nil}
|
||||
/// Clears the value of `position`. Subsequent reads from it will return its default value.
|
||||
mutating func clearPosition() {_uniqueStorage()._position = nil}
|
||||
public mutating func clearPosition() {_uniqueStorage()._position = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Power settings
|
||||
var power: Config.PowerConfig {
|
||||
public var power: Config.PowerConfig {
|
||||
get {return _storage._power ?? Config.PowerConfig()}
|
||||
set {_uniqueStorage()._power = newValue}
|
||||
}
|
||||
/// Returns true if `power` has been explicitly set.
|
||||
var hasPower: Bool {return _storage._power != nil}
|
||||
public var hasPower: Bool {return _storage._power != nil}
|
||||
/// Clears the value of `power`. Subsequent reads from it will return its default value.
|
||||
mutating func clearPower() {_uniqueStorage()._power = nil}
|
||||
public mutating func clearPower() {_uniqueStorage()._power = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Wifi Settings
|
||||
var network: Config.NetworkConfig {
|
||||
public var network: Config.NetworkConfig {
|
||||
get {return _storage._network ?? Config.NetworkConfig()}
|
||||
set {_uniqueStorage()._network = newValue}
|
||||
}
|
||||
/// Returns true if `network` has been explicitly set.
|
||||
var hasNetwork: Bool {return _storage._network != nil}
|
||||
public var hasNetwork: Bool {return _storage._network != nil}
|
||||
/// Clears the value of `network`. Subsequent reads from it will return its default value.
|
||||
mutating func clearNetwork() {_uniqueStorage()._network = nil}
|
||||
public mutating func clearNetwork() {_uniqueStorage()._network = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Display
|
||||
var display: Config.DisplayConfig {
|
||||
public var display: Config.DisplayConfig {
|
||||
get {return _storage._display ?? Config.DisplayConfig()}
|
||||
set {_uniqueStorage()._display = newValue}
|
||||
}
|
||||
/// Returns true if `display` has been explicitly set.
|
||||
var hasDisplay: Bool {return _storage._display != nil}
|
||||
public var hasDisplay: Bool {return _storage._display != nil}
|
||||
/// Clears the value of `display`. Subsequent reads from it will return its default value.
|
||||
mutating func clearDisplay() {_uniqueStorage()._display = nil}
|
||||
public mutating func clearDisplay() {_uniqueStorage()._display = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Lora Radio
|
||||
var lora: Config.LoRaConfig {
|
||||
public var lora: Config.LoRaConfig {
|
||||
get {return _storage._lora ?? Config.LoRaConfig()}
|
||||
set {_uniqueStorage()._lora = newValue}
|
||||
}
|
||||
/// Returns true if `lora` has been explicitly set.
|
||||
var hasLora: Bool {return _storage._lora != nil}
|
||||
public var hasLora: Bool {return _storage._lora != nil}
|
||||
/// Clears the value of `lora`. Subsequent reads from it will return its default value.
|
||||
mutating func clearLora() {_uniqueStorage()._lora = nil}
|
||||
public mutating func clearLora() {_uniqueStorage()._lora = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Bluetooth settings
|
||||
var bluetooth: Config.BluetoothConfig {
|
||||
public var bluetooth: Config.BluetoothConfig {
|
||||
get {return _storage._bluetooth ?? Config.BluetoothConfig()}
|
||||
set {_uniqueStorage()._bluetooth = newValue}
|
||||
}
|
||||
/// Returns true if `bluetooth` has been explicitly set.
|
||||
var hasBluetooth: Bool {return _storage._bluetooth != nil}
|
||||
public var hasBluetooth: Bool {return _storage._bluetooth != nil}
|
||||
/// Clears the value of `bluetooth`. Subsequent reads from it will return its default value.
|
||||
mutating func clearBluetooth() {_uniqueStorage()._bluetooth = nil}
|
||||
public mutating func clearBluetooth() {_uniqueStorage()._bluetooth = nil}
|
||||
|
||||
///
|
||||
/// A version integer used to invalidate old save files when we make
|
||||
/// incompatible changes This integer is set at build time and is private to
|
||||
/// NodeDB.cpp in the device code.
|
||||
var version: UInt32 {
|
||||
public var version: UInt32 {
|
||||
get {return _storage._version}
|
||||
set {_uniqueStorage()._version = newValue}
|
||||
}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _storage = _StorageClass.defaultInstance
|
||||
}
|
||||
|
||||
struct LocalModuleConfig {
|
||||
public struct LocalModuleConfig {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the MQTT module
|
||||
var mqtt: ModuleConfig.MQTTConfig {
|
||||
public var mqtt: ModuleConfig.MQTTConfig {
|
||||
get {return _storage._mqtt ?? ModuleConfig.MQTTConfig()}
|
||||
set {_uniqueStorage()._mqtt = newValue}
|
||||
}
|
||||
/// Returns true if `mqtt` has been explicitly set.
|
||||
var hasMqtt: Bool {return _storage._mqtt != nil}
|
||||
public var hasMqtt: Bool {return _storage._mqtt != nil}
|
||||
/// Clears the value of `mqtt`. Subsequent reads from it will return its default value.
|
||||
mutating func clearMqtt() {_uniqueStorage()._mqtt = nil}
|
||||
public mutating func clearMqtt() {_uniqueStorage()._mqtt = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Serial module
|
||||
var serial: ModuleConfig.SerialConfig {
|
||||
public var serial: ModuleConfig.SerialConfig {
|
||||
get {return _storage._serial ?? ModuleConfig.SerialConfig()}
|
||||
set {_uniqueStorage()._serial = newValue}
|
||||
}
|
||||
/// Returns true if `serial` has been explicitly set.
|
||||
var hasSerial: Bool {return _storage._serial != nil}
|
||||
public var hasSerial: Bool {return _storage._serial != nil}
|
||||
/// Clears the value of `serial`. Subsequent reads from it will return its default value.
|
||||
mutating func clearSerial() {_uniqueStorage()._serial = nil}
|
||||
public mutating func clearSerial() {_uniqueStorage()._serial = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the ExternalNotification module
|
||||
var externalNotification: ModuleConfig.ExternalNotificationConfig {
|
||||
public var externalNotification: ModuleConfig.ExternalNotificationConfig {
|
||||
get {return _storage._externalNotification ?? ModuleConfig.ExternalNotificationConfig()}
|
||||
set {_uniqueStorage()._externalNotification = newValue}
|
||||
}
|
||||
/// Returns true if `externalNotification` has been explicitly set.
|
||||
var hasExternalNotification: Bool {return _storage._externalNotification != nil}
|
||||
public var hasExternalNotification: Bool {return _storage._externalNotification != nil}
|
||||
/// Clears the value of `externalNotification`. Subsequent reads from it will return its default value.
|
||||
mutating func clearExternalNotification() {_uniqueStorage()._externalNotification = nil}
|
||||
public mutating func clearExternalNotification() {_uniqueStorage()._externalNotification = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Store & Forward module
|
||||
var storeForward: ModuleConfig.StoreForwardConfig {
|
||||
public var storeForward: ModuleConfig.StoreForwardConfig {
|
||||
get {return _storage._storeForward ?? ModuleConfig.StoreForwardConfig()}
|
||||
set {_uniqueStorage()._storeForward = newValue}
|
||||
}
|
||||
/// Returns true if `storeForward` has been explicitly set.
|
||||
var hasStoreForward: Bool {return _storage._storeForward != nil}
|
||||
public var hasStoreForward: Bool {return _storage._storeForward != nil}
|
||||
/// Clears the value of `storeForward`. Subsequent reads from it will return its default value.
|
||||
mutating func clearStoreForward() {_uniqueStorage()._storeForward = nil}
|
||||
public mutating func clearStoreForward() {_uniqueStorage()._storeForward = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the RangeTest module
|
||||
var rangeTest: ModuleConfig.RangeTestConfig {
|
||||
public var rangeTest: ModuleConfig.RangeTestConfig {
|
||||
get {return _storage._rangeTest ?? ModuleConfig.RangeTestConfig()}
|
||||
set {_uniqueStorage()._rangeTest = newValue}
|
||||
}
|
||||
/// Returns true if `rangeTest` has been explicitly set.
|
||||
var hasRangeTest: Bool {return _storage._rangeTest != nil}
|
||||
public var hasRangeTest: Bool {return _storage._rangeTest != nil}
|
||||
/// Clears the value of `rangeTest`. Subsequent reads from it will return its default value.
|
||||
mutating func clearRangeTest() {_uniqueStorage()._rangeTest = nil}
|
||||
public mutating func clearRangeTest() {_uniqueStorage()._rangeTest = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Telemetry module
|
||||
var telemetry: ModuleConfig.TelemetryConfig {
|
||||
public var telemetry: ModuleConfig.TelemetryConfig {
|
||||
get {return _storage._telemetry ?? ModuleConfig.TelemetryConfig()}
|
||||
set {_uniqueStorage()._telemetry = newValue}
|
||||
}
|
||||
/// Returns true if `telemetry` has been explicitly set.
|
||||
var hasTelemetry: Bool {return _storage._telemetry != nil}
|
||||
public var hasTelemetry: Bool {return _storage._telemetry != nil}
|
||||
/// Clears the value of `telemetry`. Subsequent reads from it will return its default value.
|
||||
mutating func clearTelemetry() {_uniqueStorage()._telemetry = nil}
|
||||
public mutating func clearTelemetry() {_uniqueStorage()._telemetry = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Canned Message module
|
||||
var cannedMessage: ModuleConfig.CannedMessageConfig {
|
||||
public var cannedMessage: ModuleConfig.CannedMessageConfig {
|
||||
get {return _storage._cannedMessage ?? ModuleConfig.CannedMessageConfig()}
|
||||
set {_uniqueStorage()._cannedMessage = newValue}
|
||||
}
|
||||
/// Returns true if `cannedMessage` has been explicitly set.
|
||||
var hasCannedMessage: Bool {return _storage._cannedMessage != nil}
|
||||
public var hasCannedMessage: Bool {return _storage._cannedMessage != nil}
|
||||
/// Clears the value of `cannedMessage`. Subsequent reads from it will return its default value.
|
||||
mutating func clearCannedMessage() {_uniqueStorage()._cannedMessage = nil}
|
||||
public mutating func clearCannedMessage() {_uniqueStorage()._cannedMessage = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Audio module
|
||||
var audio: ModuleConfig.AudioConfig {
|
||||
public var audio: ModuleConfig.AudioConfig {
|
||||
get {return _storage._audio ?? ModuleConfig.AudioConfig()}
|
||||
set {_uniqueStorage()._audio = newValue}
|
||||
}
|
||||
/// Returns true if `audio` has been explicitly set.
|
||||
var hasAudio: Bool {return _storage._audio != nil}
|
||||
public var hasAudio: Bool {return _storage._audio != nil}
|
||||
/// Clears the value of `audio`. Subsequent reads from it will return its default value.
|
||||
mutating func clearAudio() {_uniqueStorage()._audio = nil}
|
||||
public mutating func clearAudio() {_uniqueStorage()._audio = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Remote Hardware module
|
||||
var remoteHardware: ModuleConfig.RemoteHardwareConfig {
|
||||
public var remoteHardware: ModuleConfig.RemoteHardwareConfig {
|
||||
get {return _storage._remoteHardware ?? ModuleConfig.RemoteHardwareConfig()}
|
||||
set {_uniqueStorage()._remoteHardware = newValue}
|
||||
}
|
||||
/// Returns true if `remoteHardware` has been explicitly set.
|
||||
var hasRemoteHardware: Bool {return _storage._remoteHardware != nil}
|
||||
public var hasRemoteHardware: Bool {return _storage._remoteHardware != nil}
|
||||
/// Clears the value of `remoteHardware`. Subsequent reads from it will return its default value.
|
||||
mutating func clearRemoteHardware() {_uniqueStorage()._remoteHardware = nil}
|
||||
public mutating func clearRemoteHardware() {_uniqueStorage()._remoteHardware = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Neighbor Info module
|
||||
var neighborInfo: ModuleConfig.NeighborInfoConfig {
|
||||
public var neighborInfo: ModuleConfig.NeighborInfoConfig {
|
||||
get {return _storage._neighborInfo ?? ModuleConfig.NeighborInfoConfig()}
|
||||
set {_uniqueStorage()._neighborInfo = newValue}
|
||||
}
|
||||
/// Returns true if `neighborInfo` has been explicitly set.
|
||||
var hasNeighborInfo: Bool {return _storage._neighborInfo != nil}
|
||||
public var hasNeighborInfo: Bool {return _storage._neighborInfo != nil}
|
||||
/// Clears the value of `neighborInfo`. Subsequent reads from it will return its default value.
|
||||
mutating func clearNeighborInfo() {_uniqueStorage()._neighborInfo = nil}
|
||||
public mutating func clearNeighborInfo() {_uniqueStorage()._neighborInfo = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Ambient Lighting module
|
||||
var ambientLighting: ModuleConfig.AmbientLightingConfig {
|
||||
public var ambientLighting: ModuleConfig.AmbientLightingConfig {
|
||||
get {return _storage._ambientLighting ?? ModuleConfig.AmbientLightingConfig()}
|
||||
set {_uniqueStorage()._ambientLighting = newValue}
|
||||
}
|
||||
/// Returns true if `ambientLighting` has been explicitly set.
|
||||
var hasAmbientLighting: Bool {return _storage._ambientLighting != nil}
|
||||
public var hasAmbientLighting: Bool {return _storage._ambientLighting != nil}
|
||||
/// Clears the value of `ambientLighting`. Subsequent reads from it will return its default value.
|
||||
mutating func clearAmbientLighting() {_uniqueStorage()._ambientLighting = nil}
|
||||
public mutating func clearAmbientLighting() {_uniqueStorage()._ambientLighting = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Detection Sensor module
|
||||
var detectionSensor: ModuleConfig.DetectionSensorConfig {
|
||||
public var detectionSensor: ModuleConfig.DetectionSensorConfig {
|
||||
get {return _storage._detectionSensor ?? ModuleConfig.DetectionSensorConfig()}
|
||||
set {_uniqueStorage()._detectionSensor = newValue}
|
||||
}
|
||||
/// Returns true if `detectionSensor` has been explicitly set.
|
||||
var hasDetectionSensor: Bool {return _storage._detectionSensor != nil}
|
||||
public var hasDetectionSensor: Bool {return _storage._detectionSensor != nil}
|
||||
/// Clears the value of `detectionSensor`. Subsequent reads from it will return its default value.
|
||||
mutating func clearDetectionSensor() {_uniqueStorage()._detectionSensor = nil}
|
||||
public mutating func clearDetectionSensor() {_uniqueStorage()._detectionSensor = nil}
|
||||
|
||||
///
|
||||
/// Paxcounter Config
|
||||
var paxcounter: ModuleConfig.PaxcounterConfig {
|
||||
public var paxcounter: ModuleConfig.PaxcounterConfig {
|
||||
get {return _storage._paxcounter ?? ModuleConfig.PaxcounterConfig()}
|
||||
set {_uniqueStorage()._paxcounter = newValue}
|
||||
}
|
||||
/// Returns true if `paxcounter` has been explicitly set.
|
||||
var hasPaxcounter: Bool {return _storage._paxcounter != nil}
|
||||
public var hasPaxcounter: Bool {return _storage._paxcounter != nil}
|
||||
/// Clears the value of `paxcounter`. Subsequent reads from it will return its default value.
|
||||
mutating func clearPaxcounter() {_uniqueStorage()._paxcounter = nil}
|
||||
public mutating func clearPaxcounter() {_uniqueStorage()._paxcounter = nil}
|
||||
|
||||
///
|
||||
/// A version integer used to invalidate old save files when we make
|
||||
/// incompatible changes This integer is set at build time and is private to
|
||||
/// NodeDB.cpp in the device code.
|
||||
var version: UInt32 {
|
||||
public var version: UInt32 {
|
||||
get {return _storage._version}
|
||||
set {_uniqueStorage()._version = newValue}
|
||||
}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _storage = _StorageClass.defaultInstance
|
||||
}
|
||||
|
|
@ -292,8 +292,8 @@ extension LocalModuleConfig: @unchecked Sendable {}
|
|||
fileprivate let _protobuf_package = "meshtastic"
|
||||
|
||||
extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".LocalConfig"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
|
|
@ -345,7 +345,7 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
return _storage
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
_ = _uniqueStorage()
|
||||
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
@ -367,7 +367,7 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
|
|
@ -401,7 +401,7 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: LocalConfig, rhs: LocalConfig) -> Bool {
|
||||
public static func ==(lhs: LocalConfig, rhs: LocalConfig) -> Bool {
|
||||
if lhs._storage !== rhs._storage {
|
||||
let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in
|
||||
let _storage = _args.0
|
||||
|
|
@ -424,8 +424,8 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
}
|
||||
|
||||
extension LocalModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".LocalModuleConfig"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
|
|
@ -495,7 +495,7 @@ extension LocalModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
return _storage
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
_ = _uniqueStorage()
|
||||
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
@ -523,7 +523,7 @@ extension LocalModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
|
|
@ -575,7 +575,7 @@ extension LocalModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: LocalModuleConfig, rhs: LocalModuleConfig) -> Bool {
|
||||
public static func ==(lhs: LocalModuleConfig, rhs: LocalModuleConfig) -> Bool {
|
||||
if lhs._storage !== rhs._storage {
|
||||
let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in
|
||||
let _storage = _args.0
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -22,103 +22,103 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
|
|||
|
||||
///
|
||||
/// This message wraps a MeshPacket with extra metadata about the sender and how it arrived.
|
||||
struct ServiceEnvelope {
|
||||
public struct ServiceEnvelope {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// The (probably encrypted) packet
|
||||
var packet: MeshPacket {
|
||||
public var packet: MeshPacket {
|
||||
get {return _packet ?? MeshPacket()}
|
||||
set {_packet = newValue}
|
||||
}
|
||||
/// Returns true if `packet` has been explicitly set.
|
||||
var hasPacket: Bool {return self._packet != nil}
|
||||
public var hasPacket: Bool {return self._packet != nil}
|
||||
/// Clears the value of `packet`. Subsequent reads from it will return its default value.
|
||||
mutating func clearPacket() {self._packet = nil}
|
||||
public mutating func clearPacket() {self._packet = nil}
|
||||
|
||||
///
|
||||
/// The global channel ID it was sent on
|
||||
var channelID: String = String()
|
||||
public var channelID: String = String()
|
||||
|
||||
///
|
||||
/// The sending gateway node ID. Can we use this to authenticate/prevent fake
|
||||
/// nodeid impersonation for senders? - i.e. use gateway/mesh id (which is authenticated) + local node id as
|
||||
/// the globally trusted nodenum
|
||||
var gatewayID: String = String()
|
||||
public var gatewayID: String = String()
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
|
||||
fileprivate var _packet: MeshPacket? = nil
|
||||
}
|
||||
|
||||
///
|
||||
/// Information about a node intended to be reported unencrypted to a map using MQTT.
|
||||
struct MapReport {
|
||||
public struct MapReport {
|
||||
// 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.
|
||||
|
||||
///
|
||||
/// A full name for this user, i.e. "Kevin Hester"
|
||||
var longName: String = String()
|
||||
public var longName: String = String()
|
||||
|
||||
///
|
||||
/// A VERY short name, ideally two characters.
|
||||
/// Suitable for a tiny OLED screen
|
||||
var shortName: String = String()
|
||||
public var shortName: String = String()
|
||||
|
||||
///
|
||||
/// Role of the node that applies specific settings for a particular use-case
|
||||
var role: Config.DeviceConfig.Role = .client
|
||||
public var role: Config.DeviceConfig.Role = .client
|
||||
|
||||
///
|
||||
/// Hardware model of the node, i.e. T-Beam, Heltec V3, etc...
|
||||
var hwModel: HardwareModel = .unset
|
||||
public var hwModel: HardwareModel = .unset
|
||||
|
||||
///
|
||||
/// Device firmware version string
|
||||
var firmwareVersion: String = String()
|
||||
public var firmwareVersion: String = String()
|
||||
|
||||
///
|
||||
/// The region code for the radio (US, CN, EU433, etc...)
|
||||
var region: Config.LoRaConfig.RegionCode = .unset
|
||||
public var region: Config.LoRaConfig.RegionCode = .unset
|
||||
|
||||
///
|
||||
/// Modem preset used by the radio (LongFast, MediumSlow, etc...)
|
||||
var modemPreset: Config.LoRaConfig.ModemPreset = .longFast
|
||||
public var modemPreset: Config.LoRaConfig.ModemPreset = .longFast
|
||||
|
||||
///
|
||||
/// Whether the node has a channel with default PSK and name (LongFast, MediumSlow, etc...)
|
||||
/// and it uses the default frequency slot given the region and modem preset.
|
||||
var hasDefaultChannel_p: Bool = false
|
||||
public var hasDefaultChannel_p: Bool = false
|
||||
|
||||
///
|
||||
/// Latitude: multiply by 1e-7 to get degrees in floating point
|
||||
var latitudeI: Int32 = 0
|
||||
public var latitudeI: Int32 = 0
|
||||
|
||||
///
|
||||
/// Longitude: multiply by 1e-7 to get degrees in floating point
|
||||
var longitudeI: Int32 = 0
|
||||
public var longitudeI: Int32 = 0
|
||||
|
||||
///
|
||||
/// Altitude in meters above MSL
|
||||
var altitude: Int32 = 0
|
||||
public var altitude: Int32 = 0
|
||||
|
||||
///
|
||||
/// Indicates the bits of precision for latitude and longitude set by the sending node
|
||||
var positionPrecision: UInt32 = 0
|
||||
public var positionPrecision: UInt32 = 0
|
||||
|
||||
///
|
||||
/// Number of online nodes (heard in the last 2 hours) this node has in its list that were received locally (not via MQTT)
|
||||
var numOnlineLocalNodes: UInt32 = 0
|
||||
public var numOnlineLocalNodes: UInt32 = 0
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
public init() {}
|
||||
}
|
||||
|
||||
#if swift(>=5.5) && canImport(_Concurrency)
|
||||
|
|
@ -131,14 +131,14 @@ extension MapReport: @unchecked Sendable {}
|
|||
fileprivate let _protobuf_package = "meshtastic"
|
||||
|
||||
extension ServiceEnvelope: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".ServiceEnvelope"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -152,7 +152,7 @@ extension ServiceEnvelope: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
|
|
@ -169,7 +169,7 @@ extension ServiceEnvelope: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: ServiceEnvelope, rhs: ServiceEnvelope) -> Bool {
|
||||
public static func ==(lhs: ServiceEnvelope, rhs: ServiceEnvelope) -> Bool {
|
||||
if lhs._packet != rhs._packet {return false}
|
||||
if lhs.channelID != rhs.channelID {return false}
|
||||
if lhs.gatewayID != rhs.gatewayID {return false}
|
||||
|
|
@ -179,8 +179,8 @@ extension ServiceEnvelope: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen
|
|||
}
|
||||
|
||||
extension MapReport: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".MapReport"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
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"),
|
||||
|
|
@ -196,7 +196,7 @@ extension MapReport: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
|
|||
13: .standard(proto: "num_online_local_nodes"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
|
|
@ -220,7 +220,7 @@ extension MapReport: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
|
|||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
if !self.longName.isEmpty {
|
||||
try visitor.visitSingularStringField(value: self.longName, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -263,7 +263,7 @@ extension MapReport: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
|
|||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: MapReport, rhs: MapReport) -> Bool {
|
||||
public static func ==(lhs: MapReport, rhs: MapReport) -> Bool {
|
||||
if lhs.longName != rhs.longName {return false}
|
||||
if lhs.shortName != rhs.shortName {return false}
|
||||
if lhs.role != rhs.role {return false}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue