Merge branch 'master' into develop-to-master

This commit is contained in:
Ben Meadors
2025-11-19 16:07:58 -06:00
committed by GitHub
co-authored by GitHub
15 changed files with 200 additions and 109 deletions
+1 -1
View File
@@ -143,7 +143,7 @@ jobs:
merge-multiple: true merge-multiple: true
- name: Test Report - name: Test Report
uses: dorny/test-reporter@v2.1.1 uses: dorny/test-reporter@v2.2.0
with: with:
name: PlatformIO Tests name: PlatformIO Tests
path: testreport.xml path: testreport.xml
+6 -6
View File
@@ -8,15 +8,15 @@ plugins:
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- checkov@3.2.489 - checkov@3.2.492
- renovate@41.169.1 - renovate@42.5.4
- prettier@3.6.2 - prettier@3.6.2
- trufflehog@3.90.12 - trufflehog@3.90.13
- yamllint@1.37.1 - yamllint@1.37.1
- bandit@1.8.6 - bandit@1.8.6
- trivy@0.67.2 - trivy@0.67.2
- taplo@0.10.0 - taplo@0.10.0
- ruff@0.14.3 - ruff@0.14.4
- isort@7.0.0 - isort@7.0.0
- markdownlint@0.45.0 - markdownlint@0.45.0
- oxipng@9.1.5 - oxipng@9.1.5
@@ -26,9 +26,9 @@ lint:
- hadolint@2.14.0 - hadolint@2.14.0
- shfmt@3.6.0 - shfmt@3.6.0
- shellcheck@0.11.0 - shellcheck@0.11.0
- black@25.9.0 - black@25.11.0
- git-diff-check - git-diff-check
- gitleaks@8.28.0 - gitleaks@8.29.0
- clang-format@16.0.3 - clang-format@16.0.3
ignore: ignore:
- linters: [ALL] - linters: [ALL]
+1
View File
@@ -4,6 +4,7 @@ meshtasticd (2.7.16.0) unstable; urgency=medium
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Wed, 19 Nov 2025 16:12:32 +0000 -- GitHub Actions <github-actions[bot]@users.noreply.github.com> Wed, 19 Nov 2025 16:12:32 +0000
meshtasticd (2.7.15.0) unstable; urgency=medium meshtasticd (2.7.15.0) unstable; urgency=medium
* Version 2.7.15 * Version 2.7.15
+7
View File
@@ -50,6 +50,13 @@ BuildRequires: pkgconfig(x11)
BuildRequires: pkgconfig(libinput) BuildRequires: pkgconfig(libinput)
BuildRequires: pkgconfig(xkbcommon-x11) BuildRequires: pkgconfig(xkbcommon-x11)
# libbsd is needed on older Fedora/RHEL to provide 'strlcpy'
%if 0%{?fedora} >= 39 || 0%{?rhel} >= 10
BuildRequires: glibc-devel >= 2.38
%else
BuildRequires: pkgconfig(libbsd-overlay)
%endif
Requires: systemd-udev Requires: systemd-udev
%description %description
+2 -2
View File
@@ -62,7 +62,7 @@ monitor_speed = 115200
monitor_filters = direct monitor_filters = direct
lib_deps = lib_deps =
# renovate: datasource=git-refs depName=meshtastic-esp8266-oled-ssd1306 packageName=https://github.com/meshtastic/esp8266-oled-ssd1306 gitBranch=master # renovate: datasource=git-refs depName=meshtastic-esp8266-oled-ssd1306 packageName=https://github.com/meshtastic/esp8266-oled-ssd1306 gitBranch=master
https://github.com/meshtastic/esp8266-oled-ssd1306/archive/0cbc26b1f8f61957af0475f486b362eafe7cc4e2.zip https://github.com/meshtastic/esp8266-oled-ssd1306/archive/2887bf4a19f64d92c984dcc8fd5ca7429e425e4a.zip
# renovate: datasource=git-refs depName=meshtastic-OneButton packageName=https://github.com/meshtastic/OneButton gitBranch=master # renovate: datasource=git-refs depName=meshtastic-OneButton packageName=https://github.com/meshtastic/OneButton gitBranch=master
https://github.com/meshtastic/OneButton/archive/fa352d668c53f290cfa480a5f79ad422cd828c70.zip https://github.com/meshtastic/OneButton/archive/fa352d668c53f290cfa480a5f79ad422cd828c70.zip
# renovate: datasource=git-refs depName=meshtastic-arduino-fsm packageName=https://github.com/meshtastic/arduino-fsm gitBranch=master # renovate: datasource=git-refs depName=meshtastic-arduino-fsm packageName=https://github.com/meshtastic/arduino-fsm gitBranch=master
@@ -121,7 +121,7 @@ lib_deps =
[device-ui_base] [device-ui_base]
lib_deps = lib_deps =
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master # renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
https://github.com/meshtastic/device-ui/archive/19b7855e9a1d9deff37391659ca7194e4ef57c43.zip https://github.com/meshtastic/device-ui/archive/28167c67dfd13015a0b5eef1828f95fe8e3ab7c3.zip
; Common libs for environmental measurements in telemetry module ; Common libs for environmental measurements in telemetry module
[environmental_base] [environmental_base]
+3 -1
View File
@@ -935,7 +935,9 @@ void menuHandler::BluetoothToggleMenu()
bannerOptions.optionsArrayPtr = optionsArray; bannerOptions.optionsArrayPtr = optionsArray;
bannerOptions.optionsCount = 3; bannerOptions.optionsCount = 3;
bannerOptions.bannerCallback = [](int selected) -> void { bannerOptions.bannerCallback = [](int selected) -> void {
if (selected == 1 || selected == 2) { if (selected == 0)
return;
else if (selected != (config.bluetooth.enabled ? 1 : 2)) {
InputEvent event = {.inputEvent = (input_broker_event)170, .kbchar = 170, .touchX = 0, .touchY = 0}; InputEvent event = {.inputEvent = (input_broker_event)170, .kbchar = 170, .touchX = 0, .touchY = 0};
inputBroker->injectInputEvent(&event); inputBroker->injectInputEvent(&event);
} }
+1 -1
View File
@@ -52,7 +52,7 @@ int InputBroker::handleInputEvent(const InputEvent *event)
powerFSM.trigger(EVENT_INPUT); // todo: not every input should wake, like long hold release powerFSM.trigger(EVENT_INPUT); // todo: not every input should wake, like long hold release
if (event && event->inputEvent != INPUT_BROKER_NONE && externalNotificationModule && if (event && event->inputEvent != INPUT_BROKER_NONE && externalNotificationModule &&
moduleConfig.external_notification.enabled) { moduleConfig.external_notification.enabled && externalNotificationModule->nagging()) {
externalNotificationModule->stopNow(); externalNotificationModule->stopNow();
} }
-2
View File
@@ -85,10 +85,8 @@ int SystemCommandsModule::handleInputEvent(const InputEvent *event)
switch (event->inputEvent) { switch (event->inputEvent) {
// GPS // GPS
case INPUT_BROKER_GPS_TOGGLE: case INPUT_BROKER_GPS_TOGGLE:
LOG_WARN("GPS Toggle");
#if !MESHTASTIC_EXCLUDE_GPS #if !MESHTASTIC_EXCLUDE_GPS
if (gps) { if (gps) {
LOG_WARN("GPS Toggle2");
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED && if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED &&
config.position.fixed_position == false) { config.position.fixed_position == false) {
nodeDB->clearLocalPosition(); nodeDB->clearLocalPosition();
+132 -82
View File
@@ -11,6 +11,113 @@ extern graphics::Screen *screen;
TraceRouteModule *traceRouteModule; TraceRouteModule *traceRouteModule;
void TraceRouteModule::setResultText(const String &text)
{
resultText = text;
resultLines.clear();
resultLinesDirty = true;
}
void TraceRouteModule::clearResultLines()
{
resultLines.clear();
resultLinesDirty = false;
}
#if HAS_SCREEN
void TraceRouteModule::rebuildResultLines(OLEDDisplay *display)
{
if (!display) {
resultLinesDirty = false;
return;
}
resultLines.clear();
if (resultText.length() == 0) {
resultLinesDirty = false;
return;
}
int maxWidth = display->getWidth() - 4;
if (maxWidth <= 0) {
resultLinesDirty = false;
return;
}
int start = 0;
int textLength = resultText.length();
while (start <= textLength) {
int newlinePos = resultText.indexOf('\n', start);
String segment;
if (newlinePos != -1) {
segment = resultText.substring(start, newlinePos);
start = newlinePos + 1;
} else {
segment = resultText.substring(start);
start = textLength + 1;
}
if (segment.length() == 0) {
resultLines.push_back("");
continue;
}
if (display->getStringWidth(segment) <= maxWidth) {
resultLines.push_back(segment);
continue;
}
String remaining = segment;
while (remaining.length() > 0) {
String tempLine = "";
int lastGoodBreak = -1;
bool lineComplete = false;
for (int i = 0; i < static_cast<int>(remaining.length()); i++) {
char ch = remaining.charAt(i);
String testLine = tempLine + ch;
if (display->getStringWidth(testLine) > maxWidth) {
if (lastGoodBreak >= 0) {
resultLines.push_back(remaining.substring(0, lastGoodBreak + 1));
remaining = remaining.substring(lastGoodBreak + 1);
lineComplete = true;
break;
} else if (tempLine.length() > 0) {
resultLines.push_back(tempLine);
remaining = remaining.substring(i);
lineComplete = true;
break;
} else {
resultLines.push_back(String(ch));
remaining = remaining.substring(i + 1);
lineComplete = true;
break;
}
} else {
tempLine = testLine;
if (ch == ' ' || ch == '>' || ch == '<' || ch == '-' || ch == '(' || ch == ')' || ch == ',') {
lastGoodBreak = i;
}
}
}
if (!lineComplete) {
if (tempLine.length() > 0) {
resultLines.push_back(tempLine);
}
break;
}
}
}
resultLinesDirty = false;
}
#endif
bool TraceRouteModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_RouteDiscovery *r) bool TraceRouteModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_RouteDiscovery *r)
{ {
// We only alter the packet in alterReceivedProtobuf() // We only alter the packet in alterReceivedProtobuf()
@@ -406,7 +513,7 @@ bool TraceRouteModule::startTraceRoute(NodeNum node)
if (node == 0 || node == NODENUM_BROADCAST) { if (node == 0 || node == NODENUM_BROADCAST) {
LOG_ERROR("Invalid node number for trace route: 0x%08x", node); LOG_ERROR("Invalid node number for trace route: 0x%08x", node);
runState = TRACEROUTE_STATE_RESULT; runState = TRACEROUTE_STATE_RESULT;
resultText = "Invalid node"; setResultText("Invalid node");
resultShowTime = millis(); resultShowTime = millis();
tracingNode = 0; tracingNode = 0;
@@ -420,7 +527,7 @@ bool TraceRouteModule::startTraceRoute(NodeNum node)
if (node == nodeDB->getNodeNum()) { if (node == nodeDB->getNodeNum()) {
LOG_ERROR("Cannot trace route to self: 0x%08x", node); LOG_ERROR("Cannot trace route to self: 0x%08x", node);
runState = TRACEROUTE_STATE_RESULT; runState = TRACEROUTE_STATE_RESULT;
resultText = "Cannot trace self"; setResultText("Cannot trace self");
resultShowTime = millis(); resultShowTime = millis();
tracingNode = 0; tracingNode = 0;
@@ -447,6 +554,8 @@ bool TraceRouteModule::startTraceRoute(NodeNum node)
unsigned long wait = (cooldownMs - (now - lastTraceRouteTime)) / 1000; unsigned long wait = (cooldownMs - (now - lastTraceRouteTime)) / 1000;
bannerText = String("Wait for ") + String(wait) + String("s"); bannerText = String("Wait for ") + String(wait) + String("s");
runState = TRACEROUTE_STATE_COOLDOWN; runState = TRACEROUTE_STATE_COOLDOWN;
resultText = "";
clearResultLines();
requestFocus(); requestFocus();
UIFrameEvent e; UIFrameEvent e;
@@ -459,6 +568,8 @@ bool TraceRouteModule::startTraceRoute(NodeNum node)
tracingNode = node; tracingNode = node;
lastTraceRouteTime = now; lastTraceRouteTime = now;
runState = TRACEROUTE_STATE_TRACKING; runState = TRACEROUTE_STATE_TRACKING;
resultText = "";
clearResultLines();
bannerText = String("Tracing ") + getNodeName(node); bannerText = String("Tracing ") + getNodeName(node);
LOG_INFO("TraceRoute UI: Starting trace route to node 0x%08x, requesting focus", node); LOG_INFO("TraceRoute UI: Starting trace route to node 0x%08x, requesting focus", node);
@@ -501,7 +612,7 @@ bool TraceRouteModule::startTraceRoute(NodeNum node)
} else { } else {
LOG_ERROR("MeshService is NULL!"); LOG_ERROR("MeshService is NULL!");
runState = TRACEROUTE_STATE_RESULT; runState = TRACEROUTE_STATE_RESULT;
resultText = "Service unavailable"; setResultText("Service unavailable");
resultShowTime = millis(); resultShowTime = millis();
tracingNode = 0; tracingNode = 0;
@@ -514,7 +625,7 @@ bool TraceRouteModule::startTraceRoute(NodeNum node)
} else { } else {
LOG_ERROR("Failed to allocate TraceRoute packet from router"); LOG_ERROR("Failed to allocate TraceRoute packet from router");
runState = TRACEROUTE_STATE_RESULT; runState = TRACEROUTE_STATE_RESULT;
resultText = "Failed to send"; setResultText("Failed to send");
resultShowTime = millis(); resultShowTime = millis();
tracingNode = 0; tracingNode = 0;
@@ -532,7 +643,7 @@ void TraceRouteModule::launch(NodeNum node)
if (node == 0 || node == NODENUM_BROADCAST) { if (node == 0 || node == NODENUM_BROADCAST) {
LOG_ERROR("Invalid node number for trace route: 0x%08x", node); LOG_ERROR("Invalid node number for trace route: 0x%08x", node);
runState = TRACEROUTE_STATE_RESULT; runState = TRACEROUTE_STATE_RESULT;
resultText = "Invalid node"; setResultText("Invalid node");
resultShowTime = millis(); resultShowTime = millis();
tracingNode = 0; tracingNode = 0;
@@ -546,7 +657,7 @@ void TraceRouteModule::launch(NodeNum node)
if (node == nodeDB->getNodeNum()) { if (node == nodeDB->getNodeNum()) {
LOG_ERROR("Cannot trace route to self: 0x%08x", node); LOG_ERROR("Cannot trace route to self: 0x%08x", node);
runState = TRACEROUTE_STATE_RESULT; runState = TRACEROUTE_STATE_RESULT;
resultText = "Cannot trace self"; setResultText("Cannot trace self");
resultShowTime = millis(); resultShowTime = millis();
tracingNode = 0; tracingNode = 0;
@@ -568,6 +679,8 @@ void TraceRouteModule::launch(NodeNum node)
unsigned long wait = (cooldownMs - (now - lastTraceRouteTime)) / 1000; unsigned long wait = (cooldownMs - (now - lastTraceRouteTime)) / 1000;
bannerText = String("Wait for ") + String(wait) + String("s"); bannerText = String("Wait for ") + String(wait) + String("s");
runState = TRACEROUTE_STATE_COOLDOWN; runState = TRACEROUTE_STATE_COOLDOWN;
resultText = "";
clearResultLines();
requestFocus(); requestFocus();
UIFrameEvent e; UIFrameEvent e;
@@ -580,6 +693,8 @@ void TraceRouteModule::launch(NodeNum node)
runState = TRACEROUTE_STATE_TRACKING; runState = TRACEROUTE_STATE_TRACKING;
tracingNode = node; tracingNode = node;
lastTraceRouteTime = now; lastTraceRouteTime = now;
resultText = "";
clearResultLines();
bannerText = String("Tracing ") + getNodeName(node); bannerText = String("Tracing ") + getNodeName(node);
requestFocus(); requestFocus();
@@ -614,14 +729,14 @@ void TraceRouteModule::launch(NodeNum node)
} else { } else {
LOG_ERROR("MeshService is NULL!"); LOG_ERROR("MeshService is NULL!");
runState = TRACEROUTE_STATE_RESULT; runState = TRACEROUTE_STATE_RESULT;
resultText = "Service unavailable"; setResultText("Service unavailable");
resultShowTime = millis(); resultShowTime = millis();
tracingNode = 0; tracingNode = 0;
} }
} else { } else {
LOG_ERROR("Failed to allocate TraceRoute packet from router"); LOG_ERROR("Failed to allocate TraceRoute packet from router");
runState = TRACEROUTE_STATE_RESULT; runState = TRACEROUTE_STATE_RESULT;
resultText = "Failed to send"; setResultText("Failed to send");
resultShowTime = millis(); resultShowTime = millis();
tracingNode = 0; tracingNode = 0;
} }
@@ -629,7 +744,7 @@ void TraceRouteModule::launch(NodeNum node)
void TraceRouteModule::handleTraceRouteResult(const String &result) void TraceRouteModule::handleTraceRouteResult(const String &result)
{ {
resultText = result; setResultText(result);
runState = TRACEROUTE_STATE_RESULT; runState = TRACEROUTE_STATE_RESULT;
resultShowTime = millis(); resultShowTime = millis();
tracingNode = 0; tracingNode = 0;
@@ -679,83 +794,15 @@ void TraceRouteModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
if (resultText.length() > 0) { if (resultText.length() > 0) {
std::vector<String> lines; if (resultLinesDirty) {
String currentLine = ""; rebuildResultLines(display);
int maxWidth = display->getWidth() - 4;
int start = 0;
int newlinePos = resultText.indexOf('\n', start);
while (newlinePos != -1 || start < static_cast<int>(resultText.length())) {
String segment;
if (newlinePos != -1) {
segment = resultText.substring(start, newlinePos);
start = newlinePos + 1;
newlinePos = resultText.indexOf('\n', start);
} else {
segment = resultText.substring(start);
start = resultText.length();
}
if (display->getStringWidth(segment) <= maxWidth) {
lines.push_back(segment);
} else {
// Try to break at better positions (space, >, <, -)
String remaining = segment;
while (remaining.length() > 0) {
String tempLine = "";
int lastGoodBreak = -1;
bool lineComplete = false;
for (int i = 0; i < static_cast<int>(remaining.length()); i++) {
char ch = remaining.charAt(i);
String testLine = tempLine + ch;
if (display->getStringWidth(testLine) > maxWidth) {
if (lastGoodBreak >= 0) {
// Break at the last good position
lines.push_back(remaining.substring(0, lastGoodBreak + 1));
remaining = remaining.substring(lastGoodBreak + 1);
lineComplete = true;
break;
} else if (tempLine.length() > 0) {
lines.push_back(tempLine);
remaining = remaining.substring(i);
lineComplete = true;
break;
} else {
// Single character exceeds width
lines.push_back(String(ch));
remaining = remaining.substring(i + 1);
lineComplete = true;
break;
}
} else {
tempLine = testLine;
// Mark good break positions
if (ch == ' ' || ch == '>' || ch == '<' || ch == '-' || ch == '(' || ch == ')') {
lastGoodBreak = i;
}
}
}
if (!lineComplete) {
// Reached end of remaining text
if (tempLine.length() > 0) {
lines.push_back(tempLine);
}
break;
}
}
}
} }
int lineHeight = FONT_HEIGHT_SMALL + 1; // Use proper font height with 1px spacing int lineHeight = FONT_HEIGHT_SMALL + 1; // Use proper font height with 1px spacing
for (size_t i = 0; i < lines.size(); i++) { for (size_t i = 0; i < resultLines.size(); i++) {
int lineY = contentStartY + (i * lineHeight); int lineY = contentStartY + (i * lineHeight);
if (lineY + FONT_HEIGHT_SMALL <= display->getHeight()) { if (lineY + FONT_HEIGHT_SMALL <= display->getHeight()) {
display->drawString(x + 2, lineY, lines[i]); display->drawString(x + 2, lineY, resultLines[i]);
} }
} }
} }
@@ -779,7 +826,7 @@ int32_t TraceRouteModule::runOnce()
if (runState == TRACEROUTE_STATE_TRACKING && now - lastTraceRouteTime > trackingTimeoutMs) { if (runState == TRACEROUTE_STATE_TRACKING && now - lastTraceRouteTime > trackingTimeoutMs) {
LOG_INFO("TraceRoute timeout, no response received"); LOG_INFO("TraceRoute timeout, no response received");
runState = TRACEROUTE_STATE_RESULT; runState = TRACEROUTE_STATE_RESULT;
resultText = "No response received"; setResultText("No response received");
resultShowTime = now; resultShowTime = now;
tracingNode = 0; tracingNode = 0;
@@ -815,6 +862,8 @@ int32_t TraceRouteModule::runOnce()
// Cooldown finished // Cooldown finished
LOG_INFO("TraceRoute cooldown finished, returning to IDLE"); LOG_INFO("TraceRoute cooldown finished, returning to IDLE");
runState = TRACEROUTE_STATE_IDLE; runState = TRACEROUTE_STATE_IDLE;
resultText = "";
clearResultLines();
bannerText = ""; bannerText = "";
UIFrameEvent e; UIFrameEvent e;
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; e.action = UIFrameEvent::Action::REGENERATE_FRAMESET;
@@ -828,6 +877,7 @@ int32_t TraceRouteModule::runOnce()
LOG_INFO("TraceRoute result display timeout, returning to IDLE"); LOG_INFO("TraceRoute result display timeout, returning to IDLE");
runState = TRACEROUTE_STATE_IDLE; runState = TRACEROUTE_STATE_IDLE;
resultText = ""; resultText = "";
clearResultLines();
bannerText = ""; bannerText = "";
tracingNode = 0; tracingNode = 0;
UIFrameEvent e; UIFrameEvent e;
+8
View File
@@ -7,6 +7,7 @@
#if HAS_SCREEN #if HAS_SCREEN
#include "OLEDDisplayUi.h" #include "OLEDDisplayUi.h"
#endif #endif
#include <vector>
#define ROUTE_SIZE sizeof(((meshtastic_RouteDiscovery *)0)->route) / sizeof(((meshtastic_RouteDiscovery *)0)->route[0]) #define ROUTE_SIZE sizeof(((meshtastic_RouteDiscovery *)0)->route) / sizeof(((meshtastic_RouteDiscovery *)0)->route[0])
@@ -49,6 +50,11 @@ class TraceRouteModule : public ProtobufModule<meshtastic_RouteDiscovery>,
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
private: private:
void setResultText(const String &text);
void clearResultLines();
#if HAS_SCREEN
void rebuildResultLines(OLEDDisplay *display);
#endif
// Call to add unknown hops (e.g. when a node couldn't decrypt it) to the route based on hopStart and current hopLimit // Call to add unknown hops (e.g. when a node couldn't decrypt it) to the route based on hopStart and current hopLimit
void insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_RouteDiscovery *r, bool isTowardsDestination); void insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_RouteDiscovery *r, bool isTowardsDestination);
@@ -74,6 +80,8 @@ class TraceRouteModule : public ProtobufModule<meshtastic_RouteDiscovery>,
unsigned long trackingTimeoutMs = 10000; unsigned long trackingTimeoutMs = 10000;
String bannerText; String bannerText;
String resultText; String resultText;
std::vector<String> resultLines;
bool resultLinesDirty = false;
NodeNum tracingNode = 0; NodeNum tracingNode = 0;
bool initialized = false; bool initialized = false;
}; };
+2 -1
View File
@@ -116,6 +116,7 @@ void BMX160Sensor::calibrate(uint16_t forSeconds)
{ {
#if !defined(MESHTASTIC_EXCLUDE_SCREEN) #if !defined(MESHTASTIC_EXCLUDE_SCREEN)
LOG_DEBUG("BMX160 calibration started for %is", forSeconds); LOG_DEBUG("BMX160 calibration started for %is", forSeconds);
highestX = 0, lowestX = 0, highestY = 0, lowestY = 0, highestZ = 0, lowestZ = 0;
doCalibration = true; doCalibration = true;
uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided
@@ -127,4 +128,4 @@ void BMX160Sensor::calibrate(uint16_t forSeconds)
#endif #endif
#endif #endif
+2 -1
View File
@@ -157,6 +157,7 @@ void ICM20948Sensor::calibrate(uint16_t forSeconds)
{ {
#if !defined(MESHTASTIC_EXCLUDE_SCREEN) && HAS_SCREEN #if !defined(MESHTASTIC_EXCLUDE_SCREEN) && HAS_SCREEN
LOG_DEBUG("BMX160 calibration started for %is", forSeconds); LOG_DEBUG("BMX160 calibration started for %is", forSeconds);
highestX = 0, lowestX = 0, highestY = 0, lowestY = 0, highestZ = 0, lowestZ = 0;
doCalibration = true; doCalibration = true;
uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided
@@ -295,4 +296,4 @@ bool ICM20948Singleton::setWakeOnMotion()
return true; return true;
} }
#endif #endif
+4 -1
View File
@@ -692,7 +692,10 @@ void MQTT::publishNodeInfo()
} }
void MQTT::publishQueuedMessages() void MQTT::publishQueuedMessages()
{ {
if (mqttQueue.isEmpty() || !isConnected) if (mqttQueue.isEmpty())
return;
if (!moduleConfig.mqtt.proxy_to_client_enabled && !isConnected)
return; return;
LOG_DEBUG("Publish enqueued MQTT message"); LOG_DEBUG("Publish enqueued MQTT message");
+30 -10
View File
@@ -20,13 +20,14 @@
#include "PowerStatus.h" #include "PowerStatus.h"
#endif #endif
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6)
#if defined(CONFIG_NIMBLE_CPP_IDF) #if defined(CONFIG_NIMBLE_CPP_IDF)
#include "host/ble_gap.h" #include "host/ble_gap.h"
#else #else
#include "nimble/nimble/host/include/host/ble_gap.h" #include "nimble/nimble/host/include/host/ble_gap.h"
#endif #endif
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6)
namespace namespace
{ {
constexpr uint16_t kPreferredBleMtu = 517; constexpr uint16_t kPreferredBleMtu = 517;
@@ -776,16 +777,35 @@ bool NimbleBluetooth::isConnected()
int NimbleBluetooth::getRssi() int NimbleBluetooth::getRssi()
{ {
if (bleServer && isConnected()) { #if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6)
auto service = bleServer->getServiceByUUID(MESH_SERVICE_UUID); if (!bleServer || !isConnected()) {
uint16_t handle = service->getHandle(); return 0; // No active BLE connection
#ifdef NIMBLE_TWO
return NimBLEDevice::getClientByHandle(handle)->getRssi();
#else
return NimBLEDevice::getClientByID(handle)->getRssi();
#endif
} }
return 0; // FIXME figure out where to source this
uint16_t connHandle = nimbleBluetoothConnHandle.load();
if (connHandle == BLE_HS_CONN_HANDLE_NONE) {
const auto peers = bleServer->getPeerDevices();
if (!peers.empty()) {
connHandle = peers.front();
nimbleBluetoothConnHandle = connHandle;
}
}
if (connHandle == BLE_HS_CONN_HANDLE_NONE) {
return 0; // Connection handle not available yet
}
int8_t rssi = 0;
const int rc = ble_gap_conn_rssi(connHandle, &rssi);
if (rc == 0) {
return rssi;
}
LOG_DEBUG("BLE RSSI read failed, rc=%d", rc);
#endif
return 0;
} }
void NimbleBluetooth::setup() void NimbleBluetooth::setup()
+1 -1
View File
@@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 2 major = 2
minor = 7 minor = 7
build = 16 build = 16