From c0c2cf526e093b6ca3306a4fe503b6da6e38b797 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Fri, 12 Jun 2026 12:39:46 -0700 Subject: [PATCH 01/14] Add find node buzzer admin command --- protobufs | 2 +- src/buzz/FindNodeBuzzer.cpp | 79 ++++++++++++++++++++++ src/buzz/FindNodeBuzzer.h | 27 ++++++++ src/buzz/buzz.cpp | 61 ++++++++++++++++- src/buzz/buzz.h | 4 +- src/main.cpp | 1 + src/mesh/generated/meshtastic/admin.pb.cpp | 19 ++---- src/mesh/generated/meshtastic/admin.pb.h | 66 ++++++++++++++++++ src/mesh/generated/meshtastic/mesh.pb.h | 12 ++-- src/modules/AdminModule.cpp | 43 ++++++++++++ src/modules/AdminModule.h | 3 +- src/modules/Modules.cpp | 2 + 12 files changed, 298 insertions(+), 21 deletions(-) create mode 100644 src/buzz/FindNodeBuzzer.cpp create mode 100644 src/buzz/FindNodeBuzzer.h diff --git a/protobufs b/protobufs index 485ede7422e..bde2f5e9ba7 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 485ede7422e6db2c819e42913167ab15d9f557b7 +Subproject commit bde2f5e9ba7f5a6392dfacae8d98a6dac2c5cd6a diff --git a/src/buzz/FindNodeBuzzer.cpp b/src/buzz/FindNodeBuzzer.cpp new file mode 100644 index 00000000000..8560e377c1c --- /dev/null +++ b/src/buzz/FindNodeBuzzer.cpp @@ -0,0 +1,79 @@ +#include "FindNodeBuzzer.h" +#include "NodeDB.h" +#include "buzz.h" +#include "configuration.h" +#include "mesh/Throttle.h" +#include +#include + +namespace +{ +constexpr uint32_t FIND_NODE_REPEAT_INTERVAL_MS = 2000; +} + +FindNodeBuzzer *findNodeBuzzer; + +FindNodeBuzzer::FindNodeBuzzer() : concurrency::OSThread("FindNodeBuzzer", INT32_MAX) {} + +FindNodeBuzzer::Result FindNodeBuzzer::start(uint32_t durationSeconds, uint32_t *acceptedDurationSeconds) +{ + if (acceptedDurationSeconds) { + *acceptedDurationSeconds = 0; + } + + if (!hasFindNodeBuzzer()) { + return Result::NoBuzzer; + } + + if (config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_DISABLED) { + return Result::BuzzerDisabled; + } + + if (durationSeconds == 0) { + durationSeconds = DEFAULT_DURATION_SECONDS; + } else if (durationSeconds > MAX_DURATION_SECONDS) { + durationSeconds = MAX_DURATION_SECONDS; + } + + startMsec = millis(); + durationMsec = durationSeconds * 1000U; + if (acceptedDurationSeconds) { + *acceptedDurationSeconds = durationSeconds; + } + + setIntervalFromNow(0); + return Result::Started; +} + +FindNodeBuzzer::Result FindNodeBuzzer::stop() +{ + startMsec = 0; + durationMsec = 0; + setIntervalFromNow(INT32_MAX); + return Result::Stopped; +} + +bool FindNodeBuzzer::isActive() const +{ + return durationMsec != 0 && Throttle::isWithinTimespanMs(startMsec, durationMsec); +} + +int32_t FindNodeBuzzer::runOnce() +{ + if (!isActive()) { + stop(); + return INT32_MAX; + } + + if (config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_DISABLED || !playFindNodeBuzzer()) { + stop(); + return INT32_MAX; + } + + if (!isActive()) { + stop(); + return INT32_MAX; + } + + return FIND_NODE_REPEAT_INTERVAL_MS; +} diff --git a/src/buzz/FindNodeBuzzer.h b/src/buzz/FindNodeBuzzer.h new file mode 100644 index 00000000000..16fc80e6fb7 --- /dev/null +++ b/src/buzz/FindNodeBuzzer.h @@ -0,0 +1,27 @@ +#pragma once + +#include "concurrency/OSThread.h" +#include + +class FindNodeBuzzer : private concurrency::OSThread +{ + public: + enum class Result : uint8_t { Started, Stopped, NoBuzzer, BuzzerDisabled }; + + static constexpr uint32_t DEFAULT_DURATION_SECONDS = 30; + static constexpr uint32_t MAX_DURATION_SECONDS = 300; + + FindNodeBuzzer(); + + Result start(uint32_t durationSeconds, uint32_t *acceptedDurationSeconds = nullptr); + Result stop(); + bool isActive() const; + + private: + uint32_t startMsec = 0; + uint32_t durationMsec = 0; + + int32_t runOnce() override; +}; + +extern FindNodeBuzzer *findNodeBuzzer; diff --git a/src/buzz/buzz.cpp b/src/buzz/buzz.cpp index 6692d996dfa..0ac5259da9d 100644 --- a/src/buzz/buzz.cpp +++ b/src/buzz/buzz.cpp @@ -126,6 +126,65 @@ void playTones(const ToneDuration *tone_durations, int size) } } +bool hasFindNodeBuzzer() +{ +#ifdef HAS_I2S + if (moduleConfig.external_notification.use_i2s_as_buzzer && audioThread) { + return true; + } +#endif +#if defined(PIN_BUZZER) + return true; +#endif + return config.device.buzzer_gpio || + (moduleConfig.external_notification.output_buzzer && !moduleConfig.external_notification.use_pwm); +} + +bool playFindNodeBuzzer() +{ + if (config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_DISABLED) { + return false; + } + +#ifdef HAS_I2S + if (moduleConfig.external_notification.use_i2s_as_buzzer && audioThread) { + static constexpr const char *findNodeRtttl = "find:d=16,o=5,b=220:c6,p,c6,p,g6"; + if (!audioThread->isPlaying()) { + audioThread->beginRttl(findNodeRtttl, strlen(findNodeRtttl)); + } + return true; + } +#endif + +#if defined(PIN_BUZZER) + if (!config.device.buzzer_gpio) { + config.device.buzzer_gpio = PIN_BUZZER; + } +#endif + if (config.device.buzzer_gpio) { + const ToneDuration melody[] = {{NOTE_C5, DURATION_1_8}, {NOTE_C5, DURATION_1_8}, {NOTE_G5, DURATION_1_8}}; + for (const auto &tone_duration : melody) { + tone(config.device.buzzer_gpio, tone_duration.frequency_khz, tone_duration.duration_ms); + delay(1.3 * tone_duration.duration_ms); + } + return true; + } + + if (moduleConfig.external_notification.output_buzzer && !moduleConfig.external_notification.use_pwm) { + const uint32_t buzzerPin = moduleConfig.external_notification.output_buzzer; + pinMode(buzzerPin, OUTPUT); + for (int i = 0; i < 3; i++) { + digitalWrite(buzzerPin, HIGH); + delay(DURATION_1_8); + digitalWrite(buzzerPin, LOW); + delay(DURATION_1_8); + } + return true; + } + + return false; +} + void playBeep() { ToneDuration melody[] = {{NOTE_B3, DURATION_1_16}}; @@ -265,4 +324,4 @@ void play4ClickUp() // Quick high-pitched notes with trills ToneDuration melody[] = {{NOTE_F5, 50}, {NOTE_G6, 45}, {NOTE_E7, 60}}; playTones(melody, sizeof(melody) / sizeof(ToneDuration)); -} \ No newline at end of file +} diff --git a/src/buzz/buzz.h b/src/buzz/buzz.h index 1b97e24deff..4b0a2021295 100644 --- a/src/buzz/buzz.h +++ b/src/buzz/buzz.h @@ -14,4 +14,6 @@ void playChirp(); void playClick(); void playLongPressLeadUp(); bool playNextLeadUpNote(); // Play the next note in the lead-up sequence -void resetLeadUpSequence(); // Reset the lead-up sequence to start from beginning \ No newline at end of file +void resetLeadUpSequence(); // Reset the lead-up sequence to start from beginning +bool hasFindNodeBuzzer(); +bool playFindNodeBuzzer(); diff --git a/src/main.cpp b/src/main.cpp index d1703c82df8..78249add7af 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1158,6 +1158,7 @@ extern meshtastic_DeviceMetadata getDeviceMetadata() deviceMetadata.position_flags = config.position.position_flags; deviceMetadata.hw_model = HW_VENDOR; deviceMetadata.hasRemoteHardware = moduleConfig.remote_hardware.enabled; + deviceMetadata.hasBuzzer = hasFindNodeBuzzer(); deviceMetadata.excluded_modules = meshtastic_ExcludedModules_EXCLUDED_NONE; #if MESHTASTIC_EXCLUDE_REMOTEHARDWARE deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_REMOTEHARDWARE_CONFIG; diff --git a/src/mesh/generated/meshtastic/admin.pb.cpp b/src/mesh/generated/meshtastic/admin.pb.cpp index 945840c0f4d..59365dd8fdb 100644 --- a/src/mesh/generated/meshtastic/admin.pb.cpp +++ b/src/mesh/generated/meshtastic/admin.pb.cpp @@ -15,6 +15,12 @@ PB_BIND(meshtastic_AdminMessage_InputEvent, meshtastic_AdminMessage_InputEvent, PB_BIND(meshtastic_AdminMessage_OTAEvent, meshtastic_AdminMessage_OTAEvent, AUTO) +PB_BIND(meshtastic_AdminMessage_FindNodeRequest, meshtastic_AdminMessage_FindNodeRequest, AUTO) + + +PB_BIND(meshtastic_AdminMessage_FindNodeResponse, meshtastic_AdminMessage_FindNodeResponse, AUTO) + + PB_BIND(meshtastic_LockdownAuth, meshtastic_LockdownAuth, AUTO) @@ -43,16 +49,3 @@ PB_BIND(meshtastic_SCD30_config, meshtastic_SCD30_config, AUTO) PB_BIND(meshtastic_SHTXX_config, meshtastic_SHTXX_config, AUTO) - - - - - - - - - - - - - diff --git a/src/mesh/generated/meshtastic/admin.pb.h b/src/mesh/generated/meshtastic/admin.pb.h index 223705b282c..10dcd1c42e7 100644 --- a/src/mesh/generated/meshtastic/admin.pb.h +++ b/src/mesh/generated/meshtastic/admin.pb.h @@ -93,6 +93,13 @@ typedef enum _meshtastic_AdminMessage_BackupLocation { meshtastic_AdminMessage_BackupLocation_SD = 1 } meshtastic_AdminMessage_BackupLocation; +typedef enum _meshtastic_AdminMessage_FindNodeResponse_Result { + meshtastic_AdminMessage_FindNodeResponse_Result_STARTED = 0, + meshtastic_AdminMessage_FindNodeResponse_Result_STOPPED = 1, + meshtastic_AdminMessage_FindNodeResponse_Result_NO_BUZZER = 2, + meshtastic_AdminMessage_FindNodeResponse_Result_BUZZER_DISABLED = 3 +} meshtastic_AdminMessage_FindNodeResponse_Result; + /* Three stages of this request. */ typedef enum _meshtastic_KeyVerificationAdmin_MessageType { /* This is the first stage, where a client initiates */ @@ -130,6 +137,22 @@ typedef struct _meshtastic_AdminMessage_OTAEvent { meshtastic_AdminMessage_OTAEvent_ota_hash_t ota_hash; } meshtastic_AdminMessage_OTAEvent; +/* Request that the node emit an audible find-node pattern. */ +typedef struct _meshtastic_AdminMessage_FindNodeRequest { + /* Duration to repeat the find-node pattern. Zero uses the firmware default. */ + uint16_t duration_seconds; + /* Stop any active find-node pattern instead of starting a new one. */ + bool stop; +} meshtastic_AdminMessage_FindNodeRequest; + +/* Response to a find-node request. */ +typedef struct _meshtastic_AdminMessage_FindNodeResponse { + /* Result of the request. */ + meshtastic_AdminMessage_FindNodeResponse_Result result; + /* Accepted duration in seconds. Zero for stop or failed requests. */ + uint16_t duration_seconds; +} meshtastic_AdminMessage_FindNodeResponse; + typedef PB_BYTES_ARRAY_T(32) meshtastic_LockdownAuth_passphrase_t; /* Lockdown passphrase delivery payload. @@ -454,6 +477,10 @@ typedef struct _meshtastic_AdminMessage { meshtastic_SharedContact add_contact; /* Initiate or respond to a key verification request */ meshtastic_KeyVerificationAdmin key_verification; + /* Start or stop the audible find-node pattern. */ + meshtastic_AdminMessage_FindNodeRequest find_node_request; + /* Result of a find-node request. */ + meshtastic_AdminMessage_FindNodeResponse find_node_response; /* Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared. */ int32_t factory_reset_device; /* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot) @@ -514,6 +541,10 @@ extern "C" { #define _meshtastic_AdminMessage_BackupLocation_MAX meshtastic_AdminMessage_BackupLocation_SD #define _meshtastic_AdminMessage_BackupLocation_ARRAYSIZE ((meshtastic_AdminMessage_BackupLocation)(meshtastic_AdminMessage_BackupLocation_SD+1)) +#define _meshtastic_AdminMessage_FindNodeResponse_Result_MIN meshtastic_AdminMessage_FindNodeResponse_Result_STARTED +#define _meshtastic_AdminMessage_FindNodeResponse_Result_MAX meshtastic_AdminMessage_FindNodeResponse_Result_BUZZER_DISABLED +#define _meshtastic_AdminMessage_FindNodeResponse_Result_ARRAYSIZE ((meshtastic_AdminMessage_FindNodeResponse_Result)(meshtastic_AdminMessage_FindNodeResponse_Result_BUZZER_DISABLED+1)) + #define _meshtastic_KeyVerificationAdmin_MessageType_MIN meshtastic_KeyVerificationAdmin_MessageType_INITIATE_VERIFICATION #define _meshtastic_KeyVerificationAdmin_MessageType_MAX meshtastic_KeyVerificationAdmin_MessageType_DO_NOT_VERIFY #define _meshtastic_KeyVerificationAdmin_MessageType_ARRAYSIZE ((meshtastic_KeyVerificationAdmin_MessageType)(meshtastic_KeyVerificationAdmin_MessageType_DO_NOT_VERIFY+1)) @@ -528,6 +559,9 @@ extern "C" { #define meshtastic_AdminMessage_OTAEvent_reboot_ota_mode_ENUMTYPE meshtastic_OTAMode +#define meshtastic_AdminMessage_FindNodeResponse_result_ENUMTYPE meshtastic_AdminMessage_FindNodeResponse_Result + + @@ -543,6 +577,8 @@ extern "C" { #define meshtastic_AdminMessage_init_default {0, {0}, {0, {0}}} #define meshtastic_AdminMessage_InputEvent_init_default {0, 0, 0, 0} #define meshtastic_AdminMessage_OTAEvent_init_default {_meshtastic_OTAMode_MIN, {0, {0}}} +#define meshtastic_AdminMessage_FindNodeRequest_init_default {0, 0} +#define meshtastic_AdminMessage_FindNodeResponse_init_default {_meshtastic_AdminMessage_FindNodeResponse_Result_MIN, 0} #define meshtastic_LockdownAuth_init_default {{0, {0}}, 0, 0, 0, 0, 0} #define meshtastic_HamParameters_init_default {"", 0, 0, ""} #define meshtastic_NodeRemoteHardwarePinsResponse_init_default {0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}} @@ -556,6 +592,8 @@ extern "C" { #define meshtastic_AdminMessage_init_zero {0, {0}, {0, {0}}} #define meshtastic_AdminMessage_InputEvent_init_zero {0, 0, 0, 0} #define meshtastic_AdminMessage_OTAEvent_init_zero {_meshtastic_OTAMode_MIN, {0, {0}}} +#define meshtastic_AdminMessage_FindNodeRequest_init_zero {0, 0} +#define meshtastic_AdminMessage_FindNodeResponse_init_zero {_meshtastic_AdminMessage_FindNodeResponse_Result_MIN, 0} #define meshtastic_LockdownAuth_init_zero {{0, {0}}, 0, 0, 0, 0, 0} #define meshtastic_HamParameters_init_zero {"", 0, 0, ""} #define meshtastic_NodeRemoteHardwarePinsResponse_init_zero {0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}} @@ -574,6 +612,10 @@ extern "C" { #define meshtastic_AdminMessage_InputEvent_touch_y_tag 4 #define meshtastic_AdminMessage_OTAEvent_reboot_ota_mode_tag 1 #define meshtastic_AdminMessage_OTAEvent_ota_hash_tag 2 +#define meshtastic_AdminMessage_FindNodeRequest_duration_seconds_tag 1 +#define meshtastic_AdminMessage_FindNodeRequest_stop_tag 2 +#define meshtastic_AdminMessage_FindNodeResponse_result_tag 1 +#define meshtastic_AdminMessage_FindNodeResponse_duration_seconds_tag 2 #define meshtastic_LockdownAuth_passphrase_tag 1 #define meshtastic_LockdownAuth_boots_remaining_tag 2 #define meshtastic_LockdownAuth_valid_until_epoch_tag 3 @@ -661,6 +703,8 @@ extern "C" { #define meshtastic_AdminMessage_commit_edit_settings_tag 65 #define meshtastic_AdminMessage_add_contact_tag 66 #define meshtastic_AdminMessage_key_verification_tag 67 +#define meshtastic_AdminMessage_find_node_request_tag 68 +#define meshtastic_AdminMessage_find_node_response_tag 69 #define meshtastic_AdminMessage_factory_reset_device_tag 94 #define meshtastic_AdminMessage_reboot_ota_seconds_tag 95 #define meshtastic_AdminMessage_exit_simulator_tag 96 @@ -723,6 +767,8 @@ X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_ed X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,add_contact,add_contact), 66) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,key_verification,key_verification), 67) \ +X(a, STATIC, ONEOF, MESSAGE, (payload_variant,find_node_request,find_node_request), 68) \ +X(a, STATIC, ONEOF, MESSAGE, (payload_variant,find_node_response,find_node_response), 69) \ X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_device,factory_reset_device), 94) \ X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,exit_simulator,exit_simulator), 96) \ @@ -754,6 +800,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,lockdown_auth,lockdown_auth) #define meshtastic_AdminMessage_payload_variant_store_ui_config_MSGTYPE meshtastic_DeviceUIConfig #define meshtastic_AdminMessage_payload_variant_add_contact_MSGTYPE meshtastic_SharedContact #define meshtastic_AdminMessage_payload_variant_key_verification_MSGTYPE meshtastic_KeyVerificationAdmin +#define meshtastic_AdminMessage_payload_variant_find_node_request_MSGTYPE meshtastic_AdminMessage_FindNodeRequest +#define meshtastic_AdminMessage_payload_variant_find_node_response_MSGTYPE meshtastic_AdminMessage_FindNodeResponse #define meshtastic_AdminMessage_payload_variant_ota_request_MSGTYPE meshtastic_AdminMessage_OTAEvent #define meshtastic_AdminMessage_payload_variant_sensor_config_MSGTYPE meshtastic_SensorConfig #define meshtastic_AdminMessage_payload_variant_lockdown_auth_MSGTYPE meshtastic_LockdownAuth @@ -772,6 +820,18 @@ X(a, STATIC, SINGULAR, BYTES, ota_hash, 2) #define meshtastic_AdminMessage_OTAEvent_CALLBACK NULL #define meshtastic_AdminMessage_OTAEvent_DEFAULT NULL +#define meshtastic_AdminMessage_FindNodeRequest_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, duration_seconds, 1) \ +X(a, STATIC, SINGULAR, BOOL, stop, 2) +#define meshtastic_AdminMessage_FindNodeRequest_CALLBACK NULL +#define meshtastic_AdminMessage_FindNodeRequest_DEFAULT NULL + +#define meshtastic_AdminMessage_FindNodeResponse_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, result, 1) \ +X(a, STATIC, SINGULAR, UINT32, duration_seconds, 2) +#define meshtastic_AdminMessage_FindNodeResponse_CALLBACK NULL +#define meshtastic_AdminMessage_FindNodeResponse_DEFAULT NULL + #define meshtastic_LockdownAuth_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, BYTES, passphrase, 1) \ X(a, STATIC, SINGULAR, UINT32, boots_remaining, 2) \ @@ -860,6 +920,8 @@ X(a, STATIC, OPTIONAL, UINT32, set_accuracy, 1) extern const pb_msgdesc_t meshtastic_AdminMessage_msg; extern const pb_msgdesc_t meshtastic_AdminMessage_InputEvent_msg; extern const pb_msgdesc_t meshtastic_AdminMessage_OTAEvent_msg; +extern const pb_msgdesc_t meshtastic_AdminMessage_FindNodeRequest_msg; +extern const pb_msgdesc_t meshtastic_AdminMessage_FindNodeResponse_msg; extern const pb_msgdesc_t meshtastic_LockdownAuth_msg; extern const pb_msgdesc_t meshtastic_HamParameters_msg; extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePinsResponse_msg; @@ -875,6 +937,8 @@ extern const pb_msgdesc_t meshtastic_SHTXX_config_msg; #define meshtastic_AdminMessage_fields &meshtastic_AdminMessage_msg #define meshtastic_AdminMessage_InputEvent_fields &meshtastic_AdminMessage_InputEvent_msg #define meshtastic_AdminMessage_OTAEvent_fields &meshtastic_AdminMessage_OTAEvent_msg +#define meshtastic_AdminMessage_FindNodeRequest_fields &meshtastic_AdminMessage_FindNodeRequest_msg +#define meshtastic_AdminMessage_FindNodeResponse_fields &meshtastic_AdminMessage_FindNodeResponse_msg #define meshtastic_LockdownAuth_fields &meshtastic_LockdownAuth_msg #define meshtastic_HamParameters_fields &meshtastic_HamParameters_msg #define meshtastic_NodeRemoteHardwarePinsResponse_fields &meshtastic_NodeRemoteHardwarePinsResponse_msg @@ -888,6 +952,8 @@ extern const pb_msgdesc_t meshtastic_SHTXX_config_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_ADMIN_PB_H_MAX_SIZE meshtastic_AdminMessage_size +#define meshtastic_AdminMessage_FindNodeRequest_size 6 +#define meshtastic_AdminMessage_FindNodeResponse_size 6 #define meshtastic_AdminMessage_InputEvent_size 14 #define meshtastic_AdminMessage_OTAEvent_size 36 #define meshtastic_AdminMessage_size 511 diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 4436fd16e0f..de201d7eba6 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -1345,6 +1345,8 @@ typedef struct _meshtastic_DeviceMetadata { /* Bit field of boolean for excluded modules (bitwise OR of ExcludedModules) */ uint32_t excluded_modules; + /* Indicates that the device has a buzzer or audio output usable by the find-node command */ + bool hasBuzzer; } meshtastic_DeviceMetadata; /* Packets from the radio to the phone will appear on the fromRadio characteristic. @@ -1632,7 +1634,7 @@ extern "C" { #define meshtastic_Compressed_init_default {_meshtastic_PortNum_MIN, {0, {0}}} #define meshtastic_NeighborInfo_init_default {0, 0, 0, 0, {meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default}} #define meshtastic_Neighbor_init_default {0, 0, 0, 0} -#define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0, 0} +#define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0, 0, 0} #define meshtastic_Heartbeat_init_default {0} #define meshtastic_NodeRemoteHardwarePin_init_default {0, false, meshtastic_RemoteHardwarePin_init_default} #define meshtastic_ChunkedPayload_init_default {0, 0, 0, {0, {0}}} @@ -1667,7 +1669,7 @@ extern "C" { #define meshtastic_Compressed_init_zero {_meshtastic_PortNum_MIN, {0, {0}}} #define meshtastic_NeighborInfo_init_zero {0, 0, 0, 0, {meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero}} #define meshtastic_Neighbor_init_zero {0, 0, 0, 0} -#define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0, 0} +#define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0, 0, 0, 0} #define meshtastic_Heartbeat_init_zero {0} #define meshtastic_NodeRemoteHardwarePin_init_zero {0, false, meshtastic_RemoteHardwarePin_init_zero} #define meshtastic_ChunkedPayload_init_zero {0, 0, 0, {0, {0}}} @@ -1858,6 +1860,7 @@ extern "C" { #define meshtastic_DeviceMetadata_hasRemoteHardware_tag 10 #define meshtastic_DeviceMetadata_hasPKC_tag 11 #define meshtastic_DeviceMetadata_excluded_modules_tag 12 +#define meshtastic_DeviceMetadata_hasBuzzer_tag 13 #define meshtastic_FromRadio_id_tag 1 #define meshtastic_FromRadio_packet_tag 2 #define meshtastic_FromRadio_my_info_tag 3 @@ -2252,7 +2255,8 @@ X(a, STATIC, SINGULAR, UINT32, position_flags, 8) \ X(a, STATIC, SINGULAR, UENUM, hw_model, 9) \ X(a, STATIC, SINGULAR, BOOL, hasRemoteHardware, 10) \ X(a, STATIC, SINGULAR, BOOL, hasPKC, 11) \ -X(a, STATIC, SINGULAR, UINT32, excluded_modules, 12) +X(a, STATIC, SINGULAR, UINT32, excluded_modules, 12) \ +X(a, STATIC, SINGULAR, BOOL, hasBuzzer, 13) #define meshtastic_DeviceMetadata_CALLBACK NULL #define meshtastic_DeviceMetadata_DEFAULT NULL @@ -2371,7 +2375,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg; #define meshtastic_ClientNotification_size 482 #define meshtastic_Compressed_size 239 #define meshtastic_Data_size 335 -#define meshtastic_DeviceMetadata_size 54 +#define meshtastic_DeviceMetadata_size 56 #define meshtastic_DuplicatedPublicKey_size 0 #define meshtastic_FileInfo_size 236 #define meshtastic_FromRadio_size 510 diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index d5ccbaf1292..e55bf831954 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -5,6 +5,7 @@ #include "PowerFSM.h" #include "RTC.h" #include "SPILock.h" +#include "buzz/FindNodeBuzzer.h" #include "input/InputBroker.h" #include "meshUtils.h" #include @@ -602,6 +603,11 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta handleSendInputEvent(r->send_input_event); break; } + case meshtastic_AdminMessage_find_node_request_tag: { + LOG_INFO("Client requesting find-node buzzer"); + handleFindNodeRequest(mp, r->find_node_request); + break; + } #ifdef ARCH_PORTDUINO case meshtastic_AdminMessage_exit_simulator_tag: LOG_INFO("Exiting simulator"); @@ -1386,6 +1392,42 @@ void AdminModule::handleGetDeviceMetadata(const meshtastic_MeshPacket &req) } } +void AdminModule::handleFindNodeRequest(const meshtastic_MeshPacket &req, const meshtastic_AdminMessage_FindNodeRequest &request) +{ + meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default; + r.which_payload_variant = meshtastic_AdminMessage_find_node_response_tag; + + uint32_t acceptedDurationSeconds = 0; + FindNodeBuzzer::Result result = FindNodeBuzzer::Result::NoBuzzer; + if (findNodeBuzzer) { + result = + request.stop ? findNodeBuzzer->stop() : findNodeBuzzer->start(request.duration_seconds, &acceptedDurationSeconds); + } + + switch (result) { + case FindNodeBuzzer::Result::Started: + r.find_node_response.result = meshtastic_AdminMessage_FindNodeResponse_Result_STARTED; + r.find_node_response.duration_seconds = acceptedDurationSeconds; + break; + case FindNodeBuzzer::Result::Stopped: + r.find_node_response.result = meshtastic_AdminMessage_FindNodeResponse_Result_STOPPED; + break; + case FindNodeBuzzer::Result::BuzzerDisabled: + r.find_node_response.result = meshtastic_AdminMessage_FindNodeResponse_Result_BUZZER_DISABLED; + break; + case FindNodeBuzzer::Result::NoBuzzer: + default: + r.find_node_response.result = meshtastic_AdminMessage_FindNodeResponse_Result_NO_BUZZER; + break; + } + + setPassKey(&r); + myReply = allocDataProtobuf(r); + if (req.pki_encrypted) { + myReply->pki_encrypted = true; + } +} + void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &req) { meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default; @@ -1601,6 +1643,7 @@ bool AdminModule::messageIsResponse(const meshtastic_AdminMessage *r) r->which_payload_variant == meshtastic_AdminMessage_get_canned_message_module_messages_response_tag || r->which_payload_variant == meshtastic_AdminMessage_get_device_metadata_response_tag || r->which_payload_variant == meshtastic_AdminMessage_get_ringtone_response_tag || + r->which_payload_variant == meshtastic_AdminMessage_find_node_response_tag || r->which_payload_variant == meshtastic_AdminMessage_get_device_connection_status_response_tag || r->which_payload_variant == meshtastic_AdminMessage_get_node_remote_hardware_pins_response_tag || r->which_payload_variant == meshtastic_AdminMessage_get_ui_config_response_tag) diff --git a/src/modules/AdminModule.h b/src/modules/AdminModule.h index aeb41471c05..a28d6efe40f 100644 --- a/src/modules/AdminModule.h +++ b/src/modules/AdminModule.h @@ -55,6 +55,7 @@ class AdminModule : public ProtobufModule, public Obser void handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &req); void handleGetNodeRemoteHardwarePins(const meshtastic_MeshPacket &req); void handleGetDeviceUIConfig(const meshtastic_MeshPacket &req); + void handleFindNodeRequest(const meshtastic_MeshPacket &req, const meshtastic_AdminMessage_FindNodeRequest &request); /** * Setters */ @@ -90,4 +91,4 @@ static constexpr const char *licensedModeMessage = extern AdminModule *adminModule; -void disableBluetooth(); \ No newline at end of file +void disableBluetooth(); diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index 5cc94a68fca..47a5171e7c0 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -1,3 +1,4 @@ +#include "buzz/FindNodeBuzzer.h" #include "configuration.h" #if !MESHTASTIC_EXCLUDE_INPUTBROKER #include "buzz/BuzzerFeedbackThread.h" @@ -115,6 +116,7 @@ */ void setupModules() { + findNodeBuzzer = new FindNodeBuzzer(); #if (HAS_BUTTON || ARCH_PORTDUINO) && !MESHTASTIC_EXCLUDE_INPUTBROKER if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { inputBroker = new InputBroker(); From 1c02b2fcbd22155c0191aa7ca595a290bdce8551 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Wed, 17 Jun 2026 08:09:28 -0700 Subject: [PATCH 02/14] chore: ignore local worktree directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 55e90a8f28d..144c64e80ce 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ web.tar .platformio .local .cache +.worktrees/ .DS_Store Thumbs.db From 54deedd6cfe0779c651711fca9bf508bb28f76b0 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sat, 20 Jun 2026 13:47:46 -0700 Subject: [PATCH 03/14] fix: preserve moved device config fields --- src/modules/AdminModule.cpp | 42 +++++++++++++++++++++++-------------- src/modules/AdminModule.h | 2 +- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index c2120f0ee97..2b80b0ba82f 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -93,13 +93,13 @@ static uint32_t effectiveBuzzerGpio(uint32_t gpio) static bool sameDeviceConfig(const meshtastic_Config_DeviceConfig ¤t, const meshtastic_Config_DeviceConfig &requested) { - return current.role == requested.role && current.serial_enabled == requested.serial_enabled && + return current.role == requested.role && effectiveButtonGpio(current.button_gpio) == effectiveButtonGpio(requested.button_gpio) && effectiveBuzzerGpio(current.buzzer_gpio) == effectiveBuzzerGpio(requested.buzzer_gpio) && current.rebroadcast_mode == requested.rebroadcast_mode && current.node_info_broadcast_secs == requested.node_info_broadcast_secs && current.double_tap_as_button_press == requested.double_tap_as_button_press && - current.is_managed == requested.is_managed && current.disable_triple_click == requested.disable_triple_click && + current.disable_triple_click == requested.disable_triple_click && strncmp(current.tzdef, requested.tzdef, sizeof(current.tzdef)) == 0 && current.led_heartbeat_disabled == requested.led_heartbeat_disabled && current.buzzer_mode == requested.buzzer_mode; } @@ -795,31 +795,37 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers) auto existingRole = config.device.role; bool isRegionUnset = (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET); bool requiresReboot = true; + bool reloadConfig = true; switch (c.which_payload_variant) { case meshtastic_Config_device_tag: { LOG_INFO("Set config: Device"); - if (config.has_device && sameDeviceConfig(config.device, c.payload_variant.device)) { + auto requestedDevice = c.payload_variant.device; + if (config.has_device) { + requestedDevice.serial_enabled = config.device.serial_enabled; + requestedDevice.is_managed = config.device.is_managed; + } + if (config.has_device && sameDeviceConfig(config.device, requestedDevice)) { LOG_DEBUG("Device config unchanged, skipping save"); return; } config.has_device = true; #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && \ !MESHTASTIC_EXCLUDE_ACCELEROMETER - if (config.device.double_tap_as_button_press == false && c.payload_variant.device.double_tap_as_button_press == true && + if (config.device.double_tap_as_button_press == false && requestedDevice.double_tap_as_button_press == true && accelerometerThread->enabled == false) { - config.device.double_tap_as_button_press = c.payload_variant.device.double_tap_as_button_press; + config.device.double_tap_as_button_press = requestedDevice.double_tap_as_button_press; accelerometerThread->enabled = true; accelerometerThread->start(); } #endif - if (effectiveButtonGpio(config.device.button_gpio) == effectiveButtonGpio(c.payload_variant.device.button_gpio) && - effectiveBuzzerGpio(config.device.buzzer_gpio) == effectiveBuzzerGpio(c.payload_variant.device.buzzer_gpio) && - config.device.role == c.payload_variant.device.role && - config.device.rebroadcast_mode == c.payload_variant.device.rebroadcast_mode) { + if (effectiveButtonGpio(config.device.button_gpio) == effectiveButtonGpio(requestedDevice.button_gpio) && + effectiveBuzzerGpio(config.device.buzzer_gpio) == effectiveBuzzerGpio(requestedDevice.buzzer_gpio) && + config.device.role == requestedDevice.role && config.device.rebroadcast_mode == requestedDevice.rebroadcast_mode) { requiresReboot = false; + reloadConfig = false; } - config.device = c.payload_variant.device; + config.device = requestedDevice; if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_NONE && (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) { @@ -829,8 +835,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers) sendWarning(warning); } // If we're setting router role for the first time, install its intervals - if (existingRole != c.payload_variant.device.role) { - nodeDB->installRoleDefaults(c.payload_variant.device.role); + if (existingRole != requestedDevice.role) { + nodeDB->installRoleDefaults(requestedDevice.role); changes |= SEGMENT_NODEDATABASE | SEGMENT_DEVICESTATE; // Some role defaults affect owner } if (config.device.node_info_broadcast_secs < min_node_info_broadcast_secs) { @@ -838,7 +844,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers) config.device.node_info_broadcast_secs = min_node_info_broadcast_secs; } // Router Client and Repeater deprecated; Set it to client - if (IS_ONE_OF(c.payload_variant.device.role, meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT, + if (IS_ONE_OF(requestedDevice.role, meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT, meshtastic_Config_DeviceConfig_Role_REPEATER)) { config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT; if (moduleConfig.store_forward.enabled && !moduleConfig.store_forward.is_server) { @@ -1086,7 +1092,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers) disableBluetooth(); } // end of switch case which_payload_variant - saveChanges(changes, requiresReboot); + saveChanges(changes, requiresReboot, reloadConfig); } // end of handleSetConfig bool AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c) @@ -1622,11 +1628,15 @@ void AdminModule::reboot(int32_t seconds) rebootAtMsec = (seconds < 0) ? 0 : (millis() + seconds * 1000); } -void AdminModule::saveChanges(int saveWhat, bool shouldReboot) +void AdminModule::saveChanges(int saveWhat, bool shouldReboot, bool reloadConfig) { if (!hasOpenEditTransaction) { LOG_INFO("Save changes to disk"); - service->reloadConfig(saveWhat); // Calls saveToDisk among other things + if (reloadConfig) { + service->reloadConfig(saveWhat); // Calls saveToDisk among other things + } else { + nodeDB->saveToDisk(saveWhat); + } } else { LOG_INFO("Delay save of changes to disk until the open transaction is committed"); } diff --git a/src/modules/AdminModule.h b/src/modules/AdminModule.h index e7f7971afd4..50ae9203f22 100644 --- a/src/modules/AdminModule.h +++ b/src/modules/AdminModule.h @@ -41,7 +41,7 @@ class AdminModule : public ProtobufModule, public Obser uint8_t session_passkey[8] = {0}; uint session_time = 0; - void saveChanges(int saveWhat, bool shouldReboot = true); + void saveChanges(int saveWhat, bool shouldReboot = true, bool reloadConfig = true); /** * Getters From 79c28f8c7d834008ba4d5d5a941273ee8e8c30fc Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:49:59 -0700 Subject: [PATCH 04/14] fix: keep device config reload semantics --- src/modules/AdminModule.cpp | 12 +++--------- src/modules/AdminModule.h | 2 +- src/platform/nrf52/NRF52Bluetooth.cpp | 2 -- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 2b80b0ba82f..dc106721ad3 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -795,7 +795,6 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers) auto existingRole = config.device.role; bool isRegionUnset = (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET); bool requiresReboot = true; - bool reloadConfig = true; switch (c.which_payload_variant) { case meshtastic_Config_device_tag: { @@ -823,7 +822,6 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers) effectiveBuzzerGpio(config.device.buzzer_gpio) == effectiveBuzzerGpio(requestedDevice.buzzer_gpio) && config.device.role == requestedDevice.role && config.device.rebroadcast_mode == requestedDevice.rebroadcast_mode) { requiresReboot = false; - reloadConfig = false; } config.device = requestedDevice; if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_NONE && @@ -1092,7 +1090,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers) disableBluetooth(); } // end of switch case which_payload_variant - saveChanges(changes, requiresReboot, reloadConfig); + saveChanges(changes, requiresReboot); } // end of handleSetConfig bool AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c) @@ -1628,15 +1626,11 @@ void AdminModule::reboot(int32_t seconds) rebootAtMsec = (seconds < 0) ? 0 : (millis() + seconds * 1000); } -void AdminModule::saveChanges(int saveWhat, bool shouldReboot, bool reloadConfig) +void AdminModule::saveChanges(int saveWhat, bool shouldReboot) { if (!hasOpenEditTransaction) { LOG_INFO("Save changes to disk"); - if (reloadConfig) { - service->reloadConfig(saveWhat); // Calls saveToDisk among other things - } else { - nodeDB->saveToDisk(saveWhat); - } + service->reloadConfig(saveWhat); // Calls saveToDisk among other things } else { LOG_INFO("Delay save of changes to disk until the open transaction is committed"); } diff --git a/src/modules/AdminModule.h b/src/modules/AdminModule.h index 50ae9203f22..e7f7971afd4 100644 --- a/src/modules/AdminModule.h +++ b/src/modules/AdminModule.h @@ -41,7 +41,7 @@ class AdminModule : public ProtobufModule, public Obser uint8_t session_passkey[8] = {0}; uint session_time = 0; - void saveChanges(int saveWhat, bool shouldReboot = true, bool reloadConfig = true); + void saveChanges(int saveWhat, bool shouldReboot = true); /** * Getters diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index 11ce914739c..74fc5a9292a 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -73,9 +73,7 @@ void onConnect(uint16_t conn_handle) // re-locks on every want_config too; this closes the window before that. #ifdef MESHTASTIC_PHONEAPI_ACCESS_CONTROL if (bluetoothPhoneAPI) { -#ifdef MESHTASTIC_PHONEAPI_ACCESS_CONTROL bluetoothPhoneAPI->setAdminAuthorized(false); -#endif } #endif From a6f882e5ef323f0d2b638c95cae25433baff8512 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:50:10 -0700 Subject: [PATCH 05/14] chore: remove unrelated find node diff --- .gitignore | 1 - .vscode/extensions.json | 5 +- src/Power.cpp | 5 +- src/gps/GPS.cpp | 1 - src/mesh/NodeDB.cpp | 143 +++++++++++++++++- src/motion/MotionSensor.cpp | 1 - src/power.h | 2 +- .../nrf52840/heltec_mesh_node_t1/variant.h | 1 + .../heltec_mesh_tower_v2/platformio.ini | 2 +- 9 files changed, 142 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 144c64e80ce..55e90a8f28d 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ web.tar .platformio .local .cache -.worktrees/ .DS_Store Thumbs.db diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 0287eda2733..66d8356e517 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,10 +1,7 @@ { - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format "recommendations": [ "Jason2866.esp-decoder", - "pioarduino.pioarduino-ide", - "platformio.platformio-ide" + "pioarduino.pioarduino-ide" ], "unwantedRecommendations": [ "ms-vscode.cpptools-extension-pack", diff --git a/src/Power.cpp b/src/Power.cpp index caae87d34df..5b2d41567ad 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -225,15 +225,14 @@ NullSensor ina3221Sensor; #include "modules/Telemetry/Sensor/MAX17048Sensor.h" #include extern std::pair nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1]; -#endif - #if HAS_TELEMETRY && (!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR || !MESHTASTIC_EXCLUDE_POWER_TELEMETRY) -#if !MESHTASTIC_EXCLUDE_I2C && __has_include() +#if __has_include() MAX17048Sensor max17048Sensor; #else NullSensor max17048Sensor; #endif #endif +#endif #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && HAS_RAKPROT RAK9154Sensor rak9154Sensor; diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index d0f630ef381..5078a6a271b 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -178,7 +178,6 @@ template bool sawNmeaSentenceAtBaud(T *serialGps, uint32_t timeoutM return false; } - } // namespace // For logging diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 421b13e8793..5653011fab5 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -606,6 +606,7 @@ NodeDB::NodeDB() config.bluetooth.enabled = true; } #endif + if (devicestateCRC != crc32Buffer(&devicestate, sizeof(devicestate))) saveWhat |= SEGMENT_DEVICESTATE; if (nodeDatabaseCRC != crc32Buffer(&nodeDatabase, sizeof(nodeDatabase))) @@ -1144,6 +1145,20 @@ void NodeDB::initConfigIntervals() #endif } +// Always-on traffic management defaults. Only booleans are written; every +// numeric field stays 0 and resolves to its default_traffic_mgmt_* macro at +// use (e.g. position dedup precision/interval), so fork-wide tuning changes +// take effect without another migration. Rate limiting and the features that +// exhaust or reshape relayed traffic (exhaust_hop_*, drop_unknown_enabled, +// nodeinfo_direct_response) stay opt-in. +static void installTrafficManagementDefaults(meshtastic_LocalModuleConfig &mc) +{ + mc.has_traffic_management = true; + mc.traffic_management = meshtastic_ModuleConfig_TrafficManagementConfig_init_zero; + mc.traffic_management.enabled = true; + mc.traffic_management.position_dedup_enabled = true; +} + void NodeDB::installDefaultModuleConfig() { LOG_INFO("Install default ModuleConfig"); @@ -1261,6 +1276,8 @@ void NodeDB::installDefaultModuleConfig() moduleConfig.has_neighbor_info = true; moduleConfig.neighbor_info.enabled = false; + installTrafficManagementDefaults(moduleConfig); + moduleConfig.has_detection_sensor = true; moduleConfig.detection_sensor.enabled = false; moduleConfig.detection_sensor.detection_trigger_type = meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH; @@ -1612,6 +1629,27 @@ bool NodeDB::enforceSatelliteCaps() return trimmedAny; } +#if WARM_NODE_COUNT > 0 +// Classify an evicted node's hop-protected category for the warm tier. Favorite/ignored/ +// verified are local flags (rarely reach warm — they're eviction-protected — but classify +// them if they do); otherwise tracker/sensor/tak_tracker are role-protected. +static uint8_t warmProtectedCategory(const meshtastic_NodeInfoLite &n) +{ + if (n.bitfield & (NODEINFO_BITFIELD_IS_FAVORITE_MASK | NODEINFO_BITFIELD_IS_IGNORED_MASK | + NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK)) + return static_cast(WarmProtected::Flag); + if (IS_ONE_OF(n.role, meshtastic_Config_DeviceConfig_Role_TRACKER, meshtastic_Config_DeviceConfig_Role_SENSOR, + meshtastic_Config_DeviceConfig_Role_TAK_TRACKER)) + return static_cast(WarmProtected::Role); + return static_cast(WarmProtected::None); +} + +// The warm tier packs the device role into a 4-bit field (WARM_ROLE_MASK). Fail the build +// loudly if a new role outgrows it, rather than silently truncating role on eviction. +static_assert(_meshtastic_Config_DeviceConfig_Role_MAX <= WARM_ROLE_MASK, + "device role no longer fits the 4-bit warm metadata field"); +#endif // WARM_NODE_COUNT > 0 + void NodeDB::cleanupMeshDB() { int newPos = 0, removed = 0; @@ -1638,7 +1676,7 @@ void NodeDB::cleanupMeshDB() // Keep any key we learned (e.g. via a DM before the NodeInfo // exchange completed) rather than losing it with the purge. if (n.public_key.size == 32) - warmStore.absorb(gone, n.last_heard, n.public_key.bytes); + warmStore.absorb(gone, n.last_heard, n.public_key.bytes, n.role, warmProtectedCategory(n)); #endif eraseNodeSatellites(gone); @@ -1821,7 +1859,8 @@ void NodeDB::demoteOldestHotNodesToWarm() continue; // Keep the public key if we have one (40 B warm record); keyless nodes // still get a placeholder so re-admission restores last_heard. - warmStore.absorb(n.num, n.last_heard, n.public_key.size > 0 ? n.public_key.bytes : nullptr); + warmStore.absorb(n.num, n.last_heard, n.public_key.size > 0 ? n.public_key.bytes : nullptr, n.role, + warmProtectedCategory(n)); // Demotion drops the node from the header table, so drop its satellites // too (the eviction chokepoint) — they'd otherwise orphan until the next // enforceSatelliteCaps pass. @@ -2225,6 +2264,16 @@ void NodeDB::loadFromDisk() } } + // Always-on traffic management: a device that has NEVER configured TMM + // (has_traffic_management false — AdminModule always sets the has_ flag on + // write, even when disabling) gets the fork defaults. Explicitly configured + // devices keep their exact settings. + if (!moduleConfig.has_traffic_management) { + LOG_INFO("Traffic management never configured, installing always-on defaults"); + installTrafficManagementDefaults(moduleConfig); + saveToDisk(SEGMENT_MODULECONFIG); + } + state = loadProto(channelFileName, meshtastic_ChannelFile_size, sizeof(meshtastic_ChannelFile), &meshtastic_ChannelFile_msg, &channelFile); if (state != LoadFileResult::LOAD_SUCCESS) { @@ -2772,6 +2821,10 @@ HopStartStatus classifyHopStart(const meshtastic_MeshPacket &p) return HopStartStatus::INVALID; if (p.hop_start == 0) { + // hop_start == hop_limit == 0: intentional zero-hop broadcast (e.g. beacon). Valid by definition — + // the packet was never meant to travel any hops, so no hop_start ambiguity applies. + if (p.hop_limit == 0) + return HopStartStatus::VALID; // Firmware prior to 2.3.0 (585805c) lacked a hop_start field. Firmware version 2.5.0 (bf34329) introduced a // bitfield that is always present. Use the presence of the bitfield to determine if the origin's firmware // version is guaranteed to have hop_start populated. Note that this can only be done for decoded packets as @@ -3112,8 +3165,14 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp) mp.via_mqtt); // Store if we received this packet via MQTT #if HAS_VARIABLE_HOPS - // Only sample packets that arrived over LoRa. - if (mp.transport_mechanism == meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA && hopScalingModule) { + // Only sample genuine RF-origin packets. The transport check excludes packets received + // directly from the broker (TRANSPORT_MQTT), but an MQTT-origin packet rebroadcast onto + // LoRa by a gateway arrives as TRANSPORT_LORA with via_mqtt set — count those would + // inflate the local mesh-size estimate with non-RF nodes (and they usually carry + // hop_start==0, landing in the hop-0 bucket that pulls the recommendation lowest), so + // exclude via_mqtt too. + if (mp.transport_mechanism == meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA && !mp.via_mqtt && + hopScalingModule) { uint8_t hopCount = std::max(int8_t(0), getHopsAway(mp)); hopScalingModule->samplePacketForHistogram(mp.from, hopCount); } @@ -3294,6 +3353,73 @@ meshtastic_NodeInfoLite *NodeDB::getMeshNode(NodeNum n) return NULL; } +ResolvedNode NodeDB::resolveLastByte(uint8_t lastByte, bool requireDirectNeighbor) +{ + ResolvedNode result; // defaults to {None, 0} + + // 0 is the NO_RELAY_NODE / NO_NEXT_HOP_PREFERENCE sentinel (also what MQTT-sourced packets carry + // when hop_start==0). getLastByteOfNodeNum() never yields 0, so nothing can legitimately match. + if (lastByte == 0) + return result; + + const NodeNum self = getNodeNum(); + NodeNum firstMatch = 0; + uint8_t matches = 0; + + for (size_t i = 0; i < numMeshNodes; i++) { + const meshtastic_NodeInfoLite *node = &meshNodes->at(i); + + // Candidate gate: never resolve to ourselves, the sentinels, or an ignored node. + if (node->num == self || node->num == 0 || node->num == NODENUM_BROADCAST) + continue; + if (nodeInfoLiteIsIgnored(node)) + continue; + if (getLastByteOfNodeNum(node->num) != lastByte) // cheapest discriminator last + continue; + + // Relevance gate: is this node a plausible relay for the requested scope? + bool relevant; + if (requireDirectNeighbor) { + relevant = node->has_hops_away && node->hops_away == 0 && sinceLastSeen(node) < NEXTHOP_NEIGHBOR_FRESH_SECS; + } else { + const bool directNeighbor = node->has_hops_away && node->hops_away == 0; + const bool routerRole = + IS_ONE_OF(node->role, meshtastic_Config_DeviceConfig_Role_ROUTER, meshtastic_Config_DeviceConfig_Role_ROUTER_LATE, + meshtastic_Config_DeviceConfig_Role_CLIENT_BASE); + relevant = directNeighbor || nodeInfoLiteIsFavorite(node) || routerRole; + } + if (!relevant) + continue; + + if (++matches == 1) { + firstMatch = node->num; + } else { + // A second relevant candidate shares this byte: ambiguous. No further scanning can + // change that, so stop early and report the collision. + result.status = LastByteResolution::Ambiguous; + result.num = 0; + return result; + } + } + + if (matches == 1) { + result.status = LastByteResolution::Unique; + result.num = firstMatch; + } + return result; +} + +bool NodeDB::resolveUniqueLastByte(uint8_t lastByte, bool requireDirectNeighbor, NodeNum *outNum) +{ + ResolvedNode r = resolveLastByte(lastByte, requireDirectNeighbor); + if (r.status == LastByteResolution::Unique) { + if (outNum) + *outNum = r.num; + return true; + } + return false; +} + // returns true if the maximum number of nodes is reached or we are running low on memory bool NodeDB::isFull() { @@ -3364,8 +3490,8 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n) #if WARM_NODE_COUNT > 0 // Demote to the warm tier so the identity (and crucially the // PKI key) outlives the hot-store slot. - warmStore.absorb(evicted.num, evicted.last_heard, - evicted.public_key.size == 32 ? evicted.public_key.bytes : NULL); + warmStore.absorb(evicted.num, evicted.last_heard, evicted.public_key.size == 32 ? evicted.public_key.bytes : NULL, + evicted.role, warmProtectedCategory(evicted)); #endif eraseNodeSatellites(evicted.num); // Shove the remaining nodes down the chain @@ -3394,7 +3520,10 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n) // Re-admission: restore what the warm tier kept for this node WarmNodeEntry warm; if (warmStore.take(n, warm)) { - lite->last_heard = warm.last_heard; + lite->last_heard = warmTimeOf(warm); // mask off the stolen role/protected metadata bits + // Restore the role the warm tier cached, so re-admission isn't stuck at CLIENT + // until the next NodeInfo arrives. + lite->role = static_cast(warmRoleOf(warm)); if (!memfll(warm.public_key, 0, sizeof(warm.public_key))) { lite->public_key.size = 32; memcpy(lite->public_key.bytes, warm.public_key, 32); diff --git a/src/motion/MotionSensor.cpp b/src/motion/MotionSensor.cpp index a431c56111f..878b4dd5088 100755 --- a/src/motion/MotionSensor.cpp +++ b/src/motion/MotionSensor.cpp @@ -1,6 +1,5 @@ #include "MotionSensor.h" #include "FSCommon.h" -#include "NodeDB.h" #include "SPILock.h" #include "SafeFile.h" #include "concurrency/LockGuard.h" diff --git a/src/power.h b/src/power.h index 591f41161d8..a4243a3066b 100644 --- a/src/power.h +++ b/src/power.h @@ -63,7 +63,7 @@ extern NullSensor ina3221Sensor; #endif #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR -#if !MESHTASTIC_EXCLUDE_I2C && __has_include() +#if __has_include() #include "modules/Telemetry/Sensor/MAX17048Sensor.h" extern MAX17048Sensor max17048Sensor; #else diff --git a/variants/nrf52840/heltec_mesh_node_t1/variant.h b/variants/nrf52840/heltec_mesh_node_t1/variant.h index d406304fa37..c2808ad5482 100644 --- a/variants/nrf52840/heltec_mesh_node_t1/variant.h +++ b/variants/nrf52840/heltec_mesh_node_t1/variant.h @@ -115,6 +115,7 @@ extern "C" { #define PIN_SPI1_SCK ST7735_SCK // GPS (UC6580) + #define GPS_UC6580 #define GPS_BAUDRATE 115200 #define PIN_GPS_RESET (0 + 26) diff --git a/variants/nrf52840/heltec_mesh_tower_v2/platformio.ini b/variants/nrf52840/heltec_mesh_tower_v2/platformio.ini index e40356a7c40..05f3f49d4ef 100644 --- a/variants/nrf52840/heltec_mesh_tower_v2/platformio.ini +++ b/variants/nrf52840/heltec_mesh_tower_v2/platformio.ini @@ -21,7 +21,7 @@ build_flags = ${nrf52840_base.build_flags} -D HAS_LORA_FEM=1 build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/heltec_mesh_tower_v2> -lib_deps = +lib_deps = ${nrf52840_base.lib_deps} # renovate: datasource=custom.pio depName=ArduinoJson packageName=bblanchon/library/ArduinoJson bblanchon/ArduinoJson@6.21.6 From 37ae5ef8058bf9c97857b6a8128e154cdcbd99f9 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:51:37 -0700 Subject: [PATCH 06/14] chore: drop unrelated variant formatting --- variants/esp32c6/m5stack_unitc6l/variant.cpp | 3 +-- .../nrf52840/heltec_mesh_tower_v2/variant.cpp | 5 +++- .../nrf52840/heltec_mesh_tower_v2/variant.h | 24 +++++++++---------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/variants/esp32c6/m5stack_unitc6l/variant.cpp b/variants/esp32c6/m5stack_unitc6l/variant.cpp index 23fecef861e..7dc5785f682 100644 --- a/variants/esp32c6/m5stack_unitc6l/variant.cpp +++ b/variants/esp32c6/m5stack_unitc6l/variant.cpp @@ -60,8 +60,7 @@ void c6l_init() vTaskDelay(10 / portTICK_PERIOD_MS); i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_PULL_EN, 0b11100011); // pull up/down enable, 0 disable, 1 enable vTaskDelay(10 / portTICK_PERIOD_MS); - i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_IN_DEF_STA, - 0b00000011); // P0 P1 default to high level; button press triggers the interrupt + i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_IN_DEF_STA, 0b00000011); // P0 P1 default to high level; button press triggers the interrupt vTaskDelay(10 / portTICK_PERIOD_MS); i2c_write_byte(PI4IO_M_ADDR, PI4IO_REG_INT_MASK, 0b11111100); // P0 P1 interrupts enabled (0 = enable, 1 = disable) vTaskDelay(10 / portTICK_PERIOD_MS); diff --git a/variants/nrf52840/heltec_mesh_tower_v2/variant.cpp b/variants/nrf52840/heltec_mesh_tower_v2/variant.cpp index 6f8b0303e6a..08843c0a66b 100644 --- a/variants/nrf52840/heltec_mesh_tower_v2/variant.cpp +++ b/variants/nrf52840/heltec_mesh_tower_v2/variant.cpp @@ -31,7 +31,10 @@ const uint32_t g_ADigitalPinMap[] = { // P1 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}; -void initVariant() {} +void initVariant() +{ + +} void variant_shutdown() { diff --git a/variants/nrf52840/heltec_mesh_tower_v2/variant.h b/variants/nrf52840/heltec_mesh_tower_v2/variant.h index bb5708f2993..1dd0ce63f26 100644 --- a/variants/nrf52840/heltec_mesh_tower_v2/variant.h +++ b/variants/nrf52840/heltec_mesh_tower_v2/variant.h @@ -39,8 +39,8 @@ extern "C" { #define NUM_ANALOG_INPUTS (1) #define NUM_ANALOG_OUTPUTS (0) -#define PIN_LED1 (32 + 15) // green -#define LED_BLUE PIN_LED1 // fake for bluefruit library +#define PIN_LED1 (32 + 15) // green +#define LED_BLUE PIN_LED1 // fake for bluefruit library #define LED_GREEN PIN_LED1 #define LED_STATE_ON 0 // State when LED is lit @@ -78,10 +78,10 @@ No longer populated on PCB #define SX126X_DIO3_TCXO_VOLTAGE 1.8 #define USE_KCT8103L_PA_ONLY -#define LORA_KCT8103L_EN (0 + 15) // CSD - KCT8103L chip enable (HIGH=on) -#define LORA_KCT8103L_TX_RX (0 + 16) // TX or bypass control (HIGH=TX, LOW=RX) -#define LORA_PA_POWER LORA_KCT8103L_EN -#define RF_PA_DETECT_PIN (0 + 13) // HIGH=high-power PA, LOW=low-power +#define LORA_KCT8103L_EN (0 + 15) // CSD - KCT8103L chip enable (HIGH=on) +#define LORA_KCT8103L_TX_RX (0 + 16) // TX or bypass control (HIGH=TX, LOW=RX) +#define LORA_PA_POWER LORA_KCT8103L_EN +#define RF_PA_DETECT_PIN (0 + 13) // HIGH=high-power PA, LOW=low-power #define RF_PA_HIGH_POWER_VALUE HIGH /* @@ -105,10 +105,10 @@ No longer populated on PCB #define PIN_GPS_EN (0 + 7) // P0.07, VGNSS_Ctrl #define GPS_EN_ACTIVE LOW #define PERIPHERAL_WARMUP_MS 1000 // Make sure GNSS power is stable before continuing -#define PIN_GPS_STANDBY (32 + 2) // P1.02, WAKE_UP. Low allows sleep, high forces wake. -#define PIN_GPS_PPS (32 + 4) // P1.04, 1PPS -#define GPS_RX_PIN (32 + 5) // P1.05, MCU RX connected to GPS TXD. -#define GPS_TX_PIN (32 + 7) // P1.07, MCU TX connected to GPS RXD. +#define PIN_GPS_STANDBY (32 + 2) // P1.02, WAKE_UP. Low allows sleep, high forces wake. +#define PIN_GPS_PPS (32 + 4) // P1.04, 1PPS +#define GPS_RX_PIN (32 + 5) // P1.05, MCU RX connected to GPS TXD. +#define GPS_TX_PIN (32 + 7) // P1.07, MCU TX connected to GPS RXD. #define GPS_THREAD_INTERVAL 50 @@ -123,9 +123,9 @@ No longer populated on PCB #define SERIAL_PRINT_PORT 0 -#define ADC_CTRL (0 + 21) // P0.21, ADC_Ctrl +#define ADC_CTRL (0 + 21) // P0.21, ADC_Ctrl #define ADC_CTRL_ENABLED HIGH -#define BATTERY_PIN (0 + 4) // P0.04, ADC_IN +#define BATTERY_PIN (0 + 4) // P0.04, ADC_IN #define ADC_RESOLUTION 14 #define BATTERY_SENSE_RESOLUTION_BITS 12 From c9c772b755c741ed4c274b011f2d1b48eae4b422 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:52:09 -0700 Subject: [PATCH 07/14] chore: drop generated version-only noise --- src/mesh/generated/meshtastic/apponly.pb.cpp | 2 +- src/mesh/generated/meshtastic/apponly.pb.h | 2 +- src/mesh/generated/meshtastic/atak.pb.cpp | 2 +- src/mesh/generated/meshtastic/atak.pb.h | 2 +- src/mesh/generated/meshtastic/cannedmessages.pb.cpp | 2 +- src/mesh/generated/meshtastic/cannedmessages.pb.h | 2 +- src/mesh/generated/meshtastic/channel.pb.cpp | 2 +- src/mesh/generated/meshtastic/channel.pb.h | 2 +- src/mesh/generated/meshtastic/clientonly.pb.cpp | 2 +- src/mesh/generated/meshtastic/clientonly.pb.h | 2 +- src/mesh/generated/meshtastic/config.pb.cpp | 2 +- src/mesh/generated/meshtastic/config.pb.h | 2 +- src/mesh/generated/meshtastic/connection_status.pb.cpp | 2 +- src/mesh/generated/meshtastic/connection_status.pb.h | 2 +- src/mesh/generated/meshtastic/device_ui.pb.cpp | 2 +- src/mesh/generated/meshtastic/device_ui.pb.h | 2 +- src/mesh/generated/meshtastic/deviceonly.pb.cpp | 2 +- src/mesh/generated/meshtastic/deviceonly.pb.h | 2 +- src/mesh/generated/meshtastic/deviceonly_legacy.pb.cpp | 2 +- src/mesh/generated/meshtastic/deviceonly_legacy.pb.h | 2 +- src/mesh/generated/meshtastic/interdevice.pb.cpp | 2 +- src/mesh/generated/meshtastic/interdevice.pb.h | 2 +- src/mesh/generated/meshtastic/localonly.pb.cpp | 2 +- src/mesh/generated/meshtastic/localonly.pb.h | 2 +- src/mesh/generated/meshtastic/module_config.pb.cpp | 2 +- src/mesh/generated/meshtastic/module_config.pb.h | 2 +- src/mesh/generated/meshtastic/mqtt.pb.cpp | 2 +- src/mesh/generated/meshtastic/mqtt.pb.h | 2 +- src/mesh/generated/meshtastic/paxcount.pb.cpp | 2 +- src/mesh/generated/meshtastic/paxcount.pb.h | 2 +- src/mesh/generated/meshtastic/portnums.pb.cpp | 2 +- src/mesh/generated/meshtastic/portnums.pb.h | 2 +- src/mesh/generated/meshtastic/powermon.pb.cpp | 2 +- src/mesh/generated/meshtastic/powermon.pb.h | 2 +- src/mesh/generated/meshtastic/remote_hardware.pb.cpp | 2 +- src/mesh/generated/meshtastic/remote_hardware.pb.h | 2 +- src/mesh/generated/meshtastic/rtttl.pb.cpp | 2 +- src/mesh/generated/meshtastic/rtttl.pb.h | 2 +- src/mesh/generated/meshtastic/serial_hal.pb.cpp | 2 +- src/mesh/generated/meshtastic/serial_hal.pb.h | 2 +- src/mesh/generated/meshtastic/storeforward.pb.cpp | 2 +- src/mesh/generated/meshtastic/storeforward.pb.h | 2 +- src/mesh/generated/meshtastic/telemetry.pb.cpp | 2 +- src/mesh/generated/meshtastic/telemetry.pb.h | 2 +- src/mesh/generated/meshtastic/xmodem.pb.cpp | 2 +- src/mesh/generated/meshtastic/xmodem.pb.h | 2 +- 46 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/mesh/generated/meshtastic/apponly.pb.cpp b/src/mesh/generated/meshtastic/apponly.pb.cpp index 64d43b7ee1c..8b1b3da19e2 100644 --- a/src/mesh/generated/meshtastic/apponly.pb.cpp +++ b/src/mesh/generated/meshtastic/apponly.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/apponly.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/apponly.pb.h b/src/mesh/generated/meshtastic/apponly.pb.h index f1ef2d8e68c..88cbcb5e67b 100644 --- a/src/mesh/generated/meshtastic/apponly.pb.h +++ b/src/mesh/generated/meshtastic/apponly.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_APPONLY_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_APPONLY_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/atak.pb.cpp b/src/mesh/generated/meshtastic/atak.pb.cpp index 32dccb08613..717727fa55f 100644 --- a/src/mesh/generated/meshtastic/atak.pb.cpp +++ b/src/mesh/generated/meshtastic/atak.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/atak.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/atak.pb.h b/src/mesh/generated/meshtastic/atak.pb.h index 4e194fac7f9..6ea298f9ed7 100644 --- a/src/mesh/generated/meshtastic/atak.pb.h +++ b/src/mesh/generated/meshtastic/atak.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_ATAK_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_ATAK_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/cannedmessages.pb.cpp b/src/mesh/generated/meshtastic/cannedmessages.pb.cpp index 9f51e9634d9..1f4ebc9271e 100644 --- a/src/mesh/generated/meshtastic/cannedmessages.pb.cpp +++ b/src/mesh/generated/meshtastic/cannedmessages.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/cannedmessages.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/cannedmessages.pb.h b/src/mesh/generated/meshtastic/cannedmessages.pb.h index 06d14b98f42..8343c4d6ebf 100644 --- a/src/mesh/generated/meshtastic/cannedmessages.pb.h +++ b/src/mesh/generated/meshtastic/cannedmessages.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_CANNEDMESSAGES_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_CANNEDMESSAGES_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/channel.pb.cpp b/src/mesh/generated/meshtastic/channel.pb.cpp index 52f923b1352..6670a40fc12 100644 --- a/src/mesh/generated/meshtastic/channel.pb.cpp +++ b/src/mesh/generated/meshtastic/channel.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/channel.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/channel.pb.h b/src/mesh/generated/meshtastic/channel.pb.h index d03a8cec9ca..9dc757ab4a5 100644 --- a/src/mesh/generated/meshtastic/channel.pb.h +++ b/src/mesh/generated/meshtastic/channel.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/clientonly.pb.cpp b/src/mesh/generated/meshtastic/clientonly.pb.cpp index d99af8cf5d2..8f380a9720f 100644 --- a/src/mesh/generated/meshtastic/clientonly.pb.cpp +++ b/src/mesh/generated/meshtastic/clientonly.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/clientonly.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/clientonly.pb.h b/src/mesh/generated/meshtastic/clientonly.pb.h index a7f7817b456..9375d9f4690 100644 --- a/src/mesh/generated/meshtastic/clientonly.pb.h +++ b/src/mesh/generated/meshtastic/clientonly.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/config.pb.cpp b/src/mesh/generated/meshtastic/config.pb.cpp index 3f23bf8565a..c554ca43ce9 100644 --- a/src/mesh/generated/meshtastic/config.pb.cpp +++ b/src/mesh/generated/meshtastic/config.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/config.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index f1505b8fbe1..1f49ef9f373 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/connection_status.pb.cpp b/src/mesh/generated/meshtastic/connection_status.pb.cpp index d1495bb8324..b0df459ad3a 100644 --- a/src/mesh/generated/meshtastic/connection_status.pb.cpp +++ b/src/mesh/generated/meshtastic/connection_status.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/connection_status.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/connection_status.pb.h b/src/mesh/generated/meshtastic/connection_status.pb.h index c433e370b1c..55559dcefb4 100644 --- a/src/mesh/generated/meshtastic/connection_status.pb.h +++ b/src/mesh/generated/meshtastic/connection_status.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_CONNECTION_STATUS_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_CONNECTION_STATUS_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/device_ui.pb.cpp b/src/mesh/generated/meshtastic/device_ui.pb.cpp index b5a37408fb8..01940265f95 100644 --- a/src/mesh/generated/meshtastic/device_ui.pb.cpp +++ b/src/mesh/generated/meshtastic/device_ui.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/device_ui.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/device_ui.pb.h b/src/mesh/generated/meshtastic/device_ui.pb.h index d23675090f2..b99fb10b93b 100644 --- a/src/mesh/generated/meshtastic/device_ui.pb.h +++ b/src/mesh/generated/meshtastic/device_ui.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.cpp b/src/mesh/generated/meshtastic/deviceonly.pb.cpp index 1a601fe9f49..5580866379a 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.cpp +++ b/src/mesh/generated/meshtastic/deviceonly.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/deviceonly.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index db29644ce83..474b332a8da 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/deviceonly_legacy.pb.cpp b/src/mesh/generated/meshtastic/deviceonly_legacy.pb.cpp index 88e1535981c..04c3a98d94d 100644 --- a/src/mesh/generated/meshtastic/deviceonly_legacy.pb.cpp +++ b/src/mesh/generated/meshtastic/deviceonly_legacy.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/deviceonly_legacy.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/deviceonly_legacy.pb.h b/src/mesh/generated/meshtastic/deviceonly_legacy.pb.h index 60fca4eb6a1..6beee080923 100644 --- a/src/mesh/generated/meshtastic/deviceonly_legacy.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly_legacy.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_DEVICEONLY_LEGACY_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_DEVICEONLY_LEGACY_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/interdevice.pb.cpp b/src/mesh/generated/meshtastic/interdevice.pb.cpp index 7ed583cc6a1..e3913f78c9d 100644 --- a/src/mesh/generated/meshtastic/interdevice.pb.cpp +++ b/src/mesh/generated/meshtastic/interdevice.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/interdevice.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/interdevice.pb.h b/src/mesh/generated/meshtastic/interdevice.pb.h index 8bc22a1f4ba..c381438ebe6 100644 --- a/src/mesh/generated/meshtastic/interdevice.pb.h +++ b/src/mesh/generated/meshtastic/interdevice.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_INTERDEVICE_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_INTERDEVICE_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/localonly.pb.cpp b/src/mesh/generated/meshtastic/localonly.pb.cpp index 0a752a5a80a..34391df73e1 100644 --- a/src/mesh/generated/meshtastic/localonly.pb.cpp +++ b/src/mesh/generated/meshtastic/localonly.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/localonly.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h index 1863cef73a4..27f5ad7bfdf 100644 --- a/src/mesh/generated/meshtastic/localonly.pb.h +++ b/src/mesh/generated/meshtastic/localonly.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/module_config.pb.cpp b/src/mesh/generated/meshtastic/module_config.pb.cpp index 7543cca0fc8..f2fe5d967f9 100644 --- a/src/mesh/generated/meshtastic/module_config.pb.cpp +++ b/src/mesh/generated/meshtastic/module_config.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/module_config.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h index e929ab6b93f..25937e9720d 100644 --- a/src/mesh/generated/meshtastic/module_config.pb.h +++ b/src/mesh/generated/meshtastic/module_config.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_MODULE_CONFIG_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_MODULE_CONFIG_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/mqtt.pb.cpp b/src/mesh/generated/meshtastic/mqtt.pb.cpp index 74536cb79d1..2c32ef2e47e 100644 --- a/src/mesh/generated/meshtastic/mqtt.pb.cpp +++ b/src/mesh/generated/meshtastic/mqtt.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/mqtt.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/mqtt.pb.h b/src/mesh/generated/meshtastic/mqtt.pb.h index f1692afd776..5249c098bde 100644 --- a/src/mesh/generated/meshtastic/mqtt.pb.h +++ b/src/mesh/generated/meshtastic/mqtt.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/paxcount.pb.cpp b/src/mesh/generated/meshtastic/paxcount.pb.cpp index 40328814711..ff738bde906 100644 --- a/src/mesh/generated/meshtastic/paxcount.pb.cpp +++ b/src/mesh/generated/meshtastic/paxcount.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/paxcount.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/paxcount.pb.h b/src/mesh/generated/meshtastic/paxcount.pb.h index b6b51fdd5e9..06078aef795 100644 --- a/src/mesh/generated/meshtastic/paxcount.pb.h +++ b/src/mesh/generated/meshtastic/paxcount.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_PAXCOUNT_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_PAXCOUNT_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/portnums.pb.cpp b/src/mesh/generated/meshtastic/portnums.pb.cpp index 8fca9af793e..15a6ba372f0 100644 --- a/src/mesh/generated/meshtastic/portnums.pb.cpp +++ b/src/mesh/generated/meshtastic/portnums.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/portnums.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/portnums.pb.h b/src/mesh/generated/meshtastic/portnums.pb.h index 6a4527b70e3..494ef4a5497 100644 --- a/src/mesh/generated/meshtastic/portnums.pb.h +++ b/src/mesh/generated/meshtastic/portnums.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_PORTNUMS_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_PORTNUMS_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/powermon.pb.cpp b/src/mesh/generated/meshtastic/powermon.pb.cpp index 6a9b7551ada..8838e165fc0 100644 --- a/src/mesh/generated/meshtastic/powermon.pb.cpp +++ b/src/mesh/generated/meshtastic/powermon.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/powermon.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/powermon.pb.h b/src/mesh/generated/meshtastic/powermon.pb.h index a1c145f230a..3072b8ac55f 100644 --- a/src/mesh/generated/meshtastic/powermon.pb.h +++ b/src/mesh/generated/meshtastic/powermon.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_POWERMON_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_POWERMON_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/remote_hardware.pb.cpp b/src/mesh/generated/meshtastic/remote_hardware.pb.cpp index 239950e7ef3..8942104b5ac 100644 --- a/src/mesh/generated/meshtastic/remote_hardware.pb.cpp +++ b/src/mesh/generated/meshtastic/remote_hardware.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/remote_hardware.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/remote_hardware.pb.h b/src/mesh/generated/meshtastic/remote_hardware.pb.h index ade250e932d..9ab3413c3fd 100644 --- a/src/mesh/generated/meshtastic/remote_hardware.pb.h +++ b/src/mesh/generated/meshtastic/remote_hardware.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_REMOTE_HARDWARE_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_REMOTE_HARDWARE_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/rtttl.pb.cpp b/src/mesh/generated/meshtastic/rtttl.pb.cpp index 61ad8b73f64..c994741f34a 100644 --- a/src/mesh/generated/meshtastic/rtttl.pb.cpp +++ b/src/mesh/generated/meshtastic/rtttl.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/rtttl.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/rtttl.pb.h b/src/mesh/generated/meshtastic/rtttl.pb.h index 0572265f7a3..b6e152dbf88 100644 --- a/src/mesh/generated/meshtastic/rtttl.pb.h +++ b/src/mesh/generated/meshtastic/rtttl.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_RTTTL_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_RTTTL_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/serial_hal.pb.cpp b/src/mesh/generated/meshtastic/serial_hal.pb.cpp index 24834817bf1..183bc48f6e4 100644 --- a/src/mesh/generated/meshtastic/serial_hal.pb.cpp +++ b/src/mesh/generated/meshtastic/serial_hal.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/serial_hal.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/serial_hal.pb.h b/src/mesh/generated/meshtastic/serial_hal.pb.h index 39f834ba453..5dfcdf1ca1a 100644 --- a/src/mesh/generated/meshtastic/serial_hal.pb.h +++ b/src/mesh/generated/meshtastic/serial_hal.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_SERIAL_HAL_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_SERIAL_HAL_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/storeforward.pb.cpp b/src/mesh/generated/meshtastic/storeforward.pb.cpp index 71a232bf613..82db566a190 100644 --- a/src/mesh/generated/meshtastic/storeforward.pb.cpp +++ b/src/mesh/generated/meshtastic/storeforward.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/storeforward.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/storeforward.pb.h b/src/mesh/generated/meshtastic/storeforward.pb.h index 44ffd098c7d..75cff52058b 100644 --- a/src/mesh/generated/meshtastic/storeforward.pb.h +++ b/src/mesh/generated/meshtastic/storeforward.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_STOREFORWARD_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_STOREFORWARD_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/telemetry.pb.cpp b/src/mesh/generated/meshtastic/telemetry.pb.cpp index 7a8c6c9098e..bc21b9dcbea 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.cpp +++ b/src/mesh/generated/meshtastic/telemetry.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/telemetry.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h index 57da2a5b807..e8d337049df 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.h +++ b/src/mesh/generated/meshtastic/telemetry.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_INCLUDED diff --git a/src/mesh/generated/meshtastic/xmodem.pb.cpp b/src/mesh/generated/meshtastic/xmodem.pb.cpp index 3960ccdaa03..09ae41d35b0 100644 --- a/src/mesh/generated/meshtastic/xmodem.pb.cpp +++ b/src/mesh/generated/meshtastic/xmodem.pb.cpp @@ -1,5 +1,5 @@ /* Automatically generated nanopb constant definitions */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #include "meshtastic/xmodem.pb.h" #if PB_PROTO_HEADER_VERSION != 40 diff --git a/src/mesh/generated/meshtastic/xmodem.pb.h b/src/mesh/generated/meshtastic/xmodem.pb.h index 76edc0df654..3410fda0f4b 100644 --- a/src/mesh/generated/meshtastic/xmodem.pb.h +++ b/src/mesh/generated/meshtastic/xmodem.pb.h @@ -1,5 +1,5 @@ /* Automatically generated nanopb header */ -/* Generated by nanopb-0.4.9 */ +/* Generated by nanopb-0.4.9.1 */ #ifndef PB_MESHTASTIC_MESHTASTIC_XMODEM_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_XMODEM_PB_H_INCLUDED From 913a9164a78a153303a2990db78fe174a642d197 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:52:48 -0700 Subject: [PATCH 08/14] fix: avoid dropping config writes during sync --- src/mesh/PhoneAPI.cpp | 79 ------------------------------------------- 1 file changed, 79 deletions(-) diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 51142fd3699..5ee553bdc17 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -43,74 +43,6 @@ // Flag to indicate a heartbeat was received and we should send queue status bool heartbeatReceived = false; -static bool readProtoVarint(const uint8_t *bytes, size_t size, size_t &pos, uint64_t &value) -{ - value = 0; - unsigned shift = 0; - - while (pos < size && shift < 64) { - uint8_t byte = bytes[pos++]; - value |= static_cast(byte & 0x7f) << shift; - if ((byte & 0x80) == 0) { - return true; - } - shift += 7; - } - - return false; -} - -static bool skipProtoField(const uint8_t *bytes, size_t size, size_t &pos, uint8_t wireType) -{ - uint64_t length = 0; - - switch (wireType) { - case 0: - return readProtoVarint(bytes, size, pos, length); - case 1: - if (size - pos < 8) { - return false; - } - pos += 8; - return true; - case 2: - if (!readProtoVarint(bytes, size, pos, length) || length > size - pos) { - return false; - } - pos += static_cast(length); - return true; - case 5: - if (size - pos < 4) { - return false; - } - pos += 4; - return true; - default: - return false; - } -} - -static bool adminPayloadHasTopLevelField(const uint8_t *bytes, size_t size, pb_size_t fieldNumber) -{ - size_t pos = 0; - while (pos < size) { - uint64_t key = 0; - if (!readProtoVarint(bytes, size, pos, key)) { - return false; - } - - if ((key >> 3) == fieldNumber) { - return true; - } - - if (!skipProtoField(bytes, size, pos, key & 0x07)) { - return false; - } - } - - return false; -} - #ifdef MESHTASTIC_PHONEAPI_ACCESS_CONTROL // Auth-slot table and status-slot table are both sized to the typical // SerialConsole + BluetoothPhoneAPI footprint plus room for WiFi/TCP @@ -1700,17 +1632,6 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p) { printPacket("PACKET FROM PHONE", &p); - NodeNum localNodeNum = nodeDB->getNodeNum(); - bool isLocalAdmin = (p.from == 0 || p.from == localNodeNum) && p.which_payload_variant == meshtastic_MeshPacket_decoded_tag && - p.decoded.portnum == meshtastic_PortNum_ADMIN_APP && p.to == localNodeNum; - if (state != STATE_SEND_PACKETS && isLocalAdmin) { - if (adminPayloadHasTopLevelField(p.decoded.payload.bytes, p.decoded.payload.size, - meshtastic_AdminMessage_set_config_tag)) { - LOG_WARN("Ignoring set_config while completing config handshake (state=%d)", state); - return false; - } - } - #if defined(MESHTASTIC_ENCRYPTED_STORAGE) && defined(MESHTASTIC_PHONEAPI_ACCESS_CONTROL) // Local admin gating happens here, synchronously on the dispatching // task. Two distinct cases: From 407a37eb3189f831666385036b9725b459906b94 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:53:33 -0700 Subject: [PATCH 09/14] fix: limit T1000-E QMA I2C probe override --- src/detect/ScanI2CTwoWire.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index a2049c57079..2cf5dd700fd 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -299,6 +299,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) for (addr.address = 8; addr.address < 120; addr.address++) { #if defined(TRACKER_T1000_E) && defined(HAS_QMA6100P) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) bool t1000QmaFound = false; + bool useRegularProbe = true; #endif if (asize != 0) { if (!in_array(address, asize, (uint8_t)addr.address)) @@ -306,24 +307,29 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) LOG_DEBUG("Scan address 0x%x", (uint8_t)addr.address); } #if defined(TRACKER_T1000_E) && defined(HAS_QMA6100P) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) - t1000QmaFound = - (addr.address == QMA6100P_ADDRESS_LOW || addr.address == QMA6100P_ADDRESS_HIGH) && t1000ProbeQMA6100P(addr.address); - err = t1000QmaFound ? 0 : 2; -#else - i2cBus->beginTransmission(addr.address); -#ifdef ARCH_PORTDUINO - err = 2; - if ((addr.address >= 0x30 && addr.address <= 0x37) || (addr.address >= 0x50 && addr.address <= 0x5F)) { - if (i2cBus->read() != -1) - err = 0; - } else { - err = i2cBus->writeQuick((uint8_t)0); + if (addr.address == QMA6100P_ADDRESS_LOW || addr.address == QMA6100P_ADDRESS_HIGH) { + t1000QmaFound = t1000ProbeQMA6100P(addr.address); + err = t1000QmaFound ? 0 : 2; + useRegularProbe = false; } - if (err != 0) + if (useRegularProbe) { +#endif + i2cBus->beginTransmission(addr.address); +#ifdef ARCH_PORTDUINO err = 2; + if ((addr.address >= 0x30 && addr.address <= 0x37) || (addr.address >= 0x50 && addr.address <= 0x5F)) { + if (i2cBus->read() != -1) + err = 0; + } else { + err = i2cBus->writeQuick((uint8_t)0); + } + if (err != 0) + err = 2; #else err = i2cBus->endTransmission(); #endif +#if defined(TRACKER_T1000_E) && defined(HAS_QMA6100P) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) + } #endif type = NONE; if (err == 0) { From 8d47689690ea4dcef4c394063621483b9dd47810 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:55:03 -0700 Subject: [PATCH 10/14] fix: include config for motion compass orientation --- src/motion/MotionSensor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/motion/MotionSensor.cpp b/src/motion/MotionSensor.cpp index 878b4dd5088..bee317b03aa 100755 --- a/src/motion/MotionSensor.cpp +++ b/src/motion/MotionSensor.cpp @@ -3,6 +3,7 @@ #include "SPILock.h" #include "SafeFile.h" #include "concurrency/LockGuard.h" +#include "configuration.h" #include "graphics/draw/CompassRenderer.h" #if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C From 93a2b6d8e958d6d2047800ff1e0b6c572df76711 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:59:55 -0700 Subject: [PATCH 11/14] fix: include NodeDB for motion config access --- src/motion/MotionSensor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/motion/MotionSensor.cpp b/src/motion/MotionSensor.cpp index bee317b03aa..6342cd2c8eb 100755 --- a/src/motion/MotionSensor.cpp +++ b/src/motion/MotionSensor.cpp @@ -3,8 +3,8 @@ #include "SPILock.h" #include "SafeFile.h" #include "concurrency/LockGuard.h" -#include "configuration.h" #include "graphics/draw/CompassRenderer.h" +#include "mesh/NodeDB.h" #if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C From 2ca76e9c08ba2cf931d35f91b92a8cc96fa0216c Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sat, 20 Jun 2026 16:46:34 -0700 Subject: [PATCH 12/14] chore: remove duplicated T1000-E I2C fixes --- src/detect/ScanI2CTwoWire.cpp | 66 +------ src/motion/MotionSensor.cpp | 1 - src/motion/QMA6100PSensor.cpp | 91 --------- src/platform/nrf52/T1000EI2C.cpp | 174 ------------------ src/platform/nrf52/T1000EI2C.h | 16 -- .../nrf52840/tracker-t1000-e/platformio.ini | 4 - 6 files changed, 10 insertions(+), 342 deletions(-) delete mode 100644 src/platform/nrf52/T1000EI2C.cpp delete mode 100644 src/platform/nrf52/T1000EI2C.h diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 2cf5dd700fd..a37c2873353 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -11,27 +11,6 @@ #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32) #include "meshUtils.h" // vformat #endif -#if defined(TRACKER_T1000_E) && defined(HAS_QMA6100P) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) -#include "platform/nrf52/T1000EI2C.h" -#include -#endif - -#if defined(TRACKER_T1000_E) && defined(HAS_QMA6100P) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) -namespace -{ -bool t1000ProbeQMA6100P(uint8_t address) -{ - uint8_t chipID = 0; - - T1000EI2C::restoreBus(); - const bool readOk = T1000EI2C::readRegister(address, SFE_QMA6100P_CHIP_ID, chipID); - bool found = readOk && chipID == QMA6100P_CHIP_ID; - T1000EI2C::restoreBus(); - - return found; -} -} // namespace -#endif bool in_array(uint8_t *array, int size, uint8_t lookfor) { @@ -297,39 +276,24 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) // 0x7C-0x7F Reserved for future purposes for (addr.address = 8; addr.address < 120; addr.address++) { -#if defined(TRACKER_T1000_E) && defined(HAS_QMA6100P) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) - bool t1000QmaFound = false; - bool useRegularProbe = true; -#endif if (asize != 0) { if (!in_array(address, asize, (uint8_t)addr.address)) continue; LOG_DEBUG("Scan address 0x%x", (uint8_t)addr.address); } -#if defined(TRACKER_T1000_E) && defined(HAS_QMA6100P) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) - if (addr.address == QMA6100P_ADDRESS_LOW || addr.address == QMA6100P_ADDRESS_HIGH) { - t1000QmaFound = t1000ProbeQMA6100P(addr.address); - err = t1000QmaFound ? 0 : 2; - useRegularProbe = false; - } - if (useRegularProbe) { -#endif - i2cBus->beginTransmission(addr.address); + i2cBus->beginTransmission(addr.address); #ifdef ARCH_PORTDUINO + err = 2; + if ((addr.address >= 0x30 && addr.address <= 0x37) || (addr.address >= 0x50 && addr.address <= 0x5F)) { + if (i2cBus->read() != -1) + err = 0; + } else { + err = i2cBus->writeQuick((uint8_t)0); + } + if (err != 0) err = 2; - if ((addr.address >= 0x30 && addr.address <= 0x37) || (addr.address >= 0x50 && addr.address <= 0x5F)) { - if (i2cBus->read() != -1) - err = 0; - } else { - err = i2cBus->writeQuick((uint8_t)0); - } - if (err != 0) - err = 2; #else err = i2cBus->endTransmission(); -#endif -#if defined(TRACKER_T1000_E) && defined(HAS_QMA6100P) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) - } #endif type = NONE; if (err == 0) { @@ -785,17 +749,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) } break; } - case BMM150_ADDR: -#if defined(TRACKER_T1000_E) && defined(HAS_QMA6100P) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) - if (t1000QmaFound) { - logFoundDevice("QMA6100P", (uint8_t)addr.address); - type = QMA6100P; - break; - } -#endif - logFoundDevice("BMM150", (uint8_t)addr.address); - type = BMM150; - break; + SCAN_SIMPLE_CASE(BMM150_ADDR, BMM150, "BMM150", (uint8_t)addr.address); #ifdef HAS_TPS65233 SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233", (uint8_t)addr.address); #endif diff --git a/src/motion/MotionSensor.cpp b/src/motion/MotionSensor.cpp index 6342cd2c8eb..878b4dd5088 100755 --- a/src/motion/MotionSensor.cpp +++ b/src/motion/MotionSensor.cpp @@ -4,7 +4,6 @@ #include "SafeFile.h" #include "concurrency/LockGuard.h" #include "graphics/draw/CompassRenderer.h" -#include "mesh/NodeDB.h" #if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C diff --git a/src/motion/QMA6100PSensor.cpp b/src/motion/QMA6100PSensor.cpp index c7ab1971815..a04837e8028 100644 --- a/src/motion/QMA6100PSensor.cpp +++ b/src/motion/QMA6100PSensor.cpp @@ -2,77 +2,9 @@ #if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && defined(HAS_QMA6100P) -#if defined(TRACKER_T1000_E) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) -#include "platform/nrf52/T1000EI2C.h" -#endif - // Flag when an interrupt has been detected volatile static bool QMA6100P_IRQ = false; -#if defined(TRACKER_T1000_E) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) -namespace -{ -bool qma6100pUpdateRegister(uint8_t address, uint8_t reg, uint8_t (*mutate)(uint8_t)) -{ - uint8_t value = 0; - return T1000EI2C::readRegister(address, reg, value) && T1000EI2C::writeRegister(address, reg, mutate(value)); -} - -uint8_t qma6100pSetRange(uint8_t value) -{ - sfe_qma6100p_fsr_bitfield_t fsr; - fsr.all = value; - fsr.bits.range = QMA_6100P_MPU_ACCEL_SCALE; - return fsr.all; -} - -uint8_t qma6100pEnableAccel(uint8_t value) -{ - sfe_qma6100p_pm_bitfield_t pm; - pm.all = value; - pm.bits.mode_bit = 1; - return pm.all; -} - -uint8_t qma6100pConfigureIntPin(uint8_t value) -{ - return value | 0b00000010; -} - -uint8_t qma6100pConfigureIntLatch(uint8_t value) -{ - return value | 0b10000001; -} - -uint8_t qma6100pMapAnyMotionToInt1(uint8_t value) -{ - sfe_qma6100p_int_map1_bitfield_t intMap1; - intMap1.all = value; - intMap1.bits.int1_any_mot = 1; - return intMap1.all; -} - -bool qma6100pInitBounded(uint8_t address) -{ - uint8_t chipID = 0; - - T1000EI2C::restoreBus(); - const bool ok = T1000EI2C::readRegister(address, SFE_QMA6100P_CHIP_ID, chipID) && chipID == QMA6100P_CHIP_ID && - T1000EI2C::writeRegister(address, SFE_QMA6100P_SR, 0xb6) && - T1000EI2C::writeRegister(address, SFE_QMA6100P_SR, 0) && - qma6100pUpdateRegister(address, SFE_QMA6100P_FSR, qma6100pSetRange) && - qma6100pUpdateRegister(address, SFE_QMA6100P_PM, qma6100pEnableAccel) && - T1000EI2C::writeRegister(address, SFE_QMA6100P_INT_EN2, 0b00000111) && - qma6100pUpdateRegister(address, SFE_QMA6100P_INT_MAP1, qma6100pMapAnyMotionToInt1) && - qma6100pUpdateRegister(address, SFE_QMA6100P_INTPINT_CONF, qma6100pConfigureIntPin) && - qma6100pUpdateRegister(address, SFE_QMA6100P_INT_CFG, qma6100pConfigureIntLatch); - T1000EI2C::restoreBus(); - - return ok; -} -} // namespace -#endif - // Interrupt service routine void QMA6100PSetInterrupt() { @@ -83,20 +15,6 @@ QMA6100PSensor::QMA6100PSensor(ScanI2C::FoundDevice foundDevice) : MotionSensor: bool QMA6100PSensor::init() { -#if defined(TRACKER_T1000_E) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) - if (!qma6100pInitBounded(device.address.address)) { - LOG_WARN("QMA6100P init failed"); - return false; - } - QMA6100P_IRQ = false; - -#ifdef QMA_6100P_INT_PIN - pinMode(QMA_6100P_INT_PIN, INPUT_PULLUP); - attachInterrupt(QMA_6100P_INT_PIN, QMA6100PSetInterrupt, FALLING); -#endif - - return true; -#else // Initialise the sensor sensor = QMA6100PSingleton::GetInstance(); if (!sensor->init(device)) @@ -104,7 +22,6 @@ bool QMA6100PSensor::init() // Enable simple Wake on Motion return sensor->setWakeOnMotion(); -#endif } #ifdef QMA_6100P_INT_PIN @@ -123,13 +40,6 @@ int32_t QMA6100PSensor::runOnce() int32_t QMA6100PSensor::runOnce() { -#if defined(TRACKER_T1000_E) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) - uint8_t tempVal = 0; - if (!T1000EI2C::readRegister(device.address.address, SFE_QMA6100P_INT_ST0, tempVal)) { - LOG_DEBUG("QMA6100PS isWakeOnMotion failed to read interrupts"); - return MOTION_SENSOR_CHECK_INTERVAL_MS; - } -#else // Wake on motion using polling - this is not as efficient as using hardware interrupt pin (see above) uint8_t tempVal; @@ -137,7 +47,6 @@ int32_t QMA6100PSensor::runOnce() LOG_DEBUG("QMA6100PS isWakeOnMotion failed to read interrupts"); return MOTION_SENSOR_CHECK_INTERVAL_MS; } -#endif if ((tempVal & 7) != 0) { // Wake up! diff --git a/src/platform/nrf52/T1000EI2C.cpp b/src/platform/nrf52/T1000EI2C.cpp deleted file mode 100644 index d379469eba8..00000000000 --- a/src/platform/nrf52/T1000EI2C.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include "T1000EI2C.h" - -#if !MESHTASTIC_EXCLUDE_I2C && defined(TRACKER_T1000_E) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) - -#include -#include - -namespace -{ -constexpr uint32_t i2cTimeoutUs = 5000; - -void stopTwim(NRF_TWIM_Type *twim); - -bool waitForEventOrError(volatile uint32_t &event, NRF_TWIM_Type *twim) -{ - const uint32_t start = micros(); - while (!event && !twim->EVENTS_ERROR) { - if ((uint32_t)(micros() - start) >= i2cTimeoutUs) { - stopTwim(twim); - return false; - } - } - - return event && !twim->EVENTS_ERROR; -} - -void configureTwim(NRF_TWIM_Type *twim) -{ - twim->ENABLE = TWIM_ENABLE_ENABLE_Disabled; - twim->PSEL.SCL = PIN_WIRE_SCL; - twim->PSEL.SDA = PIN_WIRE_SDA; - twim->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K100; - twim->ENABLE = TWIM_ENABLE_ENABLE_Enabled; -} - -void clearTwimEvents(NRF_TWIM_Type *twim) -{ - twim->SHORTS = 0; - twim->EVENTS_STOPPED = 0; - twim->EVENTS_ERROR = 0; - twim->EVENTS_SUSPENDED = 0; - twim->EVENTS_RXSTARTED = 0; - twim->EVENTS_TXSTARTED = 0; - twim->EVENTS_LASTRX = 0; - twim->EVENTS_LASTTX = 0; - twim->ERRORSRC = TWIM_ERRORSRC_ANACK_Msk | TWIM_ERRORSRC_DNACK_Msk | TWIM_ERRORSRC_OVERRUN_Msk; -} - -void stopTwim(NRF_TWIM_Type *twim) -{ - twim->TASKS_STOP = 1; - - const uint32_t start = micros(); - while (!twim->EVENTS_STOPPED && (uint32_t)(micros() - start) < i2cTimeoutUs) - ; - - clearTwimEvents(twim); -} - -bool waitForStop(NRF_TWIM_Type *twim) -{ - const uint32_t start = micros(); - while (!twim->EVENTS_STOPPED && !twim->EVENTS_ERROR) { - if ((uint32_t)(micros() - start) >= i2cTimeoutUs) { - stopTwim(twim); - return false; - } - } - - const bool ok = twim->EVENTS_STOPPED && !twim->EVENTS_ERROR; - if (!ok) - stopTwim(twim); - else - clearTwimEvents(twim); - - return ok; -} -} // namespace - -namespace T1000EI2C -{ -void restoreBus() -{ - pinMode(PIN_3V3_EN, OUTPUT); - digitalWrite(PIN_3V3_EN, HIGH); - pinMode(PIN_3V3_ACC_EN, OUTPUT); - digitalWrite(PIN_3V3_ACC_EN, HIGH); -#ifdef T1000X_SENSOR_EN_PIN - pinMode(T1000X_SENSOR_EN_PIN, OUTPUT); - digitalWrite(T1000X_SENSOR_EN_PIN, HIGH); -#endif - delay(20); - - Wire.end(); - - pinMode(PIN_WIRE_SCL, INPUT_PULLUP); - pinMode(PIN_WIRE_SDA, INPUT_PULLUP); - delayMicroseconds(10); - - for (uint8_t i = 0; i < 9 && digitalRead(PIN_WIRE_SDA) == LOW; i++) { - pinMode(PIN_WIRE_SCL, OUTPUT); - digitalWrite(PIN_WIRE_SCL, LOW); - delayMicroseconds(5); - pinMode(PIN_WIRE_SCL, INPUT_PULLUP); - delayMicroseconds(5); - } - - pinMode(PIN_WIRE_SDA, OUTPUT); - digitalWrite(PIN_WIRE_SDA, LOW); - delayMicroseconds(5); - pinMode(PIN_WIRE_SCL, INPUT_PULLUP); - delayMicroseconds(5); - pinMode(PIN_WIRE_SDA, INPUT_PULLUP); - delayMicroseconds(5); - - Wire.begin(); -} - -bool readRegister(uint8_t address, uint8_t reg, uint8_t &value) -{ - NRF_TWIM_Type *twim = NRF_TWIM0; - - configureTwim(twim); - clearTwimEvents(twim); - twim->ADDRESS = address; - twim->TXD.PTR = (uint32_t)® - twim->TXD.MAXCNT = 1; - twim->TASKS_RESUME = 1; - twim->TASKS_STARTTX = 1; - - if (!waitForEventOrError(twim->EVENTS_LASTTX, twim)) { - stopTwim(twim); - return false; - } - - twim->EVENTS_LASTTX = 0; - twim->EVENTS_SUSPENDED = 0; - twim->TASKS_SUSPEND = 1; - - if (!waitForEventOrError(twim->EVENTS_SUSPENDED, twim)) { - stopTwim(twim); - return false; - } - - twim->EVENTS_SUSPENDED = 0; - twim->EVENTS_LASTRX = 0; - twim->RXD.PTR = (uint32_t)&value; - twim->RXD.MAXCNT = 1; - twim->SHORTS = TWIM_SHORTS_LASTRX_STOP_Msk; - twim->TASKS_RESUME = 1; - twim->TASKS_STARTRX = 1; - - return waitForStop(twim) && twim->RXD.AMOUNT == 1; -} - -bool writeRegister(uint8_t address, uint8_t reg, uint8_t value) -{ - NRF_TWIM_Type *twim = NRF_TWIM0; - uint8_t data[] = {reg, value}; - - configureTwim(twim); - clearTwimEvents(twim); - twim->ADDRESS = address; - twim->TXD.PTR = (uint32_t)data; - twim->TXD.MAXCNT = sizeof(data); - twim->SHORTS = TWIM_SHORTS_LASTTX_STOP_Msk; - twim->TASKS_RESUME = 1; - twim->TASKS_STARTTX = 1; - - return waitForStop(twim); -} -} // namespace T1000EI2C - -#endif diff --git a/src/platform/nrf52/T1000EI2C.h b/src/platform/nrf52/T1000EI2C.h deleted file mode 100644 index e16e325200a..00000000000 --- a/src/platform/nrf52/T1000EI2C.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "configuration.h" - -#if !MESHTASTIC_EXCLUDE_I2C && defined(TRACKER_T1000_E) && (defined(ARCH_NRF52) || defined(NRF52_SERIES) || defined(NRF52)) - -#include - -namespace T1000EI2C -{ -void restoreBus(); -bool readRegister(uint8_t address, uint8_t reg, uint8_t &value); -bool writeRegister(uint8_t address, uint8_t reg, uint8_t value); -} // namespace T1000EI2C - -#endif diff --git a/variants/nrf52840/tracker-t1000-e/platformio.ini b/variants/nrf52840/tracker-t1000-e/platformio.ini index 5429744b322..43ba7a8b46b 100644 --- a/variants/nrf52840/tracker-t1000-e/platformio.ini +++ b/variants/nrf52840/tracker-t1000-e/platformio.ini @@ -16,11 +16,7 @@ build_flags = ${nrf52840_base.build_flags} -Isrc/platform/nrf52/softdevice -Isrc/platform/nrf52/softdevice/nrf52 -DTRACKER_T1000_E - -DMESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR=1 - -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR=1 -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL=1 - -DMESHTASTIC_EXCLUDE_HEALTH_TELEMETRY=1 - -DMESHTASTIC_EXCLUDE_POWER_TELEMETRY=1 -DMESHTASTIC_EXCLUDE_CANNEDMESSAGES=1 -DMESHTASTIC_EXCLUDE_SCREEN=1 -DMESHTASTIC_EXCLUDE_DETECTIONSENSOR=1 From 67b67973eac2aa647508d9d64a317ff4da5c4acc Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sat, 20 Jun 2026 16:47:00 -0700 Subject: [PATCH 13/14] chore: restore i2c scanner whitespace --- src/detect/ScanI2CTwoWire.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index a37c2873353..b8b6915c2a3 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -10,6 +10,7 @@ #endif #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32) #include "meshUtils.h" // vformat + #endif bool in_array(uint8_t *array, int size, uint8_t lookfor) From 1d27252e71ee82125bc4ece40ce0d99d214f35e2 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Tue, 23 Jun 2026 11:07:00 -0700 Subject: [PATCH 14/14] Default find node duration in firmware --- protobufs | 2 +- src/buzz/FindNodeBuzzer.cpp | 17 ++-------------- src/buzz/FindNodeBuzzer.h | 5 ++--- src/mesh/generated/meshtastic/admin.pb.h | 26 ++++++++---------------- src/modules/AdminModule.cpp | 7 ++----- 5 files changed, 16 insertions(+), 41 deletions(-) diff --git a/protobufs b/protobufs index 6566cd61812..dfcbebecd51 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 6566cd61812af44c5a3e77f01db8f72de0a1020a +Subproject commit dfcbebecd51fc9f668e89be77086a27b35cceb65 diff --git a/src/buzz/FindNodeBuzzer.cpp b/src/buzz/FindNodeBuzzer.cpp index 382dc85f9f9..66ec365c80c 100644 --- a/src/buzz/FindNodeBuzzer.cpp +++ b/src/buzz/FindNodeBuzzer.cpp @@ -15,12 +15,8 @@ FindNodeBuzzer *findNodeBuzzer; FindNodeBuzzer::FindNodeBuzzer() : concurrency::OSThread("FindNodeBuzzer", INT32_MAX) {} -FindNodeBuzzer::Result FindNodeBuzzer::start(uint32_t durationSeconds, uint32_t *acceptedDurationSeconds) +FindNodeBuzzer::Result FindNodeBuzzer::start() { - if (acceptedDurationSeconds) { - *acceptedDurationSeconds = 0; - } - if (!hasFindNodeBuzzer()) { return Result::NoBuzzer; } @@ -29,17 +25,8 @@ FindNodeBuzzer::Result FindNodeBuzzer::start(uint32_t durationSeconds, uint32_t return Result::BuzzerDisabled; } - if (durationSeconds == 0) { - durationSeconds = DEFAULT_DURATION_SECONDS; - } else if (durationSeconds > MAX_DURATION_SECONDS) { - durationSeconds = MAX_DURATION_SECONDS; - } - startMsec = millis(); - durationMsec = durationSeconds * 1000U; - if (acceptedDurationSeconds) { - *acceptedDurationSeconds = durationSeconds; - } + durationMsec = DEFAULT_DURATION_SECONDS * 1000U; if (!playFindNodeBuzzer()) { stop(); diff --git a/src/buzz/FindNodeBuzzer.h b/src/buzz/FindNodeBuzzer.h index 16fc80e6fb7..5d5ee0f288f 100644 --- a/src/buzz/FindNodeBuzzer.h +++ b/src/buzz/FindNodeBuzzer.h @@ -8,12 +8,11 @@ class FindNodeBuzzer : private concurrency::OSThread public: enum class Result : uint8_t { Started, Stopped, NoBuzzer, BuzzerDisabled }; - static constexpr uint32_t DEFAULT_DURATION_SECONDS = 30; - static constexpr uint32_t MAX_DURATION_SECONDS = 300; + static constexpr uint32_t DEFAULT_DURATION_SECONDS = 5 * 60; FindNodeBuzzer(); - Result start(uint32_t durationSeconds, uint32_t *acceptedDurationSeconds = nullptr); + Result start(); Result stop(); bool isActive() const; diff --git a/src/mesh/generated/meshtastic/admin.pb.h b/src/mesh/generated/meshtastic/admin.pb.h index 6495ef66cb2..5b3d9c63492 100644 --- a/src/mesh/generated/meshtastic/admin.pb.h +++ b/src/mesh/generated/meshtastic/admin.pb.h @@ -139,8 +139,6 @@ typedef struct _meshtastic_AdminMessage_OTAEvent { /* Request that the node emit an audible find-node pattern. */ typedef struct _meshtastic_AdminMessage_FindNodeRequest { - /* Duration to repeat the find-node pattern. Zero uses the firmware default. */ - uint16_t duration_seconds; /* Stop any active find-node pattern instead of starting a new one. */ bool stop; } meshtastic_AdminMessage_FindNodeRequest; @@ -149,8 +147,6 @@ typedef struct _meshtastic_AdminMessage_FindNodeRequest { typedef struct _meshtastic_AdminMessage_FindNodeResponse { /* Result of the request. */ meshtastic_AdminMessage_FindNodeResponse_Result result; - /* Accepted duration in seconds. Zero for stop or failed requests. */ - uint16_t duration_seconds; } meshtastic_AdminMessage_FindNodeResponse; typedef PB_BYTES_ARRAY_T(32) meshtastic_LockdownAuth_passphrase_t; @@ -580,8 +576,8 @@ extern "C" { #define meshtastic_AdminMessage_init_default {0, {0}, {0, {0}}} #define meshtastic_AdminMessage_InputEvent_init_default {0, 0, 0, 0} #define meshtastic_AdminMessage_OTAEvent_init_default {_meshtastic_OTAMode_MIN, {0, {0}}} -#define meshtastic_AdminMessage_FindNodeRequest_init_default {0, 0} -#define meshtastic_AdminMessage_FindNodeResponse_init_default {_meshtastic_AdminMessage_FindNodeResponse_Result_MIN, 0} +#define meshtastic_AdminMessage_FindNodeRequest_init_default {0} +#define meshtastic_AdminMessage_FindNodeResponse_init_default {_meshtastic_AdminMessage_FindNodeResponse_Result_MIN} #define meshtastic_LockdownAuth_init_default {{0, {0}}, 0, 0, 0, 0, 0} #define meshtastic_HamParameters_init_default {"", 0, 0, "", ""} #define meshtastic_NodeRemoteHardwarePinsResponse_init_default {0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}} @@ -595,8 +591,8 @@ extern "C" { #define meshtastic_AdminMessage_init_zero {0, {0}, {0, {0}}} #define meshtastic_AdminMessage_InputEvent_init_zero {0, 0, 0, 0} #define meshtastic_AdminMessage_OTAEvent_init_zero {_meshtastic_OTAMode_MIN, {0, {0}}} -#define meshtastic_AdminMessage_FindNodeRequest_init_zero {0, 0} -#define meshtastic_AdminMessage_FindNodeResponse_init_zero {_meshtastic_AdminMessage_FindNodeResponse_Result_MIN, 0} +#define meshtastic_AdminMessage_FindNodeRequest_init_zero {0} +#define meshtastic_AdminMessage_FindNodeResponse_init_zero {_meshtastic_AdminMessage_FindNodeResponse_Result_MIN} #define meshtastic_LockdownAuth_init_zero {{0, {0}}, 0, 0, 0, 0, 0} #define meshtastic_HamParameters_init_zero {"", 0, 0, "", ""} #define meshtastic_NodeRemoteHardwarePinsResponse_init_zero {0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}} @@ -615,10 +611,8 @@ extern "C" { #define meshtastic_AdminMessage_InputEvent_touch_y_tag 4 #define meshtastic_AdminMessage_OTAEvent_reboot_ota_mode_tag 1 #define meshtastic_AdminMessage_OTAEvent_ota_hash_tag 2 -#define meshtastic_AdminMessage_FindNodeRequest_duration_seconds_tag 1 -#define meshtastic_AdminMessage_FindNodeRequest_stop_tag 2 +#define meshtastic_AdminMessage_FindNodeRequest_stop_tag 1 #define meshtastic_AdminMessage_FindNodeResponse_result_tag 1 -#define meshtastic_AdminMessage_FindNodeResponse_duration_seconds_tag 2 #define meshtastic_LockdownAuth_passphrase_tag 1 #define meshtastic_LockdownAuth_boots_remaining_tag 2 #define meshtastic_LockdownAuth_valid_until_epoch_tag 3 @@ -825,14 +819,12 @@ X(a, STATIC, SINGULAR, BYTES, ota_hash, 2) #define meshtastic_AdminMessage_OTAEvent_DEFAULT NULL #define meshtastic_AdminMessage_FindNodeRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, duration_seconds, 1) \ -X(a, STATIC, SINGULAR, BOOL, stop, 2) +X(a, STATIC, SINGULAR, BOOL, stop, 1) #define meshtastic_AdminMessage_FindNodeRequest_CALLBACK NULL #define meshtastic_AdminMessage_FindNodeRequest_DEFAULT NULL #define meshtastic_AdminMessage_FindNodeResponse_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, result, 1) \ -X(a, STATIC, SINGULAR, UINT32, duration_seconds, 2) +X(a, STATIC, SINGULAR, UENUM, result, 1) #define meshtastic_AdminMessage_FindNodeResponse_CALLBACK NULL #define meshtastic_AdminMessage_FindNodeResponse_DEFAULT NULL @@ -957,8 +949,8 @@ extern const pb_msgdesc_t meshtastic_SHTXX_config_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_ADMIN_PB_H_MAX_SIZE meshtastic_AdminMessage_size -#define meshtastic_AdminMessage_FindNodeRequest_size 6 -#define meshtastic_AdminMessage_FindNodeResponse_size 6 +#define meshtastic_AdminMessage_FindNodeRequest_size 2 +#define meshtastic_AdminMessage_FindNodeResponse_size 2 #define meshtastic_AdminMessage_InputEvent_size 14 #define meshtastic_AdminMessage_OTAEvent_size 36 #define meshtastic_AdminMessage_size 511 diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index dc106721ad3..03eff265a1b 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -1482,18 +1482,15 @@ void AdminModule::handleFindNodeRequest(const meshtastic_MeshPacket &req, const meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default; r.which_payload_variant = meshtastic_AdminMessage_find_node_response_tag; - uint32_t acceptedDurationSeconds = 0; FindNodeBuzzer::Result result = FindNodeBuzzer::Result::NoBuzzer; if (findNodeBuzzer) { - result = - request.stop ? findNodeBuzzer->stop() : findNodeBuzzer->start(request.duration_seconds, &acceptedDurationSeconds); + result = request.stop ? findNodeBuzzer->stop() : findNodeBuzzer->start(); } switch (result) { case FindNodeBuzzer::Result::Started: r.find_node_response.result = meshtastic_AdminMessage_FindNodeResponse_Result_STARTED; - r.find_node_response.duration_seconds = acceptedDurationSeconds; - LOG_INFO("Find-node buzzer started for %u seconds", acceptedDurationSeconds); + LOG_INFO("Find-node buzzer started for %u seconds", FindNodeBuzzer::DEFAULT_DURATION_SECONDS); break; case FindNodeBuzzer::Result::Stopped: r.find_node_response.result = meshtastic_AdminMessage_FindNodeResponse_Result_STOPPED;