Add saved node and region discovery response switches

This commit is contained in:
mikecarper committed 2026-10-24 20:37:51 -07:00
1 parent 1ab4091a05
commit 4fd3358a45
15 files changed
+705 -5

No files matched your search

+17
View File
@@ -832,6 +832,7 @@ void CommonCLI::loadPrefs(FILESYSTEM* fs) {
#endif
_prefs->usb_debug_enabled = 0;
_prefs->trace_when_repeat_off = 0;
_prefs->discovery_responses = mesh::discovery::DEFAULT_RESPONSES;
_prefs->ota_channel = 0;
#ifdef WITH_RS232_BRIDGE
_prefs->rs232_heartbeat = 1;
@@ -1105,6 +1106,7 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
// from a previous load of a newer image.
_prefs->usb_debug_enabled = 0;
_prefs->trace_when_repeat_off = 0;
_prefs->discovery_responses = mesh::discovery::DEFAULT_RESPONSES;
_prefs->gps_sync_interval_hours = 0;
_prefs->ota_channel = 0;
_prefs->rs232_bridge_enabled = 0;
@@ -1809,6 +1811,9 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
ensureRxPowerSavingDefaults(&_prefs->rx_ps_rx_us, &_prefs->rx_ps_sleep_us);
recalculateRxPowerSavingFromLevel(_prefs); // retune supported level-based timings to loaded SF/BW
// Read reply controls independently of the current UART profile. Older
// images have no record and retain both replies enabled.
_prefs->discovery_responses = mesh::discovery::readPrefs(file);
// Read the footer independently of optional legacy UART tails/profile.
#if defined(RAK_4631)
_prefs->peripherals_shared = mesh::peripherals::readCommonMode(file);
@@ -1983,6 +1988,11 @@ static bool writeCommonPrefsImage(Writer& writer, NodePrefs* prefs) {
prefs->rs232_idle_seconds);
WRITE_COMMON_PREFS_BYTES(power_tail, sizeof(power_tail));
#endif
if (prefs->discovery_responses != mesh::discovery::DEFAULT_RESPONSES) {
uint8_t discovery_tail[mesh::discovery::PREFS_SIZE];
mesh::discovery::encodePrefs(discovery_tail, prefs->discovery_responses);
WRITE_COMMON_PREFS_BYTES(discovery_tail, sizeof(discovery_tail));
}
#if defined(RAK_4631)
uint8_t peripheral_footer[mesh::peripherals::FooterSize];
mesh::peripherals::encodeFooter(peripheral_footer, prefs->peripherals_shared);
@@ -2078,6 +2088,8 @@ void CommonCLI::savePrefs(FILESYSTEM* fs, PrefsSaveRouting::Scope scope) {
_common_save_succeeded = false;
_prefs->usb_debug_enabled = _prefs->usb_debug_enabled == 1 ? 1 : 0;
_prefs->trace_when_repeat_off = _prefs->trace_when_repeat_off == 1 ? 1 : 0;
if (_prefs->discovery_responses > mesh::discovery::DEFAULT_RESPONSES)
_prefs->discovery_responses = mesh::discovery::DEFAULT_RESPONSES;
#if defined(ESP32_PLATFORM)
if (!mesh::esp32::cpuclock::validSelection(_prefs->cpu_freq_mhz)
|| (_prefs->cpu_freq_mhz && !_board->supportsCpuFrequencyMHz(_prefs->cpu_freq_mhz)))
@@ -2234,6 +2246,11 @@ void CommonCLI::savePrefs(FILESYSTEM* fs, PrefsSaveRouting::Scope scope) {
_prefs->rs232_idle_seconds);
file.write(power_tail, sizeof(power_tail));
#endif
if (_prefs->discovery_responses != mesh::discovery::DEFAULT_RESPONSES) {
uint8_t discovery_tail[mesh::discovery::PREFS_SIZE];
mesh::discovery::encodePrefs(discovery_tail, _prefs->discovery_responses);
file.write(discovery_tail, sizeof(discovery_tail));
}
#if defined(RAK_4631)
uint8_t peripheral_footer[mesh::peripherals::FooterSize];
mesh::peripherals::encodeFooter(peripheral_footer, _prefs->peripherals_shared);
+5
View File
@@ -13,6 +13,7 @@
#include <helpers/CommonRadioPrefs.h>
#include <helpers/DynamicConfigSerializer.h>
#include <helpers/RepeaterRadioTiming.h>
#include <helpers/DiscoveryResponsePrefs.h>
#include <helpers/RadioProfileCLI.h>
#include <helpers/MorseReplyHandoff.h>
#include <helpers/WirelessControl.h>
@@ -203,6 +204,9 @@ public:
// Repeater-only opt-in for routed trace diagnostics while repeat is off.
// Appended after usb_debug in /com_prefs; existing images stay disabled.
uint8_t trace_when_repeat_off = 0;
// Independent repeater reply gates: bit 0=node, bit 1=anonymous regions.
// Stored in a checked extension before the platform-specific EOF footer.
uint8_t discovery_responses = 3;
// Runtime UART choice for merged RS-232 repeater artifacts. Appended at
// /com_prefs offset 862; single-UART builds keep their compiled port here.
uint8_t bridge_uart = 0;
@@ -472,6 +476,7 @@ protected:
def("lat", node_lat);
def("lon", node_lon);
def("disc_mod", discovery_mod_timestamp);
def("disc_responses", discovery_responses);
def("ota_ch", ota_channel); // WiFi OTA release channel selector
def("radio", radio);
def("bridge", bridge);
+69
View File
@@ -0,0 +1,69 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
namespace mesh {
namespace discovery {
static constexpr uint8_t NODE_RESPONSES = 1;
static constexpr uint8_t REGION_RESPONSES = 2;
static constexpr uint8_t DEFAULT_RESPONSES = NODE_RESPONSES | REGION_RESPONSES;
static constexpr size_t PREFS_SIZE = 8;
static constexpr size_t COMMON_LEGACY_SIZE = 877;
static constexpr size_t LEGACY_RS232_TAIL_SIZE = 10;
inline uint16_t checksum(const uint8_t* bytes, size_t length) {
uint16_t crc = 0xffff;
for (size_t i = 0; i < length; ++i) {
crc ^= static_cast<uint16_t>(bytes[i]) << 8;
for (unsigned bit = 0; bit < 8; ++bit)
crc = static_cast<uint16_t>((crc & 0x8000) ? (crc << 1) ^ 0x1021 : crc << 1);
}
return crc;
}
// The record is omitted when both response types are enabled. Keep it before
// existing platform footers, whose readers locate those policies at EOF.
inline void encodePrefs(uint8_t* out, uint8_t mask) {
out[0] = 'D'; out[1] = 'R'; out[2] = 'P'; out[3] = 1;
out[4] = mask <= DEFAULT_RESPONSES ? mask : DEFAULT_RESPONSES;
out[5] = 0;
const uint16_t crc = checksum(out, 6);
out[6] = static_cast<uint8_t>(crc >> 8);
out[7] = static_cast<uint8_t>(crc);
}
inline bool decodePrefs(const uint8_t* in, size_t size, uint8_t& mask) {
mask = DEFAULT_RESPONSES;
if (!in || size != PREFS_SIZE || in[0] != 'D' || in[1] != 'R'
|| in[2] != 'P' || in[3] != 1 || in[4] > DEFAULT_RESPONSES || in[5] != 0
|| checksum(in, 6) != static_cast<uint16_t>((in[6] << 8) | in[7]))
return false;
mask = in[4];
return true;
}
template <typename File>
uint8_t readPrefs(File& file) {
uint8_t mask = DEFAULT_RESPONSES;
uint8_t bytes[PREFS_SIZE] = {};
const size_t size = file.size();
size_t offset = COMMON_LEGACY_SIZE;
if (size < offset + PREFS_SIZE || !file.seek(offset)
|| file.read(bytes, sizeof(bytes)) != sizeof(bytes))
return mask;
// The source image decides whether a UART power tail exists. Depending on
// this build's bridge flags would lose saved settings across role changes.
if (bytes[0] == 'R' && bytes[1] == 'S' && bytes[2] == 'P' && bytes[3] == 1) {
offset += LEGACY_RS232_TAIL_SIZE;
if (size < offset + PREFS_SIZE || !file.seek(offset)
|| file.read(bytes, sizeof(bytes)) != sizeof(bytes))
return mask;
}
decodePrefs(bytes, sizeof(bytes), mask);
return mask;
}
} // namespace discovery
} // namespace mesh