diff --git a/Localizable.xcstrings b/Localizable.xcstrings
index 2881b290..ad45481e 100644
--- a/Localizable.xcstrings
+++ b/Localizable.xcstrings
@@ -9017,7 +9017,7 @@
}
},
"incomplete" : {
- "extractionState" : "migrated",
+ "extractionState" : "manual",
"localizations" : {
"de" : {
"stringUnit" : {
@@ -15216,6 +15216,9 @@
}
}
}
+ },
+ "Model" : {
+
},
"module.configuration" : {
"localizations" : {
@@ -23713,18 +23716,15 @@
}
}
},
- "Version %@ includes breaking changes to devices and the client apps. Only nodes version %@ and above are supported." : {
+ "Version %@ includes substantial network optimizations and extensive changes to devices and client apps. Only nodes version %@ and above are supported." : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
- "value" : "Version %1$@ includes breaking changes to devices and the client apps. Only nodes version %2$@ and above are supported."
+ "value" : "Version %1$@ includes substantial network optimizations and extensive changes to devices and client apps. Only nodes version %2$@ and above are supported."
}
}
}
- },
- "Version 1.2 End of life (EOL) Info" : {
-
},
"Version: %@ (%@) " : {
"localizations" : {
@@ -24065,4 +24065,4 @@
}
},
"version" : "1.0"
-}
+}
\ No newline at end of file
diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj
index 6ea81c15..35592c2d 100644
--- a/Meshtastic.xcodeproj/project.pbxproj
+++ b/Meshtastic.xcodeproj/project.pbxproj
@@ -1704,7 +1704,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 2.5.10;
+ MARKETING_VERSION = 2.5.11;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
@@ -1738,7 +1738,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 2.5.10;
+ MARKETING_VERSION = 2.5.11;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
@@ -1770,7 +1770,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 2.5.10;
+ MARKETING_VERSION = 2.5.11;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1803,7 +1803,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 2.5.10;
+ MARKETING_VERSION = 2.5.11;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
diff --git a/Meshtastic/Assets.xcassets/TLORABOARD.imageset/Contents.json b/Meshtastic/Assets.xcassets/HELTECHT62.imageset/Contents.json
similarity index 51%
rename from Meshtastic/Assets.xcassets/TLORABOARD.imageset/Contents.json
rename to Meshtastic/Assets.xcassets/HELTECHT62.imageset/Contents.json
index f8356864..418dd7fe 100644
--- a/Meshtastic/Assets.xcassets/TLORABOARD.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/HELTECHT62.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "LILYGO-TTGO-LoRa32-V2-1-1-6-Version-433-868-915Mhz-ESP32-LoRa-OLED-0-96.jpg_Q90.jpg_.webp.png",
+ "filename" : "heltec-ht62-esp32c3-sx1262.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/HELTECHT62.imageset/heltec-ht62-esp32c3-sx1262.svg b/Meshtastic/Assets.xcassets/HELTECHT62.imageset/heltec-ht62-esp32c3-sx1262.svg
new file mode 100644
index 00000000..c52534ef
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/HELTECHT62.imageset/heltec-ht62-esp32c3-sx1262.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/HELTECMESHNODET114.imageset/Contents.json b/Meshtastic/Assets.xcassets/HELTECMESHNODET114.imageset/Contents.json
new file mode 100644
index 00000000..a4f550b7
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/HELTECMESHNODET114.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "heltec-mesh-node-t114-case.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/HELTECMESHNODET114.imageset/heltec-mesh-node-t114-case.svg b/Meshtastic/Assets.xcassets/HELTECMESHNODET114.imageset/heltec-mesh-node-t114-case.svg
new file mode 100644
index 00000000..b2abe639
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/HELTECMESHNODET114.imageset/heltec-mesh-node-t114-case.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/HELTECV3.imageset/Contents.json b/Meshtastic/Assets.xcassets/HELTECV3.imageset/Contents.json
index 98595042..42c0472b 100644
--- a/Meshtastic/Assets.xcassets/HELTECV3.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/HELTECV3.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "Heltec_turq.png",
+ "filename" : "heltec-v3-case.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/HELTECV3.imageset/Heltec_turq.png b/Meshtastic/Assets.xcassets/HELTECV3.imageset/Heltec_turq.png
deleted file mode 100644
index c4454bcc..00000000
Binary files a/Meshtastic/Assets.xcassets/HELTECV3.imageset/Heltec_turq.png and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/HELTECV3.imageset/heltec-v3-case.svg b/Meshtastic/Assets.xcassets/HELTECV3.imageset/heltec-v3-case.svg
new file mode 100644
index 00000000..1b1d3c55
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/HELTECV3.imageset/heltec-v3-case.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE213.imageset/Contents.json b/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE213.imageset/Contents.json
new file mode 100644
index 00000000..687a7da9
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE213.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "heltec-vision-master-e213.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE213.imageset/heltec-vision-master-e213.svg b/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE213.imageset/heltec-vision-master-e213.svg
new file mode 100644
index 00000000..2c1cca09
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE213.imageset/heltec-vision-master-e213.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE290.imageset/Contents.json b/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE290.imageset/Contents.json
new file mode 100644
index 00000000..13ddda16
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE290.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "heltec-vision-master-e290.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE290.imageset/heltec-vision-master-e290.svg b/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE290.imageset/heltec-vision-master-e290.svg
new file mode 100644
index 00000000..ca7d296a
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/HELTECVISIONMASTERE290.imageset/heltec-vision-master-e290.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/HELTECWIRELESSPAPER.imageset/Contents.json b/Meshtastic/Assets.xcassets/HELTECWIRELESSPAPER.imageset/Contents.json
index 1a8d07dc..a1a7444e 100644
--- a/Meshtastic/Assets.xcassets/HELTECWIRELESSPAPER.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/HELTECWIRELESSPAPER.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "Paper-Meshtastic-2 copy.jpg",
+ "filename" : "heltec-wireless-paper.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/HELTECWIRELESSPAPER.imageset/Paper-Meshtastic-2 copy.jpg b/Meshtastic/Assets.xcassets/HELTECWIRELESSPAPER.imageset/Paper-Meshtastic-2 copy.jpg
deleted file mode 100644
index 36692599..00000000
Binary files a/Meshtastic/Assets.xcassets/HELTECWIRELESSPAPER.imageset/Paper-Meshtastic-2 copy.jpg and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/HELTECWIRELESSPAPER.imageset/heltec-wireless-paper.svg b/Meshtastic/Assets.xcassets/HELTECWIRELESSPAPER.imageset/heltec-wireless-paper.svg
new file mode 100644
index 00000000..cb3f188d
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/HELTECWIRELESSPAPER.imageset/heltec-wireless-paper.svg
@@ -0,0 +1 @@
+
diff --git a/Meshtastic/Assets.xcassets/HELTECWIRELESSTRACKER.imageset/Contents.json b/Meshtastic/Assets.xcassets/HELTECWIRELESSTRACKER.imageset/Contents.json
index 3b6b227c..d13152fe 100644
--- a/Meshtastic/Assets.xcassets/HELTECWIRELESSTRACKER.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/HELTECWIRELESSTRACKER.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "images.png",
+ "filename" : "heltec-wireless-tracker.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/HELTECWIRELESSTRACKER.imageset/heltec-wireless-tracker.svg b/Meshtastic/Assets.xcassets/HELTECWIRELESSTRACKER.imageset/heltec-wireless-tracker.svg
new file mode 100644
index 00000000..a5392595
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/HELTECWIRELESSTRACKER.imageset/heltec-wireless-tracker.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/HELTECWIRELESSTRACKER.imageset/images.png b/Meshtastic/Assets.xcassets/HELTECWIRELESSTRACKER.imageset/images.png
deleted file mode 100644
index 4e9336c5..00000000
Binary files a/Meshtastic/Assets.xcassets/HELTECWIRELESSTRACKER.imageset/images.png and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/HELTECWSLV3.imageset/Contents.json b/Meshtastic/Assets.xcassets/HELTECWSLV3.imageset/Contents.json
index aed717e4..dea94fc1 100644
--- a/Meshtastic/Assets.xcassets/HELTECWSLV3.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/HELTECWSLV3.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "heltecwsl.png",
+ "filename" : "heltec-wsl-v3.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/HELTECWSLV3.imageset/heltec-wsl-v3.svg b/Meshtastic/Assets.xcassets/HELTECWSLV3.imageset/heltec-wsl-v3.svg
new file mode 100644
index 00000000..1741223e
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/HELTECWSLV3.imageset/heltec-wsl-v3.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/HELTECWSLV3.imageset/heltecwsl.png b/Meshtastic/Assets.xcassets/HELTECWSLV3.imageset/heltecwsl.png
deleted file mode 100644
index 8881d0e1..00000000
Binary files a/Meshtastic/Assets.xcassets/HELTECWSLV3.imageset/heltecwsl.png and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/LILYGOTBEAMS3CORE.imageset/Contents.json b/Meshtastic/Assets.xcassets/LILYGOTBEAMS3CORE.imageset/Contents.json
index 892d20eb..1febc627 100644
--- a/Meshtastic/Assets.xcassets/LILYGOTBEAMS3CORE.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/LILYGOTBEAMS3CORE.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "tbeam_supreme.png",
+ "filename" : "tbeam-s3-core.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/LILYGOTBEAMS3CORE.imageset/tbeam-s3-core.svg b/Meshtastic/Assets.xcassets/LILYGOTBEAMS3CORE.imageset/tbeam-s3-core.svg
new file mode 100644
index 00000000..f42e6d2c
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/LILYGOTBEAMS3CORE.imageset/tbeam-s3-core.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/LILYGOTBEAMS3CORE.imageset/tbeam_supreme.png b/Meshtastic/Assets.xcassets/LILYGOTBEAMS3CORE.imageset/tbeam_supreme.png
deleted file mode 100644
index 6a618653..00000000
Binary files a/Meshtastic/Assets.xcassets/LILYGOTBEAMS3CORE.imageset/tbeam_supreme.png and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/NANOG2ULTRA.imageset/Contents.json b/Meshtastic/Assets.xcassets/NANOG2ULTRA.imageset/Contents.json
index 2f074381..fe8b1d15 100644
--- a/Meshtastic/Assets.xcassets/NANOG2ULTRA.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/NANOG2ULTRA.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "nano_g2_ultra_product_image.jpg",
+ "filename" : "nano-g2-ultra.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/NANOG2ULTRA.imageset/nano-g2-ultra.svg b/Meshtastic/Assets.xcassets/NANOG2ULTRA.imageset/nano-g2-ultra.svg
new file mode 100644
index 00000000..6dbe47af
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/NANOG2ULTRA.imageset/nano-g2-ultra.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/NANOG2ULTRA.imageset/nano_g2_ultra_product_image.jpg b/Meshtastic/Assets.xcassets/NANOG2ULTRA.imageset/nano_g2_ultra_product_image.jpg
deleted file mode 100644
index 18f2b472..00000000
Binary files a/Meshtastic/Assets.xcassets/NANOG2ULTRA.imageset/nano_g2_ultra_product_image.jpg and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/RAK11200.imageset/Contents.json b/Meshtastic/Assets.xcassets/PROMICRO.imageset/Contents.json
similarity index 75%
rename from Meshtastic/Assets.xcassets/RAK11200.imageset/Contents.json
rename to Meshtastic/Assets.xcassets/PROMICRO.imageset/Contents.json
index ed6c2585..0fbd5109 100644
--- a/Meshtastic/Assets.xcassets/RAK11200.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/PROMICRO.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "RAK_DEV_KIT-2.jpg",
+ "filename" : "promicro.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/PROMICRO.imageset/promicro.svg b/Meshtastic/Assets.xcassets/PROMICRO.imageset/promicro.svg
new file mode 100644
index 00000000..3dc26021
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/PROMICRO.imageset/promicro.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/RAK11200.imageset/RAK_DEV_KIT-2.jpg b/Meshtastic/Assets.xcassets/RAK11200.imageset/RAK_DEV_KIT-2.jpg
deleted file mode 100644
index 9300bed0..00000000
Binary files a/Meshtastic/Assets.xcassets/RAK11200.imageset/RAK_DEV_KIT-2.jpg and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/TLORAV1.imageset/Contents.json b/Meshtastic/Assets.xcassets/RAK11310.imageset/Contents.json
similarity index 75%
rename from Meshtastic/Assets.xcassets/TLORAV1.imageset/Contents.json
rename to Meshtastic/Assets.xcassets/RAK11310.imageset/Contents.json
index 093c722d..3046b536 100644
--- a/Meshtastic/Assets.xcassets/TLORAV1.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/RAK11310.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "TLORA_olive 1.png",
+ "filename" : "rak11310.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/RAK11310.imageset/rak11310.svg b/Meshtastic/Assets.xcassets/RAK11310.imageset/rak11310.svg
new file mode 100644
index 00000000..8c5ce28e
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/RAK11310.imageset/rak11310.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/RAK4631.imageset/Contents.json b/Meshtastic/Assets.xcassets/RAK4631.imageset/Contents.json
index feb2e6c0..60b17db3 100644
--- a/Meshtastic/Assets.xcassets/RAK4631.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/RAK4631.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "RAK 4.png",
+ "filename" : "rak4631_case.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/RAK4631.imageset/RAK 4.png b/Meshtastic/Assets.xcassets/RAK4631.imageset/RAK 4.png
deleted file mode 100644
index e34322b8..00000000
Binary files a/Meshtastic/Assets.xcassets/RAK4631.imageset/RAK 4.png and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/RAK4631.imageset/rak4631_case.svg b/Meshtastic/Assets.xcassets/RAK4631.imageset/rak4631_case.svg
new file mode 100644
index 00000000..a0b2bbb8
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/RAK4631.imageset/rak4631_case.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/RPIPICO.imageset/Contents.json b/Meshtastic/Assets.xcassets/RPIPICO.imageset/Contents.json
new file mode 100644
index 00000000..87088506
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/RPIPICO.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "pico.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/RPIPICO.imageset/pico.svg b/Meshtastic/Assets.xcassets/RPIPICO.imageset/pico.svg
new file mode 100644
index 00000000..82ce6526
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/RPIPICO.imageset/pico.svg
@@ -0,0 +1,2956 @@
+
+
diff --git a/Meshtastic/Assets.xcassets/SEEEDXIAOS3.imageset/Contents.json b/Meshtastic/Assets.xcassets/SEEEDXIAOS3.imageset/Contents.json
new file mode 100644
index 00000000..fdd4019e
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/SEEEDXIAOS3.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "seeed-xiao-s3.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/SEEEDXIAOS3.imageset/seeed-xiao-s3.svg b/Meshtastic/Assets.xcassets/SEEEDXIAOS3.imageset/seeed-xiao-s3.svg
new file mode 100644
index 00000000..04e97fe0
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/SEEEDXIAOS3.imageset/seeed-xiao-s3.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/SENSECAPINDICATOR.imageset/Contents.json b/Meshtastic/Assets.xcassets/SENSECAPINDICATOR.imageset/Contents.json
new file mode 100644
index 00000000..3870939e
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/SENSECAPINDICATOR.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "seeed-sensecap-indicator.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/SENSECAPINDICATOR.imageset/seeed-sensecap-indicator.svg b/Meshtastic/Assets.xcassets/SENSECAPINDICATOR.imageset/seeed-sensecap-indicator.svg
new file mode 100644
index 00000000..f7bf9db0
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/SENSECAPINDICATOR.imageset/seeed-sensecap-indicator.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/STATIONG2.imageset/Contents.json b/Meshtastic/Assets.xcassets/STATIONG2.imageset/Contents.json
new file mode 100644
index 00000000..dc823045
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/STATIONG2.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "station-g2.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/STATIONG2.imageset/station-g2.svg b/Meshtastic/Assets.xcassets/STATIONG2.imageset/station-g2.svg
new file mode 100644
index 00000000..8d2e0aed
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/STATIONG2.imageset/station-g2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/TBEAM.imageset/Contents.json b/Meshtastic/Assets.xcassets/TBEAM.imageset/Contents.json
index 64a09f22..0ecd041c 100644
--- a/Meshtastic/Assets.xcassets/TBEAM.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/TBEAM.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "tbeam.png",
+ "filename" : "tbeam.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/TBEAM.imageset/tbeam.png b/Meshtastic/Assets.xcassets/TBEAM.imageset/tbeam.png
deleted file mode 100644
index 75fec7be..00000000
Binary files a/Meshtastic/Assets.xcassets/TBEAM.imageset/tbeam.png and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/TBEAM.imageset/tbeam.svg b/Meshtastic/Assets.xcassets/TBEAM.imageset/tbeam.svg
new file mode 100644
index 00000000..cd0475c6
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TBEAM.imageset/tbeam.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/TDECK.imageset/Contents.json b/Meshtastic/Assets.xcassets/TDECK.imageset/Contents.json
new file mode 100644
index 00000000..b8451344
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TDECK.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "t-deck.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/TDECK.imageset/t-deck.svg b/Meshtastic/Assets.xcassets/TDECK.imageset/t-deck.svg
new file mode 100644
index 00000000..cdc53c5d
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TDECK.imageset/t-deck.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/TECHO.imageset/Contents.json b/Meshtastic/Assets.xcassets/TECHO.imageset/Contents.json
index f380b7af..e1adcf61 100644
--- a/Meshtastic/Assets.xcassets/TECHO.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/TECHO.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "LILYGO-TTGO-SoftRF-T-Echo-NRF52840-LoRa-SX1262-433-868-915MHz-Wireless-Module-L76K-GPS-1.png",
+ "filename" : "t-echo.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/TECHO.imageset/LILYGO-TTGO-SoftRF-T-Echo-NRF52840-LoRa-SX1262-433-868-915MHz-Wireless-Module-L76K-GPS-1.png b/Meshtastic/Assets.xcassets/TECHO.imageset/LILYGO-TTGO-SoftRF-T-Echo-NRF52840-LoRa-SX1262-433-868-915MHz-Wireless-Module-L76K-GPS-1.png
deleted file mode 100644
index 7b2f9f96..00000000
Binary files a/Meshtastic/Assets.xcassets/TECHO.imageset/LILYGO-TTGO-SoftRF-T-Echo-NRF52840-LoRa-SX1262-433-868-915MHz-Wireless-Module-L76K-GPS-1.png and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/TECHO.imageset/t-echo.svg b/Meshtastic/Assets.xcassets/TECHO.imageset/t-echo.svg
new file mode 100644
index 00000000..e178a50f
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TECHO.imageset/t-echo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/TLORABOARD.imageset/LILYGO-TTGO-LoRa32-V2-1-1-6-Version-433-868-915Mhz-ESP32-LoRa-OLED-0-96.jpg_Q90.jpg_.webp.png b/Meshtastic/Assets.xcassets/TLORABOARD.imageset/LILYGO-TTGO-LoRa32-V2-1-1-6-Version-433-868-915Mhz-ESP32-LoRa-OLED-0-96.jpg_Q90.jpg_.webp.png
deleted file mode 100644
index ff3da639..00000000
Binary files a/Meshtastic/Assets.xcassets/TLORABOARD.imageset/LILYGO-TTGO-LoRa32-V2-1-1-6-Version-433-868-915Mhz-ESP32-LoRa-OLED-0-96.jpg_Q90.jpg_.webp.png and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/TLORAC6.imageset/Contents.json b/Meshtastic/Assets.xcassets/TLORAC6.imageset/Contents.json
new file mode 100644
index 00000000..593dc16e
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TLORAC6.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "tlora-c6.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/TLORAC6.imageset/tlora-c6.svg b/Meshtastic/Assets.xcassets/TLORAC6.imageset/tlora-c6.svg
new file mode 100644
index 00000000..8b626638
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TLORAC6.imageset/tlora-c6.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/TLORAT3S3EPAPER.imageset/Contents.json b/Meshtastic/Assets.xcassets/TLORAT3S3EPAPER.imageset/Contents.json
new file mode 100644
index 00000000..33fb9c78
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TLORAT3S3EPAPER.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "tlora-t3s3-epaper.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/TLORAT3S3EPAPER.imageset/tlora-t3s3-epaper.svg b/Meshtastic/Assets.xcassets/TLORAT3S3EPAPER.imageset/tlora-t3s3-epaper.svg
new file mode 100644
index 00000000..6f2e8452
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TLORAT3S3EPAPER.imageset/tlora-t3s3-epaper.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/TLORAT3S3V1.imageset/Contents.json b/Meshtastic/Assets.xcassets/TLORAT3S3V1.imageset/Contents.json
new file mode 100644
index 00000000..a5716fc8
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TLORAT3S3V1.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "tlora-t3s3-v1.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/TLORAT3S3V1.imageset/tlora-t3s3-v1.svg b/Meshtastic/Assets.xcassets/TLORAT3S3V1.imageset/tlora-t3s3-v1.svg
new file mode 100644
index 00000000..1f8847d4
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TLORAT3S3V1.imageset/tlora-t3s3-v1.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/TLORAV1.imageset/TLORA_olive 1.png b/Meshtastic/Assets.xcassets/TLORAV1.imageset/TLORA_olive 1.png
deleted file mode 100644
index e8980a2c..00000000
Binary files a/Meshtastic/Assets.xcassets/TLORAV1.imageset/TLORA_olive 1.png and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/TLORAV2116.imageset/Contents.json b/Meshtastic/Assets.xcassets/TLORAV2116.imageset/Contents.json
new file mode 100644
index 00000000..eb286609
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TLORAV2116.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "tlora-v2-1-1_6.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/TLORAV2116.imageset/tlora-v2-1-1_6.svg b/Meshtastic/Assets.xcassets/TLORAV2116.imageset/tlora-v2-1-1_6.svg
new file mode 100644
index 00000000..dbe36ef5
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TLORAV2116.imageset/tlora-v2-1-1_6.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/TLORAV2118.imageset/Contents.json b/Meshtastic/Assets.xcassets/TLORAV2118.imageset/Contents.json
new file mode 100644
index 00000000..c7aff831
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TLORAV2118.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "tlora-v2-1-1_8.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/TLORAV2118.imageset/tlora-v2-1-1_8.svg b/Meshtastic/Assets.xcassets/TLORAV2118.imageset/tlora-v2-1-1_8.svg
new file mode 100644
index 00000000..dbe36ef5
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TLORAV2118.imageset/tlora-v2-1-1_8.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/TRACKERT1000E.imageset/Contents.json b/Meshtastic/Assets.xcassets/TRACKERT1000E.imageset/Contents.json
new file mode 100644
index 00000000..e966c95f
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TRACKERT1000E.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "tracker-t1000-e.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/TRACKERT1000E.imageset/tracker-t1000-e.svg b/Meshtastic/Assets.xcassets/TRACKERT1000E.imageset/tracker-t1000-e.svg
new file mode 100644
index 00000000..6f7a06c9
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TRACKERT1000E.imageset/tracker-t1000-e.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/TWATCHS3.imageset/Contents.json b/Meshtastic/Assets.xcassets/TWATCHS3.imageset/Contents.json
new file mode 100644
index 00000000..baffc648
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TWATCHS3.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "t-watch-s3.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/TWATCHS3.imageset/t-watch-s3.svg b/Meshtastic/Assets.xcassets/TWATCHS3.imageset/t-watch-s3.svg
new file mode 100644
index 00000000..19084c19
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/TWATCHS3.imageset/t-watch-s3.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/UNSET.imageset/Contents.json b/Meshtastic/Assets.xcassets/UNSET.imageset/Contents.json
index 04be44d5..4508d9cd 100644
--- a/Meshtastic/Assets.xcassets/UNSET.imageset/Contents.json
+++ b/Meshtastic/Assets.xcassets/UNSET.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "play_store_icon_114px-2.png",
+ "filename" : "unknown.svg",
"idiom" : "universal"
}
],
diff --git a/Meshtastic/Assets.xcassets/UNSET.imageset/play_store_icon_114px-2.png b/Meshtastic/Assets.xcassets/UNSET.imageset/play_store_icon_114px-2.png
deleted file mode 100644
index 79cf0e00..00000000
Binary files a/Meshtastic/Assets.xcassets/UNSET.imageset/play_store_icon_114px-2.png and /dev/null differ
diff --git a/Meshtastic/Assets.xcassets/UNSET.imageset/unknown.svg b/Meshtastic/Assets.xcassets/UNSET.imageset/unknown.svg
new file mode 100644
index 00000000..3b0a0744
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/UNSET.imageset/unknown.svg
@@ -0,0 +1,129 @@
+
+
diff --git a/Meshtastic/Assets.xcassets/WIOWM1110.imageset/Contents.json b/Meshtastic/Assets.xcassets/WIOWM1110.imageset/Contents.json
new file mode 100644
index 00000000..706f7fc3
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/WIOWM1110.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "wio-tracker-wm1110.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/WIOWM1110.imageset/wio-tracker-wm1110.svg b/Meshtastic/Assets.xcassets/WIOWM1110.imageset/wio-tracker-wm1110.svg
new file mode 100644
index 00000000..15ace5c5
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/WIOWM1110.imageset/wio-tracker-wm1110.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Assets.xcassets/WISMESHTAP.imageset/Contents.json b/Meshtastic/Assets.xcassets/WISMESHTAP.imageset/Contents.json
new file mode 100644
index 00000000..85d43a9b
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/WISMESHTAP.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "rak-wismeshtap.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Meshtastic/Assets.xcassets/WISMESHTAP.imageset/rak-wismeshtap.svg b/Meshtastic/Assets.xcassets/WISMESHTAP.imageset/rak-wismeshtap.svg
new file mode 100644
index 00000000..34e77876
--- /dev/null
+++ b/Meshtastic/Assets.xcassets/WISMESHTAP.imageset/rak-wismeshtap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Meshtastic/Enums/LoraConfigEnums.swift b/Meshtastic/Enums/LoraConfigEnums.swift
index 2a2d7090..deccde0f 100644
--- a/Meshtastic/Enums/LoraConfigEnums.swift
+++ b/Meshtastic/Enums/LoraConfigEnums.swift
@@ -176,6 +176,54 @@ enum RegionCodes: Int, CaseIterable, Identifiable {
return 100
}
}
+ var isCountry: Bool {
+ switch self {
+ case .unset:
+ return false
+ case .us:
+ return true
+ case .eu433:
+ return false
+ case .eu868:
+ return false
+ case .cn:
+ return true
+ case .jp:
+ return true
+ case .anz:
+ return false
+ case .kr:
+ return true
+ case .tw:
+ return true
+ case .ru:
+ return true
+ case .in:
+ return true
+ case .nz865:
+ return true
+ case .th:
+ return true
+ case .ua433:
+ return true
+ case .ua868:
+ return true
+ case .lora24:
+ return false
+ case .my433:
+ return true
+ case .my919:
+ return true
+ case .sg923:
+ return true
+ case .ph433:
+ return true
+ case .ph868:
+ return true
+ case .ph915:
+ return true
+ }
+ }
func protoEnumValue() -> Config.LoRaConfig.RegionCode {
switch self {
diff --git a/Meshtastic/Extensions/CoreData/UserEntityExtension.swift b/Meshtastic/Extensions/CoreData/UserEntityExtension.swift
index 8c49b322..b0700423 100644
--- a/Meshtastic/Extensions/CoreData/UserEntityExtension.swift
+++ b/Meshtastic/Extensions/CoreData/UserEntityExtension.swift
@@ -33,48 +33,79 @@ extension UserEntity {
let unreadMessages = messageList.filter { ($0 as AnyObject).read == false }
return unreadMessages.count
}
-
+ /// SVG Images for Vendors who are signed project backers
var hardwareImage: String? {
guard let hwModel else { return nil }
switch hwModel {
- case "HELTECV1", "HELTECV3", "HELTECV20", "HELTECV21":
+ /// Heltec
+ case "HELTECHT62":
+ return "HELTECHT62"
+ case "HELTECMESHNODET114":
+ return "HELTECMESHNODET114"
+ case "HELTECV3":
return "HELTECV3"
+ case "HELTECVISIONMASTERE213":
+ return "HELTECVISIONMASTERE213"
+ case "HELTECVISIONMASTERE290":
+ return "HELTECVISIONMASTERE290"
case "HELTECWIRELESSPAPER", "HELTECWIRELESSPAPERV10":
return "HELTECWIRELESSPAPER"
case "HELTECWIRELESSTRACKER", "HELTECWIRELESSTRACKERV10":
return "HELTECWIRELESSTRACKER"
case "HELTECWSLV3":
return "HELTECWSLV3"
- case "LILYGOTBEAMSCORE":
+ /// LilyGO
+ case "TDECK":
+ return "TDECK"
+ case "TECHO":
+ return "TECHO"
+ case "TWATCHS3":
+ return "TWATCHS3"
+ case "LILYGOTBEAMS3CORE":
return "LILYGOTBEAMS3CORE"
+ case "TBEAM", "TBEAM_V0P7":
+ return "TBEAM"
+ case "TLORAC6":
+ return "TLORAC6"
+ case "TLORAT3S3EPAPER":
+ return "TLORAT3S3EPAPER"
+ case "TLORAT3S3V1":
+ return "TLORAT3S3V1"
+ case "TLORAV2116":
+ return "TLORAV2116"
+ case "TLORAV2118":
+ return "TLORAV2118"
+ /// Seeed Studio
+ case "SENSECAPINDICATOR":
+ return "SENSECAPINDICATOR"
+ case "TRACKERT1000E":
+ return "TRACKERT1000E"
+ case "SEEEDXIAOS3":
+ return "SEEEDXIAOS3"
+ case "WIOWM1110":
+ return "WIOWM1110"
+ /// RAK Wireless
+ case "RAK4631":
+ return "UNSET"
+ case "RAK11310":
+ return "UNSET"
+ case "WISMESHTAP":
+ return "UNSET"
+ /// B&Q Consulting
case "NANOG1", "NANOG1EXPLORER":
return "NANOG1"
case "NANOG2ULTRA":
return "NANOG2ULTRA"
- case "RAK4631":
- return "RAK4631"
- case "RAK11200":
- return "RAK11200"
- case "SOLAR_NODE":
- return "SOLAR_NODE"
- case "STATIONG1":
- return "STATIONG1"
- case "ТВЕАМ", "TBEAMVOP7":
- return "ТВЕАМ"
- case "TECHO":
- return "TECHO"
- case "TLORAV1", "TLORAV11P3":
- return "TLORAV1"
- case "TLORAV2", "TLORAT3S3", "TLORAV211P6", "TLORAV211P8":
- return "TLORABOARD"
- case "UNPHONE":
- return "UNPHONE"
+ case "STATIONG2":
+ return "STATIONG2"
+ /// DIY Devices
+ case "RPIPICO":
+ return "RPIPICO"
default:
return "UNSET"
}
}
}
-
public func createUser(num: Int64, context: NSManagedObjectContext) -> UserEntity {
let newUser = UserEntity(context: context)
newUser.num = Int64(num)
diff --git a/Meshtastic/Extensions/String.swift b/Meshtastic/Extensions/String.swift
index 4e840a98..b97ad1c5 100644
--- a/Meshtastic/Extensions/String.swift
+++ b/Meshtastic/Extensions/String.swift
@@ -61,11 +61,10 @@ extension String {
}
func camelCaseToWords() -> String {
- return unicodeScalars.dropFirst().reduce(String(prefix(1))) {
- return CharacterSet.uppercaseLetters.contains($1)
- ? $0 + " " + String($1)
- : $0 + String($1)
- }
+ return self
+ .replacingOccurrences(of: "([a-z])([A-Z](?=[A-Z])[a-z]*)", with: "$1 $2", options: .regularExpression)
+ .replacingOccurrences(of: "([A-Z])([A-Z][a-z])", with: "$1 $2", options: .regularExpression)
+ .replacingOccurrences(of: "([a-z])([A-Z][a-z])", with: "$1 $2", options: .regularExpression)
}
var length: Int {
diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift
index bb707885..90d9f978 100644
--- a/Meshtastic/Helpers/BLEManager.swift
+++ b/Meshtastic/Helpers/BLEManager.swift
@@ -27,7 +27,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
@Published var automaticallyReconnect: Bool = true
@Published var mqttProxyConnected: Bool = false
@Published var mqttError: String = ""
- public var minimumVersion = "2.0.0"
+ public var minimumVersion = "2.3.2"
public var connectedVersion: String
public var isConnecting: Bool = false
public var isConnected: Bool = false
diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift
index a5cfa7ba..b2f59586 100644
--- a/Meshtastic/Helpers/MeshPackets.swift
+++ b/Meshtastic/Helpers/MeshPackets.swift
@@ -772,7 +772,8 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
}
}
} else if telemetry.metricsType == 4 {
- // Update our live activity if there is one running, not available on mac iOS >= 16.2
+ // Update our live activity if there is one running, not available on mac
+#if !targetEnvironment(macCatalyst)
#if canImport(ActivityKit)
let fifteenMinutesLater = Calendar.current.date(byAdding: .minute, value: (Int(15) ), to: Date())!
@@ -801,6 +802,7 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
Logger.services.debug("Updated live activity.")
}
}
+#endif
#endif
}
} catch {
@@ -876,6 +878,9 @@ func textMessageAppPacket(
if fetchedUsers.first(where: { $0.num == packet.to }) != nil && packet.to != Constants.maximumNodeNum {
if !storeForwardBroadcast {
newMessage.toUser = fetchedUsers.first(where: { $0.num == packet.to })
+ } else {
+ /// Make a new to user if they are unknown
+ newMessage.toUser = createUser(num: Int64(truncatingIfNeeded: packet.to), context: context)
}
}
if fetchedUsers.first(where: { $0.num == packet.from }) != nil {
@@ -903,11 +908,14 @@ func textMessageAppPacket(
newMessage.fromUser?.publicKey = packet.publicKey
}
}
- if packet.rxTime > 0 {
- newMessage.fromUser?.userNode?.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
- } else {
- newMessage.fromUser?.userNode?.lastHeard = Date()
- }
+ } else {
+ /// Make a new from user if they are unknown
+ newMessage.fromUser = createUser(num: Int64(truncatingIfNeeded: packet.to), context: context)
+ }
+ if packet.rxTime > 0 {
+ newMessage.fromUser?.userNode?.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
+ } else {
+ newMessage.fromUser?.userNode?.lastHeard = Date()
}
newMessage.messagePayload = messageText
newMessage.messagePayloadMarkdown = generateMessageMarkdown(message: messageText!)
diff --git a/Meshtastic/Persistence/UpdateCoreData.swift b/Meshtastic/Persistence/UpdateCoreData.swift
index 9feecf6d..b824f777 100644
--- a/Meshtastic/Persistence/UpdateCoreData.swift
+++ b/Meshtastic/Persistence/UpdateCoreData.swift
@@ -832,9 +832,9 @@ func upsertSecurityConfigPacket(config: Config.SecurityConfig, nodeNum: Int64, s
if config.adminKey.count > 0 {
fetchedNode[0].securityConfig?.adminKey = config.adminKey[0]
if config.adminKey.count > 1 {
- fetchedNode[0].securityConfig?.adminKey = config.adminKey[1]
+ fetchedNode[0].securityConfig?.adminKey2 = config.adminKey[1]
} else if config.adminKey.count > 2 {
- fetchedNode[0].securityConfig?.adminKey = config.adminKey[2]
+ fetchedNode[0].securityConfig?.adminKey3 = config.adminKey[2]
}
}
fetchedNode[0].securityConfig?.isManaged = config.isManaged
diff --git a/Meshtastic/Resources/DeviceHardware.json b/Meshtastic/Resources/DeviceHardware.json
index 5e0135b9..a4a6949c 100644
--- a/Meshtastic/Resources/DeviceHardware.json
+++ b/Meshtastic/Resources/DeviceHardware.json
@@ -86,7 +86,8 @@
],
"images": [
"t-echo.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 8,
@@ -113,7 +114,8 @@
"images": [
"rak4631.svg",
"rak4631_case.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 10,
@@ -139,7 +141,7 @@
},
{
"hwModel": 12,
- "hwModelSlug": "TBEAM_S3_CORE",
+ "hwModelSlug": "LILYGO_TBEAM_S3_CORE",
"platformioTarget": "tbeam-s3-core",
"architecture": "esp32-s3",
"activelySupported": true,
@@ -150,7 +152,8 @@
],
"images": [
"tbeam-s3-core.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 13,
@@ -204,7 +207,8 @@
],
"images": [
"tlora-t3s3-v1.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 16,
@@ -219,7 +223,8 @@
],
"images": [
"tlora-t3s3-epaper.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 17,
@@ -243,6 +248,10 @@
"displayName": "Nano G2 Ultra",
"tags": [
"B&Q"
+ ],
+ "requiresDfu": true,
+ "images": [
+ "nano-g2-ultra.svg"
]
},
{
@@ -258,7 +267,8 @@
],
"images": [
"wio-tracker-wm1110.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 25,
@@ -282,7 +292,11 @@
"displayName": "RAK WisBlock 11310",
"tags": [
"RAK"
- ]
+ ],
+ "images": [
+ "rak11310.svg"
+ ],
+ "requiresDfu": true
},
{
"hwModel": 29,
@@ -294,7 +308,8 @@
"displayName": "Canary One",
"tags": [
"Canary"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 30,
@@ -306,7 +321,8 @@
"displayName": "RP2040 LoRa",
"tags": [
"Waveshare"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 31,
@@ -318,6 +334,10 @@
"displayName": "Station G2",
"tags": [
"B&Q"
+ ],
+ "requiresDfu": true,
+ "images": [
+ "station-g2.svg"
]
},
{
@@ -330,6 +350,9 @@
"displayName": "DIY V1",
"tags": [
"DIY"
+ ],
+ "images": [
+ "diy.svg"
]
},
{
@@ -407,8 +430,12 @@
"supportLevel": 3,
"displayName": "Raspberry Pi Pico",
"tags": [
- "Raspberry Pi",
+ "RPi",
"DIY"
+ ],
+ "requiresDfu": true,
+ "images": [
+ "pico.svg"
]
},
{
@@ -420,8 +447,12 @@
"supportLevel": 3,
"displayName": "Raspberry Pi Pico W",
"tags": [
- "Raspberry Pi",
+ "RPi",
"DIY"
+ ],
+ "requiresDfu": true,
+ "images": [
+ "rpipicow.svg"
]
},
{
@@ -437,19 +468,21 @@
],
"images": [
"heltec-wireless-tracker.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 58,
"hwModelSlug": "HELTEC_WIRELESS_TRACKER_V1_0",
"platformioTarget": "heltec-wireless-tracker-V1-0",
"architecture": "esp32-s3",
- "activelySupported": true,
+ "activelySupported": false,
"supportLevel": 3,
"displayName": "Heltec Wireless Tracker V1.0",
"images": [
"heltec-wireless-tracker.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 49,
@@ -479,7 +512,8 @@
],
"images": [
"t-deck.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 51,
@@ -525,7 +559,7 @@
"hwModelSlug": "HELTEC_WIRELESS_PAPER_V1_0",
"platformioTarget": "heltec-wireless-paper-v1_0",
"architecture": "esp32-s3",
- "activelySupported": true,
+ "activelySupported": false,
"supportLevel": 3,
"tags": [
"Heltec"
@@ -542,7 +576,8 @@
"architecture": "esp32-s3",
"activelySupported": true,
"supportLevel": 3,
- "displayName": "unPhone"
+ "displayName": "unPhone",
+ "requiresDfu": true
},
{
"hwModel": 48,
@@ -551,7 +586,8 @@
"architecture": "esp32-s3",
"activelySupported": true,
"supportLevel": 3,
- "displayName": "TrackSenger (small TFT)"
+ "displayName": "TrackSenger (small TFT)",
+ "requiresDfu": true
},
{
"hwModel": 48,
@@ -560,7 +596,8 @@
"architecture": "esp32-s3",
"activelySupported": true,
"supportLevel": 3,
- "displayName": "TrackSenger (big TFT)"
+ "displayName": "TrackSenger (big TFT)",
+ "requiresDfu": true
},
{
"hwModel": 48,
@@ -581,7 +618,8 @@
"displayName": "EBYTE EoRa-S3",
"tags": [
"EByte"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 64,
@@ -608,7 +646,8 @@
],
"images": [
"heltec-vision-master-t190.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 67,
@@ -623,7 +662,8 @@
],
"images": [
"heltec-vision-master-e213.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 68,
@@ -638,7 +678,8 @@
],
"images": [
"heltec-vision-master-e290.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 69,
@@ -654,7 +695,8 @@
"images": [
"heltec-mesh-node-t114.svg",
"heltec-mesh-node-t114-case.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 70,
@@ -684,7 +726,8 @@
],
"images": [
"tracker-t1000-e.svg"
- ]
+ ],
+ "requiresDfu": true
},
{
"hwModel": 72,
@@ -699,6 +742,23 @@
],
"images": [
"seeed-xiao-s3.svg"
- ]
+ ],
+ "requiresDfu": true
+ },
+ {
+ "hwModel": 84,
+ "hwModelSlug": "WISMESH_TAP",
+ "platformioTarget": "rak_wismeshtap",
+ "architecture": "nrf52840",
+ "activelySupported": false,
+ "supportLevel": 1,
+ "displayName": "RAK WisMesh Tap",
+ "tags": [
+ "RAK"
+ ],
+ "images": [
+ "rak-wismeshtap.svg"
+ ],
+ "requiresDfu": true
}
]
diff --git a/Meshtastic/Views/Bluetooth/Connect.swift b/Meshtastic/Views/Bluetooth/Connect.swift
index be466530..a424cbf0 100644
--- a/Meshtastic/Views/Bluetooth/Connect.swift
+++ b/Meshtastic/Views/Bluetooth/Connect.swift
@@ -324,7 +324,8 @@ struct Connect: View {
}
}
}
- #if canImport(ActivityKit)
+#if !targetEnvironment(macCatalyst)
+#if canImport(ActivityKit)
func startNodeActivity() {
liveActivityStarted = true
// 15 Minutes Local Stats Interval
@@ -367,8 +368,8 @@ struct Connect: View {
}
}
}
- #endif
-
+#endif
+#endif
func didDismissSheet() {
bleManager.disconnectPeripheral(reconnect: false)
}
diff --git a/Meshtastic/Views/Bluetooth/InvalidVersion.swift b/Meshtastic/Views/Bluetooth/InvalidVersion.swift
index 9c0cca78..ba94e7c1 100644
--- a/Meshtastic/Views/Bluetooth/InvalidVersion.swift
+++ b/Meshtastic/Views/Bluetooth/InvalidVersion.swift
@@ -41,11 +41,9 @@ struct InvalidVersion: View {
.font(.title3)
.foregroundColor(.orange)
.padding(.bottom)
- Text("Version \(minimumVersion) includes breaking changes to devices and the client apps. Only nodes version \(minimumVersion) and above are supported.")
+ Text("Version \(minimumVersion) includes substantial network optimizations and extensive changes to devices and client apps. Only nodes version \(minimumVersion) and above are supported.")
.font(.callout)
.padding([.leading, .trailing, .bottom])
- Link("Version 1.2 End of life (EOL) Info", destination: URL(string: "https://meshtastic.org/docs/1.2-End-of-life/")!)
- .font(.callout)
#if targetEnvironment(macCatalyst)
Button {
diff --git a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift
index a9f7bcfe..d9fc50a4 100644
--- a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift
+++ b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift
@@ -16,6 +16,9 @@ struct NodeDetail: View {
formatter.unitsStyle = .full
return formatter
}()
+ var modemPreset: ModemPresets = ModemPresets(
+ rawValue: UserDefaults.modemPreset
+ ) ?? ModemPresets.longFast
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@@ -44,6 +47,34 @@ struct NodeDetail: View {
NodeInfoItem(node: node)
}
Section("Node") {
+ HStack(alignment: .center) {
+ Spacer()
+ CircleText(
+ text: node.user?.shortName ?? "?",
+ color: Color(UIColor(hex: UInt32(node.num))),
+ circleSize: 75
+ )
+ if node.snr != 0 && !node.viaMqtt && node.hopsAway == 0 {
+ Spacer()
+ VStack {
+ let signalStrength = getLoRaSignalStrength(snr: node.snr, rssi: node.rssi, preset: modemPreset)
+ LoRaSignalStrengthIndicator(signalStrength: signalStrength)
+ Text("Signal \(signalStrength.description)").font(.footnote)
+ Text("SNR \(String(format: "%.2f", node.snr))dB")
+ .foregroundColor(getSnrColor(snr: node.snr, preset: modemPreset))
+ .font(.caption)
+ Text("RSSI \(node.rssi)dB")
+ .foregroundColor(getRssiColor(rssi: node.rssi))
+ .font(.caption)
+ }
+ }
+ if node.telemetries?.count ?? 0 > 0 {
+ Spacer()
+ BatteryGauge(node: node)
+ }
+ Spacer()
+ }
+ .listRowSeparator(.hidden)
if let user = node.user {
if !user.keyMatch {
Label {
diff --git a/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift b/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift
index e0da484e..9f3b8105 100644
--- a/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift
+++ b/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift
@@ -12,61 +12,71 @@ import MapKit
struct NodeInfoItem: View {
@ObservedObject var node: NodeInfoEntity
-
- var modemPreset: ModemPresets = ModemPresets(
- rawValue: UserDefaults.modemPreset
- ) ?? ModemPresets.longFast
+ @State private var currentDevice: DeviceHardware?
var body: some View {
+ if let user = node.user {
ViewThatFits(in: .horizontal) {
- VStack {
- if let user = node.user {
- HStack(alignment: .center) {
- if user.hwModel != "UNSET" {
- Image(user.hardwareImage ?? "UNSET")
+ HStack {
+ Spacer()
+ if user.hwModel != "UNSET" {
+ VStack(alignment: .center) {
+ Spacer()
+ Image(systemName: currentDevice?.activelySupported ?? false ? "checkmark.seal.fill" : "x.circle")
.resizable()
- .aspectRatio(contentMode: .fit)
- .frame(width: 65, height: 65)
- .cornerRadius(5)
- Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "unset".localized)))
- .font(.callout)
- } else {
- Image(systemName: "person.crop.circle.badge.questionmark")
- .resizable()
- .aspectRatio(contentMode: .fit)
- .frame(width: 65, height: 65)
- .cornerRadius(5)
- Text(String("incomplete".localized))
+ .aspectRatio(contentMode: .fill)
+ .frame(width: 75, height: 75)
+ .foregroundStyle(currentDevice?.activelySupported ?? false ? .green : .red)
+ Text( currentDevice?.activelySupported ?? false ? "Supported" : "Unsupported")
+ .foregroundStyle(.gray)
.font(.callout)
}
+ Spacer()
+ }
+ VStack(alignment: .center) {
+ HStack {
+ if user.hardwareImage != "UNSET" {
+ Image(user.hardwareImage ?? "UNSET")
+ .resizable()
+ .aspectRatio(contentMode: .fit)
+ .frame(maxHeight: 150)
+ .cornerRadius(5)
+ } else {
+ Image(systemName: "person.crop.circle.badge.questionmark")
+ .resizable()
+ .aspectRatio(contentMode: .fit)
+ .frame(width: 75, height: 75)
+ .cornerRadius(5)
+ }
+ }
+ }
+ Spacer()
+ }
+ .onAppear {
+ Api().loadDeviceHardwareData { (hw) in
+ for device in hw {
+ let currentHardware = node.user?.hwModel ?? "UNSET"
+ let deviceString = device.hwModelSlug.replacingOccurrences(of: "_", with: "").uppercased()
+ if deviceString == currentHardware {
+ currentDevice = device
+ }
+ }
}
}
- HStack(alignment: .center) {
- Spacer()
- CircleText(
- text: node.user?.shortName ?? "?",
- color: Color(UIColor(hex: UInt32(node.num))),
- circleSize: 75
- )
- if node.snr != 0 && !node.viaMqtt && node.hopsAway == 0 {
- Spacer()
- VStack {
- let signalStrength = getLoRaSignalStrength(snr: node.snr, rssi: node.rssi, preset: modemPreset)
- LoRaSignalStrengthIndicator(signalStrength: signalStrength)
- Text("Signal \(signalStrength.description)").font(.footnote)
- Text("SNR \(String(format: "%.2f", node.snr))dB")
- .foregroundColor(getSnrColor(snr: node.snr, preset: modemPreset))
- .font(.caption)
- Text("RSSI \(node.rssi)dB")
- .foregroundColor(getRssiColor(rssi: node.rssi))
- .font(.caption)
- }
- }
- if node.telemetries?.count ?? 0 > 0 {
- Spacer()
- BatteryGauge(node: node)
- }
- Spacer()
+ }
+ .listRowSeparator(.hidden)
+ HStack {
+ Label {
+ Text("Model")
+ } icon: {
+ Image(systemName: "flipphone")
+ .symbolRenderingMode(.hierarchical)
+ }
+ Spacer()
+ if user.hwModel != "UNSET" {
+ Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "unset".localized)))
+ } else {
+ Text(String("incomplete".localized))
}
}
}
diff --git a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift
index 37f989a5..d57dacba 100644
--- a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift
+++ b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift
@@ -103,7 +103,7 @@ struct BluetoothConfig: View {
.onFirstAppear {
// Need to request a BluetoothConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty bluetooth config")
+
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -111,10 +111,12 @@ struct BluetoothConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.bluetoothConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired bluetooth config requesting via PKI admin")
_ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty bluetooth config")
_ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/DeviceConfig.swift b/Meshtastic/Views/Settings/Config/DeviceConfig.swift
index f5fca283..da2978cf 100644
--- a/Meshtastic/Views/Settings/Config/DeviceConfig.swift
+++ b/Meshtastic/Views/Settings/Config/DeviceConfig.swift
@@ -78,7 +78,7 @@ struct DeviceConfig: View {
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Toggle(isOn: $tripleClickAsAdHocPing) {
- Label("Triple Click Ad Hoc Ping", systemImage: "map.pin")
+ Label("Triple Click Ad Hoc Ping", systemImage: "mappin")
Text("Send a position on the primary channel when the user button is triple clicked.")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
@@ -229,7 +229,6 @@ struct DeviceConfig: View {
.onFirstAppear {
// Need to request a DeviceConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty device config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -237,11 +236,13 @@ struct DeviceConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.deviceConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired device config requesting via PKI admin")
_ = bleManager.requestDeviceConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
if node.deviceConfig == nil {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty device config")
_ = bleManager.requestDeviceConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/DisplayConfig.swift b/Meshtastic/Views/Settings/Config/DisplayConfig.swift
index 07975419..88839956 100644
--- a/Meshtastic/Views/Settings/Config/DisplayConfig.swift
+++ b/Meshtastic/Views/Settings/Config/DisplayConfig.swift
@@ -166,7 +166,6 @@ struct DisplayConfig: View {
.onFirstAppear {
// Need to request a DisplayConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty display config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -174,10 +173,12 @@ struct DisplayConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.displayConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired display config requesting via PKI admin")
_ = bleManager.requestDisplayConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty display config")
_ = bleManager.requestDisplayConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/LoRaConfig.swift b/Meshtastic/Views/Settings/Config/LoRaConfig.swift
index 4c12c598..51461cf0 100644
--- a/Meshtastic/Views/Settings/Config/LoRaConfig.swift
+++ b/Meshtastic/Views/Settings/Config/LoRaConfig.swift
@@ -241,7 +241,6 @@ struct LoRaConfig: View {
.onFirstAppear {
// Need to request a LoRaConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty lora config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -249,10 +248,13 @@ struct LoRaConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.loRaConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired lora config requesting via PKI admin")
+
_ = bleManager.requestLoRaConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty lora config")
_ = bleManager.requestLoRaConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift b/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift
index fc82a4ca..62340da8 100644
--- a/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift
+++ b/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift
@@ -88,7 +88,6 @@ struct AmbientLightingConfig: View {
.onFirstAppear {
// Need to request a Ambient Lighting Config from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty ambient lighting config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -96,10 +95,12 @@ struct AmbientLightingConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.ambientLightingConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired ambient lighting module config requesting via PKI admin")
_ = bleManager.requestAmbientLightingConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty ambient lighting module config")
_ = bleManager.requestAmbientLightingConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift
index 4f580b2a..b5dfee63 100644
--- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift
+++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift
@@ -236,7 +236,6 @@ struct CannedMessagesConfig: View {
.onFirstAppear {
// Need to request a CannedMessagesModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty canned message config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -244,10 +243,12 @@ struct CannedMessagesConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.cannedMessageConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired canned messages module config requesting via PKI admin")
_ = bleManager.requestCannedMessagesModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty canned messages module config")
_ = bleManager.requestCannedMessagesModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift
index aff3dfea..59ee4f3f 100644
--- a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift
+++ b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift
@@ -194,7 +194,6 @@ struct DetectionSensorConfig: View {
.onFirstAppear {
// Need to request a DetectionSensorModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty detection sensor config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -202,10 +201,12 @@ struct DetectionSensorConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.detectionSensorConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired detection sensor module config requesting via PKI admin")
_ = bleManager.requestDetectionSensorModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty detection sensor module config")
_ = bleManager.requestDetectionSensorModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift
index a0f14c7f..9602c44b 100644
--- a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift
+++ b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift
@@ -202,7 +202,6 @@ struct ExternalNotificationConfig: View {
.onFirstAppear {
// Need to request a ExternalNotificationModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty external notificaiton module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -210,10 +209,12 @@ struct ExternalNotificationConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.externalNotificationConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired external notificaiton module config requesting via PKI admin")
_ = bleManager.requestExternalNotificationModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty external notificaiton module config")
_ = bleManager.requestExternalNotificationModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift
index 224fd43c..fc93e6f9 100644
--- a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift
+++ b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift
@@ -322,7 +322,6 @@ struct MQTTConfig: View {
.onFirstAppear {
// Need to request a MqttModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty mqtt module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -330,10 +329,12 @@ struct MQTTConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.mqttConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired mqtt module config requesting via PKI admin")
_ = bleManager.requestMqttModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty mqtt module config")
_ = bleManager.requestMqttModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
@@ -346,8 +347,8 @@ struct MQTTConfig: View {
nearbyTopics = []
let geocoder = CLGeocoder()
if LocationsHandler.shared.locationsArray.count > 0 {
- let region = RegionCodes(rawValue: Int(node?.loRaConfig?.regionCode ?? 0))?.topic
- defaultTopic = "msh/" + (region ?? "UNSET")
+ let region = RegionCodes(rawValue: Int(node?.loRaConfig?.regionCode ?? 0))
+ defaultTopic = "msh/" + (region?.topic ?? "UNSET")
geocoder.reverseGeocodeLocation(LocationsHandler.shared.locationsArray.first!, completionHandler: {(placemarks, error) in
if let error {
Logger.services.error("Failed to reverse geocode location: \(error.localizedDescription)")
@@ -356,8 +357,8 @@ struct MQTTConfig: View {
if let placemarks = placemarks, let placemark = placemarks.first {
let cc = locale.region?.identifier ?? "UNK"
- /// Country Topic unless you are US
- if placemark.isoCountryCode ?? "unknown" != cc {
+ /// Country Topic unless your region is a country
+ if !(region?.isCountry ?? false) {
let countryTopic = defaultTopic + "/" + (placemark.isoCountryCode ?? "")
if !countryTopic.isEmpty {
nearbyTopics.append(countryTopic)
diff --git a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift
index 2fd97646..24af3504 100644
--- a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift
+++ b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift
@@ -61,7 +61,6 @@ struct PaxCounterConfig: View {
.onFirstAppear {
// Need to request a PaxCounterModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty pax counter module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -69,10 +68,12 @@ struct PaxCounterConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.paxCounterConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired pax counter module config requesting via PKI admin")
_ = bleManager.requestPaxCounterModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty pax counter module config")
_ = bleManager.requestPaxCounterModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift
index ae4797fc..979eb736 100644
--- a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift
+++ b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift
@@ -84,7 +84,6 @@ struct RangeTestConfig: View {
.onFirstAppear {
// Need to request a RangeTestModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty range test module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -92,10 +91,12 @@ struct RangeTestConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.rangeTestConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired range test module config requesting via PKI admin")
_ = bleManager.requestRangeTestModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty range test module config")
_ = bleManager.requestRangeTestModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift b/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift
index 2e0931a7..b81e2348 100644
--- a/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift
+++ b/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift
@@ -75,7 +75,6 @@ struct RtttlConfig: View {
.onFirstAppear {
// Need to request a RtttlConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty range test module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -83,10 +82,12 @@ struct RtttlConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.rtttlConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired ringtone module config requesting via PKI admin")
_ = bleManager.requestRtttlConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty ringtone module config")
_ = bleManager.requestRtttlConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift
index a7fd5bdb..fd2c0c99 100644
--- a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift
+++ b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift
@@ -139,7 +139,6 @@ struct SerialConfig: View {
.onFirstAppear {
// Need to request a SerialModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty serial module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -147,10 +146,12 @@ struct SerialConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.serialConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired serial module config requesting via PKI admin")
_ = bleManager.requestSerialModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty serial module config")
_ = bleManager.requestSerialModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift
index d90ea3fb..9c247acf 100644
--- a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift
+++ b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift
@@ -149,7 +149,6 @@ struct StoreForwardConfig: View {
.onFirstAppear {
// Need to request a StoreForwardModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty store & forward module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -157,10 +156,12 @@ struct StoreForwardConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.storeForwardConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired store & forward module config requesting via PKI admin")
_ = bleManager.requestStoreAndForwardModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty store & forward module config")
_ = bleManager.requestStoreAndForwardModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift
index 4ba39834..ad173dae 100644
--- a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift
+++ b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift
@@ -137,7 +137,6 @@ struct TelemetryConfig: View {
.onFirstAppear {
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty telemetry module config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -145,10 +144,12 @@ struct TelemetryConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.telemetryConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired telemetry module config requesting via PKI admin")
_ = bleManager.requestTelemetryModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty telemetry module config")
_ = bleManager.requestTelemetryModuleConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/NetworkConfig.swift b/Meshtastic/Views/Settings/Config/NetworkConfig.swift
index 8cebde85..84f48c41 100644
--- a/Meshtastic/Views/Settings/Config/NetworkConfig.swift
+++ b/Meshtastic/Views/Settings/Config/NetworkConfig.swift
@@ -133,7 +133,6 @@ struct NetworkConfig: View {
.onFirstAppear {
// Need to request a NetworkConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty network config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -141,10 +140,12 @@ struct NetworkConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.networkConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired network config requesting via PKI admin")
_ = bleManager.requestNetworkConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty network config")
_ = bleManager.requestNetworkConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/PositionConfig.swift b/Meshtastic/Views/Settings/Config/PositionConfig.swift
index 451ac02d..f963b02b 100644
--- a/Meshtastic/Views/Settings/Config/PositionConfig.swift
+++ b/Meshtastic/Views/Settings/Config/PositionConfig.swift
@@ -410,7 +410,6 @@ struct PositionConfig: View {
supportedVersion = bleManager.connectedVersion == "0.0.0" || self.minimumVersion.compare(bleManager.connectedVersion, options: .numeric) == .orderedAscending || minimumVersion.compare(bleManager.connectedVersion, options: .numeric) == .orderedSame
// Need to request a NetworkConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty position config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -418,10 +417,12 @@ struct PositionConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.positionConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired position config requesting via PKI admin")
_ = bleManager.requestPositionConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty position config")
_ = bleManager.requestPositionConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/PowerConfig.swift b/Meshtastic/Views/Settings/Config/PowerConfig.swift
index 822fd1e0..e9f7c0e5 100644
--- a/Meshtastic/Views/Settings/Config/PowerConfig.swift
+++ b/Meshtastic/Views/Settings/Config/PowerConfig.swift
@@ -130,7 +130,7 @@ struct PowerConfig: View {
}
// Need to request a NetworkConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty power config")
+
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -138,10 +138,12 @@ struct PowerConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.powerConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired power config requesting via PKI admin")
_ = bleManager.requestPowerConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty power config")
_ = bleManager.requestPowerConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Config/SecurityConfig.swift b/Meshtastic/Views/Settings/Config/SecurityConfig.swift
index 5fb391b3..6f16c8ff 100644
--- a/Meshtastic/Views/Settings/Config/SecurityConfig.swift
+++ b/Meshtastic/Views/Settings/Config/SecurityConfig.swift
@@ -85,7 +85,7 @@ struct SecurityConfig: View {
.font(idiom == .phone ? .caption : .callout)
Divider()
Label("Tertiary Admin Key", systemImage: "key.viewfinder")
- SecureInput("Tertiary Admin Key", text: $adminKey3, isValid: $hasValidAdminKey2)
+ SecureInput("Tertiary Admin Key", text: $adminKey3, isValid: $hasValidAdminKey3)
.background(
RoundedRectangle(cornerRadius: 10.0)
.stroke(hasValidAdminKey3 ? Color.clear : Color.red, lineWidth: 2.0)
@@ -198,7 +198,6 @@ struct SecurityConfig: View {
.onFirstAppear {
// Need to request a DeviceConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
- Logger.mesh.info("empty security config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
if let connectedNode {
if node.num != connectedNode.num {
@@ -206,11 +205,13 @@ struct SecurityConfig: View {
/// 2.5 Administration with session passkey
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.securityConfig == nil {
+ Logger.mesh.info("⚙️ Empty or expired security config requesting via PKI admin")
_ = bleManager.requestSecurityConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {
if node.deviceConfig == nil {
/// Legacy Administration
+ Logger.mesh.info("☠️ Using insecure legacy admin, empty security config")
_ = bleManager.requestSecurityConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
diff --git a/Meshtastic/Views/Settings/Firmware.swift b/Meshtastic/Views/Settings/Firmware.swift
index 9962e69d..6e1427bf 100644
--- a/Meshtastic/Views/Settings/Firmware.swift
+++ b/Meshtastic/Views/Settings/Firmware.swift
@@ -185,7 +185,7 @@ struct Firmware: View {
}
.padding()
.padding(.bottom, 5)
- .onAppear {
+ .onFirstAppear {
Api().loadDeviceHardwareData { (hw) in
for device in hw {
let currentHardware = node?.user?.hwModel ?? "UNSET"
diff --git a/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift
index 9e7fe0c5..1f51447d 100644
--- a/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift
+++ b/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift
@@ -416,6 +416,26 @@ public struct AdminMessage {
set {payloadVariant = .storeUiConfig(newValue)}
}
+ ///
+ /// Set specified node-num to be ignored on the NodeDB on the device
+ public var setIgnoredNode: UInt32 {
+ get {
+ if case .setIgnoredNode(let v)? = payloadVariant {return v}
+ return 0
+ }
+ set {payloadVariant = .setIgnoredNode(newValue)}
+ }
+
+ ///
+ /// Set specified node-num to be un-ignored on the NodeDB on the device
+ public var removeIgnoredNode: UInt32 {
+ get {
+ if case .removeIgnoredNode(let v)? = payloadVariant {return v}
+ return 0
+ }
+ set {payloadVariant = .removeIgnoredNode(newValue)}
+ }
+
///
/// Begins an edit transaction for config, module config, owner, and channel settings changes
/// This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings)
@@ -633,6 +653,12 @@ public struct AdminMessage {
/// Tell the node to store UI data persistently.
case storeUiConfig(DeviceUIConfig)
///
+ /// Set specified node-num to be ignored on the NodeDB on the device
+ case setIgnoredNode(UInt32)
+ ///
+ /// Set specified node-num to be un-ignored on the NodeDB on the device
+ case removeIgnoredNode(UInt32)
+ ///
/// Begins an edit transaction for config, module config, owner, and channel settings changes
/// This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings)
case beginEditSettings(Bool)
@@ -817,6 +843,14 @@ public struct AdminMessage {
guard case .storeUiConfig(let l) = lhs, case .storeUiConfig(let r) = rhs else { preconditionFailure() }
return l == r
}()
+ case (.setIgnoredNode, .setIgnoredNode): return {
+ guard case .setIgnoredNode(let l) = lhs, case .setIgnoredNode(let r) = rhs else { preconditionFailure() }
+ return l == r
+ }()
+ case (.removeIgnoredNode, .removeIgnoredNode): return {
+ guard case .removeIgnoredNode(let l) = lhs, case .removeIgnoredNode(let r) = rhs else { preconditionFailure() }
+ return l == r
+ }()
case (.beginEditSettings, .beginEditSettings): return {
guard case .beginEditSettings(let l) = lhs, case .beginEditSettings(let r) = rhs else { preconditionFailure() }
return l == r
@@ -1184,6 +1218,8 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
44: .standard(proto: "get_ui_config_request"),
45: .standard(proto: "get_ui_config_response"),
46: .standard(proto: "store_ui_config"),
+ 47: .standard(proto: "set_ignored_node"),
+ 48: .standard(proto: "remove_ignored_node"),
64: .standard(proto: "begin_edit_settings"),
65: .standard(proto: "commit_edit_settings"),
94: .standard(proto: "factory_reset_device"),
@@ -1572,6 +1608,22 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
self.payloadVariant = .storeUiConfig(v)
}
}()
+ case 47: try {
+ var v: UInt32?
+ try decoder.decodeSingularUInt32Field(value: &v)
+ if let v = v {
+ if self.payloadVariant != nil {try decoder.handleConflictingOneOf()}
+ self.payloadVariant = .setIgnoredNode(v)
+ }
+ }()
+ case 48: try {
+ var v: UInt32?
+ try decoder.decodeSingularUInt32Field(value: &v)
+ if let v = v {
+ if self.payloadVariant != nil {try decoder.handleConflictingOneOf()}
+ self.payloadVariant = .removeIgnoredNode(v)
+ }
+ }()
case 64: try {
var v: Bool?
try decoder.decodeSingularBoolField(value: &v)
@@ -1804,6 +1856,14 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
guard case .storeUiConfig(let v)? = self.payloadVariant else { preconditionFailure() }
try visitor.visitSingularMessageField(value: v, fieldNumber: 46)
}()
+ case .setIgnoredNode?: try {
+ guard case .setIgnoredNode(let v)? = self.payloadVariant else { preconditionFailure() }
+ try visitor.visitSingularUInt32Field(value: v, fieldNumber: 47)
+ }()
+ case .removeIgnoredNode?: try {
+ guard case .removeIgnoredNode(let v)? = self.payloadVariant else { preconditionFailure() }
+ try visitor.visitSingularUInt32Field(value: v, fieldNumber: 48)
+ }()
case .beginEditSettings?: try {
guard case .beginEditSettings(let v)? = self.payloadVariant else { preconditionFailure() }
try visitor.visitSingularBoolField(value: v, fieldNumber: 64)
diff --git a/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift
index f677d644..6c4dbe93 100644
--- a/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift
+++ b/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift
@@ -134,6 +134,10 @@ public enum Language: SwiftProtobuf.Enum {
/// Greek
case greek // = 13
+ ///
+ /// Norwegian
+ case norwegian // = 14
+
///
/// Simplified Chinese (experimental)
case simplifiedChinese // = 30
@@ -163,6 +167,7 @@ public enum Language: SwiftProtobuf.Enum {
case 11: self = .russian
case 12: self = .dutch
case 13: self = .greek
+ case 14: self = .norwegian
case 30: self = .simplifiedChinese
case 31: self = .traditionalChinese
default: self = .UNRECOGNIZED(rawValue)
@@ -185,6 +190,7 @@ public enum Language: SwiftProtobuf.Enum {
case .russian: return 11
case .dutch: return 12
case .greek: return 13
+ case .norwegian: return 14
case .simplifiedChinese: return 30
case .traditionalChinese: return 31
case .UNRECOGNIZED(let i): return i
@@ -212,6 +218,7 @@ extension Language: CaseIterable {
.russian,
.dutch,
.greek,
+ .norwegian,
.simplifiedChinese,
.traditionalChinese,
]
@@ -315,6 +322,13 @@ public struct DeviceUIConfig {
/// Clears the value of `nodeHighlight`. Subsequent reads from it will return its default value.
public mutating func clearNodeHighlight() {_uniqueStorage()._nodeHighlight = nil}
+ ///
+ /// 8 integers for screen calibration data
+ public var calibrationData: Data {
+ get {return _storage._calibrationData}
+ set {_uniqueStorage()._calibrationData = newValue}
+ }
+
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
@@ -422,6 +436,7 @@ extension Language: SwiftProtobuf._ProtoNameProviding {
11: .same(proto: "RUSSIAN"),
12: .same(proto: "DUTCH"),
13: .same(proto: "GREEK"),
+ 14: .same(proto: "NORWEGIAN"),
30: .same(proto: "SIMPLIFIED_CHINESE"),
31: .same(proto: "TRADITIONAL_CHINESE"),
]
@@ -443,6 +458,7 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
11: .same(proto: "language"),
12: .standard(proto: "node_filter"),
13: .standard(proto: "node_highlight"),
+ 14: .standard(proto: "calibration_data"),
]
fileprivate class _StorageClass {
@@ -459,6 +475,7 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
var _language: Language = .english
var _nodeFilter: NodeFilter? = nil
var _nodeHighlight: NodeHighlight? = nil
+ var _calibrationData: Data = Data()
#if swift(>=5.10)
// This property is used as the initial default value for new instances of the type.
@@ -486,6 +503,7 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
_language = source._language
_nodeFilter = source._nodeFilter
_nodeHighlight = source._nodeHighlight
+ _calibrationData = source._calibrationData
}
}
@@ -517,6 +535,7 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
case 11: try { try decoder.decodeSingularEnumField(value: &_storage._language) }()
case 12: try { try decoder.decodeSingularMessageField(value: &_storage._nodeFilter) }()
case 13: try { try decoder.decodeSingularMessageField(value: &_storage._nodeHighlight) }()
+ case 14: try { try decoder.decodeSingularBytesField(value: &_storage._calibrationData) }()
default: break
}
}
@@ -568,6 +587,9 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
try { if let v = _storage._nodeHighlight {
try visitor.visitSingularMessageField(value: v, fieldNumber: 13)
} }()
+ if !_storage._calibrationData.isEmpty {
+ try visitor.visitSingularBytesField(value: _storage._calibrationData, fieldNumber: 14)
+ }
}
try unknownFields.traverse(visitor: &visitor)
}
@@ -590,6 +612,7 @@ extension DeviceUIConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
if _storage._language != rhs_storage._language {return false}
if _storage._nodeFilter != rhs_storage._nodeFilter {return false}
if _storage._nodeHighlight != rhs_storage._nodeHighlight {return false}
+ if _storage._calibrationData != rhs_storage._calibrationData {return false}
return true
}
if !storagesAreEqual {return false}
diff --git a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift
index 3349c2c9..34a33373 100644
--- a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift
+++ b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift
@@ -196,6 +196,21 @@ public struct NodeInfoLite {
set {_uniqueStorage()._isFavorite = newValue}
}
+ ///
+ /// True if node is in our ignored list
+ /// Persists between NodeDB internal clean ups
+ public var isIgnored: Bool {
+ get {return _storage._isIgnored}
+ set {_uniqueStorage()._isIgnored = newValue}
+ }
+
+ ///
+ /// Last byte of the node number of the node that should be used as the next hop to reach this node.
+ public var nextHop: UInt32 {
+ get {return _storage._nextHop}
+ set {_uniqueStorage()._nextHop = newValue}
+ }
+
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
@@ -486,6 +501,8 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
8: .standard(proto: "via_mqtt"),
9: .standard(proto: "hops_away"),
10: .standard(proto: "is_favorite"),
+ 11: .standard(proto: "is_ignored"),
+ 12: .standard(proto: "next_hop"),
]
fileprivate class _StorageClass {
@@ -499,6 +516,8 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
var _viaMqtt: Bool = false
var _hopsAway: UInt32? = nil
var _isFavorite: Bool = false
+ var _isIgnored: Bool = false
+ var _nextHop: UInt32 = 0
#if swift(>=5.10)
// This property is used as the initial default value for new instances of the type.
@@ -523,6 +542,8 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
_viaMqtt = source._viaMqtt
_hopsAway = source._hopsAway
_isFavorite = source._isFavorite
+ _isIgnored = source._isIgnored
+ _nextHop = source._nextHop
}
}
@@ -551,6 +572,8 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
case 8: try { try decoder.decodeSingularBoolField(value: &_storage._viaMqtt) }()
case 9: try { try decoder.decodeSingularUInt32Field(value: &_storage._hopsAway) }()
case 10: try { try decoder.decodeSingularBoolField(value: &_storage._isFavorite) }()
+ case 11: try { try decoder.decodeSingularBoolField(value: &_storage._isIgnored) }()
+ case 12: try { try decoder.decodeSingularUInt32Field(value: &_storage._nextHop) }()
default: break
}
}
@@ -593,6 +616,12 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
if _storage._isFavorite != false {
try visitor.visitSingularBoolField(value: _storage._isFavorite, fieldNumber: 10)
}
+ if _storage._isIgnored != false {
+ try visitor.visitSingularBoolField(value: _storage._isIgnored, fieldNumber: 11)
+ }
+ if _storage._nextHop != 0 {
+ try visitor.visitSingularUInt32Field(value: _storage._nextHop, fieldNumber: 12)
+ }
}
try unknownFields.traverse(visitor: &visitor)
}
@@ -612,6 +641,8 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
if _storage._viaMqtt != rhs_storage._viaMqtt {return false}
if _storage._hopsAway != rhs_storage._hopsAway {return false}
if _storage._isFavorite != rhs_storage._isFavorite {return false}
+ if _storage._isIgnored != rhs_storage._isIgnored {return false}
+ if _storage._nextHop != rhs_storage._nextHop {return false}
return true
}
if !storagesAreEqual {return false}
diff --git a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift
index 154d8a6b..434d1ec9 100644
--- a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift
+++ b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift
@@ -380,6 +380,11 @@ public enum HardwareModel: SwiftProtobuf.Enum {
/// Lilygo TLora-C6 with the new ESP32-C6 MCU
case tloraC6 // = 83
+ ///
+ /// WisMesh Tap
+ /// RAK-4631 w/ TFT in injection modled case
+ case wismeshTap // = 84
+
///
/// ------------------------------------------------------------------------------------------------------------------------------------------
/// Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
@@ -477,6 +482,7 @@ public enum HardwareModel: SwiftProtobuf.Enum {
case 81: self = .seeedXiaoS3
case 82: self = .ms24Sf1
case 83: self = .tloraC6
+ case 84: self = .wismeshTap
case 255: self = .privateHw
default: self = .UNRECOGNIZED(rawValue)
}
@@ -568,6 +574,7 @@ public enum HardwareModel: SwiftProtobuf.Enum {
case .seeedXiaoS3: return 81
case .ms24Sf1: return 82
case .tloraC6: return 83
+ case .wismeshTap: return 84
case .privateHw: return 255
case .UNRECOGNIZED(let i): return i
}
@@ -664,6 +671,7 @@ extension HardwareModel: CaseIterable {
.seeedXiaoS3,
.ms24Sf1,
.tloraC6,
+ .wismeshTap,
.privateHw,
]
}
@@ -684,7 +692,7 @@ public enum Constants: SwiftProtobuf.Enum {
/// From mesh.options
/// note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is
/// outside of this envelope
- case dataPayloadLen // = 237
+ case dataPayloadLen // = 233
case UNRECOGNIZED(Int)
public init() {
@@ -694,7 +702,7 @@ public enum Constants: SwiftProtobuf.Enum {
public init?(rawValue: Int) {
switch rawValue {
case 0: self = .zero
- case 237: self = .dataPayloadLen
+ case 233: self = .dataPayloadLen
default: self = .UNRECOGNIZED(rawValue)
}
}
@@ -702,7 +710,7 @@ public enum Constants: SwiftProtobuf.Enum {
public var rawValue: Int {
switch self {
case .zero: return 0
- case .dataPayloadLen: return 237
+ case .dataPayloadLen: return 233
case .UNRECOGNIZED(let i): return i
}
}
@@ -2055,6 +2063,22 @@ public struct MeshPacket {
set {_uniqueStorage()._pkiEncrypted = newValue}
}
+ ///
+ /// Last byte of the node number of the node that should be used as the next hop in routing.
+ /// Set by the firmware internally, clients are not supposed to set this.
+ public var nextHop: UInt32 {
+ get {return _storage._nextHop}
+ set {_uniqueStorage()._nextHop = newValue}
+ }
+
+ ///
+ /// Last byte of the node number of the node that will relay/relayed this packet.
+ /// Set by the firmware internally, clients are not supposed to set this.
+ public var relayNode: UInt32 {
+ get {return _storage._relayNode}
+ set {_uniqueStorage()._relayNode = newValue}
+ }
+
public var unknownFields = SwiftProtobuf.UnknownStorage()
public enum OneOf_PayloadVariant: Equatable {
@@ -2370,6 +2394,14 @@ public struct NodeInfo {
set {_uniqueStorage()._isFavorite = newValue}
}
+ ///
+ /// True if node is in our ignored list
+ /// Persists between NodeDB internal clean ups
+ public var isIgnored: Bool {
+ get {return _storage._isIgnored}
+ set {_uniqueStorage()._isIgnored = newValue}
+ }
+
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
@@ -3526,6 +3558,7 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding {
81: .same(proto: "SEEED_XIAO_S3"),
82: .same(proto: "MS24SF1"),
83: .same(proto: "TLORA_C6"),
+ 84: .same(proto: "WISMESH_TAP"),
255: .same(proto: "PRIVATE_HW"),
]
}
@@ -3533,7 +3566,7 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding {
extension Constants: SwiftProtobuf._ProtoNameProviding {
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "ZERO"),
- 237: .same(proto: "DATA_PAYLOAD_LEN"),
+ 233: .same(proto: "DATA_PAYLOAD_LEN"),
]
}
@@ -4328,6 +4361,8 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
15: .standard(proto: "hop_start"),
16: .standard(proto: "public_key"),
17: .standard(proto: "pki_encrypted"),
+ 18: .standard(proto: "next_hop"),
+ 19: .standard(proto: "relay_node"),
]
fileprivate class _StorageClass {
@@ -4347,6 +4382,8 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
var _hopStart: UInt32 = 0
var _publicKey: Data = Data()
var _pkiEncrypted: Bool = false
+ var _nextHop: UInt32 = 0
+ var _relayNode: UInt32 = 0
#if swift(>=5.10)
// This property is used as the initial default value for new instances of the type.
@@ -4377,6 +4414,8 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
_hopStart = source._hopStart
_publicKey = source._publicKey
_pkiEncrypted = source._pkiEncrypted
+ _nextHop = source._nextHop
+ _relayNode = source._relayNode
}
}
@@ -4431,6 +4470,8 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
case 15: try { try decoder.decodeSingularUInt32Field(value: &_storage._hopStart) }()
case 16: try { try decoder.decodeSingularBytesField(value: &_storage._publicKey) }()
case 17: try { try decoder.decodeSingularBoolField(value: &_storage._pkiEncrypted) }()
+ case 18: try { try decoder.decodeSingularUInt32Field(value: &_storage._nextHop) }()
+ case 19: try { try decoder.decodeSingularUInt32Field(value: &_storage._relayNode) }()
default: break
}
}
@@ -4499,6 +4540,12 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
if _storage._pkiEncrypted != false {
try visitor.visitSingularBoolField(value: _storage._pkiEncrypted, fieldNumber: 17)
}
+ if _storage._nextHop != 0 {
+ try visitor.visitSingularUInt32Field(value: _storage._nextHop, fieldNumber: 18)
+ }
+ if _storage._relayNode != 0 {
+ try visitor.visitSingularUInt32Field(value: _storage._relayNode, fieldNumber: 19)
+ }
}
try unknownFields.traverse(visitor: &visitor)
}
@@ -4524,6 +4571,8 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
if _storage._hopStart != rhs_storage._hopStart {return false}
if _storage._publicKey != rhs_storage._publicKey {return false}
if _storage._pkiEncrypted != rhs_storage._pkiEncrypted {return false}
+ if _storage._nextHop != rhs_storage._nextHop {return false}
+ if _storage._relayNode != rhs_storage._relayNode {return false}
return true
}
if !storagesAreEqual {return false}
@@ -4568,6 +4617,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
8: .standard(proto: "via_mqtt"),
9: .standard(proto: "hops_away"),
10: .standard(proto: "is_favorite"),
+ 11: .standard(proto: "is_ignored"),
]
fileprivate class _StorageClass {
@@ -4581,6 +4631,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
var _viaMqtt: Bool = false
var _hopsAway: UInt32? = nil
var _isFavorite: Bool = false
+ var _isIgnored: Bool = false
#if swift(>=5.10)
// This property is used as the initial default value for new instances of the type.
@@ -4605,6 +4656,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
_viaMqtt = source._viaMqtt
_hopsAway = source._hopsAway
_isFavorite = source._isFavorite
+ _isIgnored = source._isIgnored
}
}
@@ -4633,6 +4685,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
case 8: try { try decoder.decodeSingularBoolField(value: &_storage._viaMqtt) }()
case 9: try { try decoder.decodeSingularUInt32Field(value: &_storage._hopsAway) }()
case 10: try { try decoder.decodeSingularBoolField(value: &_storage._isFavorite) }()
+ case 11: try { try decoder.decodeSingularBoolField(value: &_storage._isIgnored) }()
default: break
}
}
@@ -4675,6 +4728,9 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
if _storage._isFavorite != false {
try visitor.visitSingularBoolField(value: _storage._isFavorite, fieldNumber: 10)
}
+ if _storage._isIgnored != false {
+ try visitor.visitSingularBoolField(value: _storage._isIgnored, fieldNumber: 11)
+ }
}
try unknownFields.traverse(visitor: &visitor)
}
@@ -4694,6 +4750,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
if _storage._viaMqtt != rhs_storage._viaMqtt {return false}
if _storage._hopsAway != rhs_storage._hopsAway {return false}
if _storage._isFavorite != rhs_storage._isFavorite {return false}
+ if _storage._isIgnored != rhs_storage._isIgnored {return false}
return true
}
if !storagesAreEqual {return false}
diff --git a/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift
index e67b5272..1ce50e07 100644
--- a/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift
+++ b/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift
@@ -156,6 +156,10 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum {
///
/// SCD40/SCD41 CO2, humidity, temperature sensor
case scd4X // = 32
+
+ ///
+ /// ClimateGuard RadSens, radiation, Geiger-Muller Tube
+ case radsens // = 33
case UNRECOGNIZED(Int)
public init() {
@@ -197,6 +201,7 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum {
case 30: self = .max30102
case 31: self = .mlx90614
case 32: self = .scd4X
+ case 33: self = .radsens
default: self = .UNRECOGNIZED(rawValue)
}
}
@@ -236,6 +241,7 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum {
case .max30102: return 30
case .mlx90614: return 31
case .scd4X: return 32
+ case .radsens: return 33
case .UNRECOGNIZED(let i): return i
}
}
@@ -280,6 +286,7 @@ extension TelemetrySensorType: CaseIterable {
.max30102,
.mlx90614,
.scd4X,
+ .radsens,
]
}
@@ -554,6 +561,17 @@ public struct EnvironmentMetrics {
/// Clears the value of `windLull`. Subsequent reads from it will return its default value.
public mutating func clearWindLull() {_uniqueStorage()._windLull = nil}
+ ///
+ /// Radiation in µR/h
+ public var radiation: Float {
+ get {return _storage._radiation ?? 0}
+ set {_uniqueStorage()._radiation = newValue}
+ }
+ /// Returns true if `radiation` has been explicitly set.
+ public var hasRadiation: Bool {return _storage._radiation != nil}
+ /// Clears the value of `radiation`. Subsequent reads from it will return its default value.
+ public mutating func clearRadiation() {_uniqueStorage()._radiation = nil}
+
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
@@ -1128,6 +1146,7 @@ extension TelemetrySensorType: SwiftProtobuf._ProtoNameProviding {
30: .same(proto: "MAX30102"),
31: .same(proto: "MLX90614"),
32: .same(proto: "SCD4X"),
+ 33: .same(proto: "RADSENS"),
]
}
@@ -1211,6 +1230,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
15: .same(proto: "weight"),
16: .standard(proto: "wind_gust"),
17: .standard(proto: "wind_lull"),
+ 18: .same(proto: "radiation"),
]
fileprivate class _StorageClass {
@@ -1231,6 +1251,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
var _weight: Float? = nil
var _windGust: Float? = nil
var _windLull: Float? = nil
+ var _radiation: Float? = nil
#if swift(>=5.10)
// This property is used as the initial default value for new instances of the type.
@@ -1262,6 +1283,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
_weight = source._weight
_windGust = source._windGust
_windLull = source._windLull
+ _radiation = source._radiation
}
}
@@ -1297,6 +1319,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
case 15: try { try decoder.decodeSingularFloatField(value: &_storage._weight) }()
case 16: try { try decoder.decodeSingularFloatField(value: &_storage._windGust) }()
case 17: try { try decoder.decodeSingularFloatField(value: &_storage._windLull) }()
+ case 18: try { try decoder.decodeSingularFloatField(value: &_storage._radiation) }()
default: break
}
}
@@ -1360,6 +1383,9 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
try { if let v = _storage._windLull {
try visitor.visitSingularFloatField(value: v, fieldNumber: 17)
} }()
+ try { if let v = _storage._radiation {
+ try visitor.visitSingularFloatField(value: v, fieldNumber: 18)
+ } }()
}
try unknownFields.traverse(visitor: &visitor)
}
@@ -1386,6 +1412,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
if _storage._weight != rhs_storage._weight {return false}
if _storage._windGust != rhs_storage._windGust {return false}
if _storage._windLull != rhs_storage._windLull {return false}
+ if _storage._radiation != rhs_storage._radiation {return false}
return true
}
if !storagesAreEqual {return false}
diff --git a/Widgets/MeshActivityAttributes.swift b/Widgets/MeshActivityAttributes.swift
index 876b75de..37376531 100644
--- a/Widgets/MeshActivityAttributes.swift
+++ b/Widgets/MeshActivityAttributes.swift
@@ -4,7 +4,7 @@
//
// Created by Garth Vander Houwen on 3/1/23.
//
-
+#if !targetEnvironment(macCatalyst)
#if canImport(ActivityKit)
import ActivityKit
@@ -36,3 +36,4 @@ struct MeshActivityAttributes: ActivityAttributes {
var name: String
}
#endif
+#endif
diff --git a/protobufs b/protobufs
index 04f21f5c..02e6576e 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit 04f21f5c7238b8e02f794d9282c4786752634b3c
+Subproject commit 02e6576efaa2f691be9504b8c1c6261703f7a277