From 2b97576b187e63d139fa1c211c323f76e8dc5f7f Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 27 Jun 2025 06:26:34 -0500 Subject: [PATCH 01/11] NRF52 BLE fixes / tweaks (#7152) * Try-fix: Flaky NRF52 bluetooth pairing for some users * Safe access for screen pointer --- src/platform/nrf52/NRF52Bluetooth.cpp | 57 +++++++++++++++------------ 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index 89e92afc6..6f0e7250f 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -314,7 +314,9 @@ void NRF52Bluetooth::onConnectionSecured(uint16_t conn_handle) } bool NRF52Bluetooth::onPairingPasskey(uint16_t conn_handle, uint8_t const passkey[6], bool match_request) { - LOG_INFO("BLE pair process started with passkey %.3s %.3s", passkey, passkey + 3); + char passkey1[4] = {passkey[0], passkey[1], passkey[2], '\0'}; + char passkey2[4] = {passkey[3], passkey[4], passkey[5], '\0'}; + LOG_INFO("BLE pair process started with passkey %s %s", passkey1, passkey2); powerFSM.trigger(EVENT_BLUETOOTH_PAIR); // Get passkey as string @@ -327,31 +329,33 @@ bool NRF52Bluetooth::onPairingPasskey(uint16_t conn_handle, uint8_t const passke bluetoothStatus->updateStatus(new meshtastic::BluetoothStatus(textkey)); #if !defined(MESHTASTIC_EXCLUDE_SCREEN) // Todo: migrate this display code back into Screen class, and observe bluetoothStatus - screen->startAlert([](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void { - char btPIN[16] = "888888"; - snprintf(btPIN, sizeof(btPIN), "%06u", configuredPasskey); - int x_offset = display->width() / 2; - int y_offset = display->height() <= 80 ? 0 : 12; - display->setTextAlignment(TEXT_ALIGN_CENTER); - display->setFont(FONT_MEDIUM); - display->drawString(x_offset + x, y_offset + y, "Bluetooth"); + if (screen) { + screen->startAlert([](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void { + char btPIN[16] = "888888"; + snprintf(btPIN, sizeof(btPIN), "%06u", configuredPasskey); + int x_offset = display->width() / 2; + int y_offset = display->height() <= 80 ? 0 : 12; + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(FONT_MEDIUM); + display->drawString(x_offset + x, y_offset + y, "Bluetooth"); - display->setFont(FONT_SMALL); - y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM - 4 : y_offset + FONT_HEIGHT_MEDIUM + 5; - display->drawString(x_offset + x, y_offset + y, "Enter this code"); + display->setFont(FONT_SMALL); + y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM - 4 : y_offset + FONT_HEIGHT_MEDIUM + 5; + display->drawString(x_offset + x, y_offset + y, "Enter this code"); - display->setFont(FONT_LARGE); - String displayPin(btPIN); - String pin = displayPin.substring(0, 3) + " " + displayPin.substring(3, 6); - y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_SMALL - 5 : y_offset + FONT_HEIGHT_SMALL + 5; - display->drawString(x_offset + x, y_offset + y, pin); + display->setFont(FONT_LARGE); + String displayPin(btPIN); + String pin = displayPin.substring(0, 3) + " " + displayPin.substring(3, 6); + y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_SMALL - 5 : y_offset + FONT_HEIGHT_SMALL + 5; + display->drawString(x_offset + x, y_offset + y, pin); - display->setFont(FONT_SMALL); - String deviceName = "Name: "; - deviceName.concat(getDeviceName()); - y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_LARGE - 6 : y_offset + FONT_HEIGHT_LARGE + 5; - display->drawString(x_offset + x, y_offset + y, deviceName); - }); + display->setFont(FONT_SMALL); + String deviceName = "Name: "; + deviceName.concat(getDeviceName()); + y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_LARGE - 6 : y_offset + FONT_HEIGHT_LARGE + 5; + display->drawString(x_offset + x, y_offset + y, deviceName); + }); + } #endif if (match_request) { uint32_t start_time = millis(); @@ -394,8 +398,7 @@ void NRF52Bluetooth::onPairingCompleted(uint16_t conn_handle, uint8_t auth_statu { if (auth_status == BLE_GAP_SEC_STATUS_SUCCESS) { LOG_INFO("BLE pair success"); - bluetoothStatus->updateStatus( - new meshtastic::BluetoothStatus(meshtastic::BluetoothStatus::ConnectionState::DISCONNECTED)); + bluetoothStatus->updateStatus(new meshtastic::BluetoothStatus(meshtastic::BluetoothStatus::ConnectionState::CONNECTED)); } else { LOG_INFO("BLE pair failed"); // Notify UI (or any other interested firmware components) @@ -404,7 +407,9 @@ void NRF52Bluetooth::onPairingCompleted(uint16_t conn_handle, uint8_t auth_statu } // Todo: migrate this display code back into Screen class, and observe bluetoothStatus - screen->endAlert(); + if (screen) { + screen->endAlert(); + } } void NRF52Bluetooth::sendLog(const uint8_t *logMessage, size_t length) From de5b55921e84f477cecaff6db4ff65655e0a94a1 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 27 Jun 2025 11:06:19 -0500 Subject: [PATCH 02/11] Extra check on UDP packets --- src/mesh/udp/UdpMulticastHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesh/udp/UdpMulticastHandler.h b/src/mesh/udp/UdpMulticastHandler.h index 39bd61021..ac4f86020 100644 --- a/src/mesh/udp/UdpMulticastHandler.h +++ b/src/mesh/udp/UdpMulticastHandler.h @@ -44,7 +44,7 @@ class UdpMulticastHandler final meshtastic_MeshPacket mp; LOG_DEBUG("Decoding MeshPacket from UDP len=%u", packetLength); bool isPacketDecoded = pb_decode_from_bytes(packet.data(), packetLength, &meshtastic_MeshPacket_msg, &mp); - if (isPacketDecoded && router) { + if (isPacketDecoded && router && mp.which_payload_variant == meshtastic_MeshPacket_encrypted_tag) { UniquePacketPoolPacket p = packetPool.allocUniqueCopy(mp); // Unset received SNR/RSSI p->rx_snr = 0; From 2ea70927c88ab2da3a525c93a1798ce02dce9b1a Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 27 Jun 2025 11:06:50 -0500 Subject: [PATCH 03/11] Revert "automated bumps (#7097)" This reverts commit 4308bbc156c81a240f31c1860fd792264f5b755f. --- bin/org.meshtastic.meshtasticd.metainfo.xml | 3 --- debian/changelog | 7 ++----- version.properties | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/bin/org.meshtastic.meshtasticd.metainfo.xml b/bin/org.meshtastic.meshtasticd.metainfo.xml index f9f647dae..4b07f6388 100644 --- a/bin/org.meshtastic.meshtasticd.metainfo.xml +++ b/bin/org.meshtastic.meshtasticd.metainfo.xml @@ -87,9 +87,6 @@ - - https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.1 - https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.0 diff --git a/debian/changelog b/debian/changelog index 4629e8c3a..d607be68c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -meshtasticd (2.7.1.0) UNRELEASED; urgency=medium +meshtasticd (2.7.0.0) UNRELEASED; urgency=medium [ Austin Lane ] * Initial packaging @@ -22,7 +22,4 @@ meshtasticd (2.7.1.0) UNRELEASED; urgency=medium [ ] * GitHub Actions Automatic version bump - [ ] - * GitHub Actions Automatic version bump - - -- Sat, 21 Jun 2025 15:51:49 +0000 + -- Mon, 16 Jun 2025 02:10:49 +0000 diff --git a/version.properties b/version.properties index 3fe1aa385..91c81a0c9 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 7 -build = 1 +build = 0 From f6743798e2db0c518cd257ff2ade95eb06999ee2 Mon Sep 17 00:00:00 2001 From: porkcube Date: Fri, 27 Jun 2025 12:09:04 -0400 Subject: [PATCH 04/11] cleanup Shutting down -> Shutting Down awkwardness (#7099) Co-authored-by: Jonathan Bennett --- src/Power.cpp | 2 +- src/input/ExpressLRSFiveWay.cpp | 4 ++-- src/modules/SystemCommandsModule.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Power.cpp b/src/Power.cpp index 400b6c6eb..fb5db416e 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -682,7 +682,7 @@ bool Power::setup() void Power::shutdown() { - LOG_INFO("Shutting down"); + LOG_INFO("Shutting Down"); #if defined(ARCH_NRF52) || defined(ARCH_ESP32) || defined(ARCH_RP2040) #ifdef PIN_LED1 diff --git a/src/input/ExpressLRSFiveWay.cpp b/src/input/ExpressLRSFiveWay.cpp index 1981a45d4..53bcedc63 100644 --- a/src/input/ExpressLRSFiveWay.cpp +++ b/src/input/ExpressLRSFiveWay.cpp @@ -235,7 +235,7 @@ void ExpressLRSFiveWay::shutdown() { LOG_INFO("Shutdown from long press"); powerFSM.trigger(EVENT_PRESS); - screen->startAlert("Shutting down..."); + screen->startAlert("Shutting Down..."); // Don't set alerting = true. We don't want to auto-dismiss this alert. playShutdownMelody(); // In case user adds a buzzer @@ -250,4 +250,4 @@ void ExpressLRSFiveWay::click() ExpressLRSFiveWay *expressLRSFiveWayInput = nullptr; -#endif \ No newline at end of file +#endif diff --git a/src/modules/SystemCommandsModule.cpp b/src/modules/SystemCommandsModule.cpp index 6a7da95af..08c87ec64 100644 --- a/src/modules/SystemCommandsModule.cpp +++ b/src/modules/SystemCommandsModule.cpp @@ -107,8 +107,8 @@ int SystemCommandsModule::handleInputEvent(const InputEvent *event) return true; // Power control case INPUT_BROKER_SHUTDOWN: - LOG_ERROR("Shutting down"); - IF_SCREEN(screen->showOverlayBanner("Shutting down...")); + LOG_ERROR("Shutting Down"); + IF_SCREEN(screen->showOverlayBanner("Shutting Down...")); nodeDB->saveToDisk(); shutdownAtMsec = millis() + DEFAULT_SHUTDOWN_SECONDS * 1000; // runState = CANNED_MESSAGE_RUN_STATE_INACTIVE; @@ -119,4 +119,4 @@ int SystemCommandsModule::handleInputEvent(const InputEvent *event) break; } return false; -} \ No newline at end of file +} From a97df4bb524d0f53276a0662e286b8b385a625b1 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 27 Jun 2025 11:22:01 -0500 Subject: [PATCH 05/11] Sanity check incoming UDP --- src/mesh/udp/UdpMulticastHandler.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mesh/udp/UdpMulticastHandler.h b/src/mesh/udp/UdpMulticastHandler.h index ac4f86020..d1cc1065c 100644 --- a/src/mesh/udp/UdpMulticastHandler.h +++ b/src/mesh/udp/UdpMulticastHandler.h @@ -45,6 +45,9 @@ class UdpMulticastHandler final LOG_DEBUG("Decoding MeshPacket from UDP len=%u", packetLength); bool isPacketDecoded = pb_decode_from_bytes(packet.data(), packetLength, &meshtastic_MeshPacket_msg, &mp); if (isPacketDecoded && router && mp.which_payload_variant == meshtastic_MeshPacket_encrypted_tag) { + mp.pki_encrypted = false; + mp.public_key.size = 0; + memset(mp.public_key.bytes, 0, sizeof(mp.public_key.bytes)); UniquePacketPoolPacket p = packetPool.allocUniqueCopy(mp); // Unset received SNR/RSSI p->rx_snr = 0; From 705515ace23e8a104f20ce078a3d3c650f16c5bc Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 27 Jun 2025 11:46:33 -0500 Subject: [PATCH 06/11] Resize meshNodes to MAX + 1 to avoid crash during sort --- src/mesh/NodeDB.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 9433cc75d..cc3639f19 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -1156,7 +1156,7 @@ void NodeDB::loadFromDisk() LOG_WARN("Node count %d exceeds MAX_NUM_NODES %d, truncating", numMeshNodes, MAX_NUM_NODES); numMeshNodes = MAX_NUM_NODES; } - meshNodes->resize(MAX_NUM_NODES); + meshNodes->resize(MAX_NUM_NODES + 1); // The rp2040, rp2035, and maybe other targets, have a problem doing a sort() when full // static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM state = loadProto(deviceStateFileName, meshtastic_DeviceState_size, sizeof(meshtastic_DeviceState), From 2bcf608654facd685321779b339584644a1ecc5d Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 28 Jun 2025 08:19:31 -0500 Subject: [PATCH 07/11] Last second fixes (#7156) * Ditch the 30 second delay for button presses * Only order strictly weakly * Too many comments! * Only sort the populated meshNodes --- src/input/ButtonThread.cpp | 11 ++++++----- src/mesh/NodeDB.cpp | 33 ++++++++++++++++----------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/input/ButtonThread.cpp b/src/input/ButtonThread.cpp index da9878fa4..ad667f003 100644 --- a/src/input/ButtonThread.cpp +++ b/src/input/ButtonThread.cpp @@ -58,15 +58,15 @@ bool ButtonThread::initButton(const ButtonConfig &config) userButton.attachLongPressStart( [](void *callerThread) -> void { ButtonThread *thread = (ButtonThread *)callerThread; - if (millis() > 30000) // hold off 30s after boot - thread->btnEvent = BUTTON_EVENT_LONG_PRESSED; + // if (millis() > 30000) // hold off 30s after boot + thread->btnEvent = BUTTON_EVENT_LONG_PRESSED; }, this); userButton.attachLongPressStop( [](void *callerThread) -> void { ButtonThread *thread = (ButtonThread *)callerThread; - if (millis() > 30000) // hold off 30s after boot - thread->btnEvent = BUTTON_EVENT_LONG_RELEASED; + // if (millis() > 30000) // hold off 30s after boot + thread->btnEvent = BUTTON_EVENT_LONG_RELEASED; }, this); } @@ -254,7 +254,8 @@ int32_t ButtonThread::runOnce() case BUTTON_EVENT_LONG_RELEASED: { LOG_INFO("LONG PRESS RELEASE"); - if (_longLongPress != INPUT_BROKER_NONE && (millis() - buttonPressStartTime) >= _longLongPressTime) { + if (millis() > 30000 && _longLongPress != INPUT_BROKER_NONE && + (millis() - buttonPressStartTime) >= _longLongPressTime) { evt.inputEvent = _longLongPress; this->notifyObservers(&evt); } diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index cc3639f19..8990d4b4f 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -1694,23 +1694,22 @@ void NodeDB::sortMeshDB() { if (!Throttle::isWithinTimespanMs(lastSort, 1000 * 5)) { lastSort = millis(); - std::sort(meshNodes->begin(), meshNodes->end(), [](const meshtastic_NodeInfoLite &a, const meshtastic_NodeInfoLite &b) { - if (a.num == myNodeInfo.my_node_num) { - return true; - } - if (b.num == myNodeInfo.my_node_num) { - return false; - } - bool aFav = a.is_favorite; - bool bFav = b.is_favorite; - if (aFav != bFav) - return aFav; - if (a.last_heard == 0 || a.last_heard == UINT32_MAX) - return false; - if (b.last_heard == 0 || b.last_heard == UINT32_MAX) - return true; - return a.last_heard > b.last_heard; - }); + std::sort(meshNodes->begin(), meshNodes->begin() + numMeshNodes, + [](const meshtastic_NodeInfoLite &a, const meshtastic_NodeInfoLite &b) { + if (a.num == myNodeInfo.my_node_num) { + return true; + } + if (b.num == myNodeInfo.my_node_num) { + return false; + } + bool aFav = a.is_favorite; + bool bFav = b.is_favorite; + if (aFav != bFav) + return aFav; + if (a.last_heard != b.last_heard) + return a.last_heard > b.last_heard; + return a.num > b.num; + }); } } From b6a13f1114ed2c259881fd8761832a5aaae97d3b Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 28 Jun 2025 22:54:03 -0500 Subject: [PATCH 08/11] Add check for theoretically impossible comparison, and drop nodenum comparison (#7165) --- src/mesh/NodeDB.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 8990d4b4f..bd4911a9b 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -1696,6 +1696,8 @@ void NodeDB::sortMeshDB() lastSort = millis(); std::sort(meshNodes->begin(), meshNodes->begin() + numMeshNodes, [](const meshtastic_NodeInfoLite &a, const meshtastic_NodeInfoLite &b) { + if (a.num == myNodeInfo.my_node_num && b.num == myNodeInfo.my_node_num) // in theory impossible + return false; if (a.num == myNodeInfo.my_node_num) { return true; } @@ -1706,9 +1708,7 @@ void NodeDB::sortMeshDB() bool bFav = b.is_favorite; if (aFav != bFav) return aFav; - if (a.last_heard != b.last_heard) - return a.last_heard > b.last_heard; - return a.num > b.num; + return a.last_heard > b.last_heard; }); } } From 26df4f81420936390bdbbbac9e593161d8e943dc Mon Sep 17 00:00:00 2001 From: Andrew Yong Date: Mon, 30 Jun 2025 19:05:24 +0800 Subject: [PATCH 09/11] fix(xiao_ble): Define xiao_ble I2C pins in parent variant (fixes #7163) (#7164) This restores the previously-defined I2C pins that got lost in the cleanup (#7024) Signed-off-by: Andrew Yong --- variants/seeed_xiao_nrf52840_kit/variant.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/variants/seeed_xiao_nrf52840_kit/variant.h b/variants/seeed_xiao_nrf52840_kit/variant.h index d2bbfdda9..a65500612 100644 --- a/variants/seeed_xiao_nrf52840_kit/variant.h +++ b/variants/seeed_xiao_nrf52840_kit/variant.h @@ -179,7 +179,11 @@ static const uint8_t SCK = PIN_SPI_SCK; #define I2C_NO_RESCAN // I2C is a bit finicky, don't scan too much #define WIRE_INTERFACES_COUNT 1 -#if !defined(XIAO_BLE_LEGACY_PINOUT) && !defined(GPS_L76K) +#if defined(XIAO_BLE_LEGACY_PINOUT) +// Used for I2C by DIY xiao_ble variant +#define PIN_WIRE_SDA D4 +#define PIN_WIRE_SCL D5 +#elif !defined(GPS_L76K) // If D6 and D7 are free, I2C is probably the most versatile assignment #define PIN_WIRE_SDA D6 #define PIN_WIRE_SCL D7 From be06a7d88121ce5a0f3741d3968525e15610e893 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 06:05:43 -0500 Subject: [PATCH 10/11] automated bumps (#7155) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- bin/org.meshtastic.meshtasticd.metainfo.xml | 3 +++ debian/changelog | 7 +++++-- version.properties | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/bin/org.meshtastic.meshtasticd.metainfo.xml b/bin/org.meshtastic.meshtasticd.metainfo.xml index 4b07f6388..ed57386a3 100644 --- a/bin/org.meshtastic.meshtasticd.metainfo.xml +++ b/bin/org.meshtastic.meshtasticd.metainfo.xml @@ -87,6 +87,9 @@ + + https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.1 + https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.0 diff --git a/debian/changelog b/debian/changelog index d607be68c..70a01bab4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -meshtasticd (2.7.0.0) UNRELEASED; urgency=medium +meshtasticd (2.7.1.0) UNRELEASED; urgency=medium [ Austin Lane ] * Initial packaging @@ -22,4 +22,7 @@ meshtasticd (2.7.0.0) UNRELEASED; urgency=medium [ ] * GitHub Actions Automatic version bump - -- Mon, 16 Jun 2025 02:10:49 +0000 + [ ] + * GitHub Actions Automatic version bump + + -- Fri, 27 Jun 2025 20:12:21 +0000 diff --git a/version.properties b/version.properties index 91c81a0c9..3fe1aa385 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 7 -build = 0 +build = 1 From 4bd416413a2ecad41f9ba3d95e6c68c8b8b2278a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 16:04:12 -0500 Subject: [PATCH 11/11] chore(deps): update meshtastic/device-ui digest to 4b7bf36 (#7178) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 693fdc9c3..0143038af 100644 --- a/platformio.ini +++ b/platformio.ini @@ -109,7 +109,7 @@ lib_deps = [device-ui_base] lib_deps = # renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master - https://github.com/meshtastic/device-ui/archive/cdc6e5bdeedb8293d10e4a02be6ca64e95a7c515.zip + https://github.com/meshtastic/device-ui/archive/4b7bf369adfa5a7bd419fa8293d21206576d52d0.zip ; Common libs for environmental measurements in telemetry module [environmental_base]