port artifact cleanup

This commit is contained in:
liquidraver
2026-08-22 18:17:42 +02:00
parent 7d695872d4
commit 7eb5f3832c
3 changed files with 5 additions and 231 deletions
+5 -3
View File
@@ -1109,15 +1109,17 @@ Codes `0x80``0x90` (`PUSH_CODE_*` in `app/CompanionMesh.h`). Most used:
Two distinct field-by-field serializations (NOT raw struct dumps), both Arduino-compatible
in their shared base fields:
**Companion `/lfs/new_prefs` (152 bytes)**`adapters/datastore/ZephyrDataStore.cpp`
**Companion `/lfs/new_prefs` (168 bytes)**`adapters/datastore/ZephyrDataStore.cpp`
`loadPrefs()`/`savePrefs()` (offset comments inline). Arduino companion layout (name, lat/lon,
radio params, telemetry modes, BLE pin, GPS, autoadd) plus ZephCore extensions from offset 92:
rx_boost(92), leds_disabled(93), reserved(94-95, was APC), default flood scope name/key(96-142),
ble_disabled(143), display/wake/screen-off/auto-shutdown(144-149), rx_duty_cycle(150),
meshtimesync(151).
**Repeater/room-server `/lfs/repeater/prefs` (297 bytes)**`app/RepeaterDataStore.cpp`
`loadPrefs()`/`savePrefs()` (same field order as `helpers/CommonCLI.cpp`; offset comments inline).
**Repeater/room-server `/lfs/repeater/prefs` (305 bytes)**`app/RepeaterDataStore.cpp`
`loadPrefs()`/`savePrefs()` (offset comments inline). This is the only serializer for the
repeater layout; `helpers/CommonCLI.cpp` carried a second, unreachable copy of it until it was
removed — do not add prefs fields anywhere but the two files named in this section.
Key ranges: name(4-36), radio(72-119), adaptive-delay(80-111, ignored at runtime),
leds_disabled(120, magic-encoded `0xA0`/`0xA1` — the byte formerly held `agc_reset_interval`, which
stored seconds/4, so any other value is a legacy interval and decodes to "LEDs on"),
-226
View File
@@ -15,7 +15,6 @@
#include <helpers/AdvertDataHelpers.h>
#include <adapters/board/ZephyrBoard.h>
#include <adapters/gps/ZephyrGPSManager.h>
#include <zephyr/fs/fs.h>
#include <zephyr/logging/log.h>
#include <stdlib.h>
#include <string.h>
@@ -47,231 +46,6 @@ static bool isValidName(const char* n) {
return true;
}
// Constrain helper
template<typename T>
static T constrain(T value, T min_val, T max_val) {
if (value < min_val) return min_val;
if (value > max_val) return max_val;
return value;
}
/* Read exactly 'len' bytes; short/error read stops the chain via ok flag */
static inline bool prefs_read(struct fs_file_t *f, void *dest, size_t len) {
return fs_read(f, dest, len) == (ssize_t)len;
}
void CommonCLI::loadPrefs(const char* path) {
struct fs_file_t file;
fs_file_t_init(&file);
if (fs_open(&file, path, FS_O_READ) < 0) {
LOG_DBG("No prefs file at %s, using defaults", path);
return;
}
uint8_t pad[8];
uint8_t leds_byte = 0;
bool ok = true;
/* Read fields in Arduino-compatible binary order.
* On truncated file, short-circuit at first failure
* so remaining fields keep their default values. */
ok = ok && prefs_read(&file, &_prefs->airtime_factor, sizeof(_prefs->airtime_factor)); // 0
ok = ok && prefs_read(&file, &_prefs->node_name, sizeof(_prefs->node_name)); // 4
ok = ok && prefs_read(&file, pad, 4); // 36
ok = ok && prefs_read(&file, &_prefs->node_lat, sizeof(_prefs->node_lat)); // 40
ok = ok && prefs_read(&file, &_prefs->node_lon, sizeof(_prefs->node_lon)); // 48
ok = ok && prefs_read(&file, &_prefs->password[0], sizeof(_prefs->password)); // 56
ok = ok && prefs_read(&file, &_prefs->freq, sizeof(_prefs->freq)); // 72
ok = ok && prefs_read(&file, &_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm)); // 76
ok = ok && prefs_read(&file, &_prefs->disable_fwd, sizeof(_prefs->disable_fwd)); // 77
ok = ok && prefs_read(&file, &_prefs->advert_interval, sizeof(_prefs->advert_interval)); // 78
ok = ok && prefs_read(&file, pad, 1); // 79
ok = ok && prefs_read(&file, &_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base)); // 80
ok = ok && prefs_read(&file, &_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor)); // 84
ok = ok && prefs_read(&file, &_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
ok = ok && prefs_read(&file, &_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor)); // 104
ok = ok && prefs_read(&file, &_prefs->backoff_multiplier, sizeof(_prefs->backoff_multiplier)); // 108
ok = ok && prefs_read(&file, &_prefs->sf, sizeof(_prefs->sf)); // 112
ok = ok && prefs_read(&file, &_prefs->cr, sizeof(_prefs->cr)); // 113
ok = ok && prefs_read(&file, &_prefs->allow_read_only, sizeof(_prefs->allow_read_only)); // 114
ok = ok && prefs_read(&file, &_prefs->multi_acks, sizeof(_prefs->multi_acks)); // 115
ok = ok && prefs_read(&file, &_prefs->bw, sizeof(_prefs->bw)); // 116
/* 120: leds_disabled, magic-encoded. Formerly agc_reset_interval — see the
* LEDS_PREF_* comment in NodePrefs.h for why this is not a bare 0/1. */
ok = ok && prefs_read(&file, &leds_byte, sizeof(leds_byte)); // 120
ok = ok && prefs_read(&file, &_prefs->path_hash_mode, sizeof(_prefs->path_hash_mode)); // 121
ok = ok && prefs_read(&file, &_prefs->loop_detect, sizeof(_prefs->loop_detect)); // 122
ok = ok && prefs_read(&file, pad, 1); // 123
ok = ok && prefs_read(&file, &_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
ok = ok && prefs_read(&file, &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
ok = ok && prefs_read(&file, &_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
ok = ok && prefs_read(&file, pad, 1); // skip bridge_enabled // 127
ok = ok && prefs_read(&file, pad, 2); // skip bridge_delay // 128
ok = ok && prefs_read(&file, pad, 1); // skip bridge_pkt_src // 130
ok = ok && prefs_read(&file, pad, 4); // skip bridge_baud // 131
ok = ok && prefs_read(&file, pad, 1); // skip bridge_channel // 135
ok = ok && prefs_read(&file, pad, 16); // skip bridge_secret // 136
ok = ok && prefs_read(&file, &_prefs->powersaving_enabled, sizeof(_prefs->powersaving_enabled)); // 152
ok = ok && prefs_read(&file, pad, 3); // 153
ok = ok && prefs_read(&file, &_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
ok = ok && prefs_read(&file, &_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
ok = ok && prefs_read(&file, &_prefs->advert_loc_policy, sizeof(_prefs->advert_loc_policy)); // 161
ok = ok && prefs_read(&file, &_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162
ok = ok && prefs_read(&file, &_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
ok = ok && prefs_read(&file, _prefs->owner_info, sizeof(_prefs->owner_info)); // 170
ok = ok && prefs_read(&file, &_prefs->rx_boost, sizeof(_prefs->rx_boost)); // 290
ok = ok && prefs_read(&file, &_prefs->rx_duty_cycle, sizeof(_prefs->rx_duty_cycle)); // 291
/* 292-293: RESERVED — formerly apc_enabled / apc_margin (APC, removed in
* 1.16.6). Still read so offset 294 onward stays where deployed nodes
* wrote it; the values are ignored. */
ok = ok && prefs_read(&file, &_prefs->_reserved_apc_enabled, sizeof(_prefs->_reserved_apc_enabled)); // 292
ok = ok && prefs_read(&file, &_prefs->_reserved_apc_margin, sizeof(_prefs->_reserved_apc_margin)); // 293
ok = ok && prefs_read(&file, &_prefs->flood_max_unscoped, sizeof(_prefs->flood_max_unscoped)); // 294
ok = ok && prefs_read(&file, &_prefs->flood_max_advert, sizeof(_prefs->flood_max_advert)); // 295
ok = ok && prefs_read(&file, &_prefs->meshtimesync, sizeof(_prefs->meshtimesync)); // 296
ok = ok && prefs_read(&file, &_prefs->cad_auto, sizeof(_prefs->cad_auto)); // 297
ok = ok && prefs_read(&file, &_prefs->cad_offset, sizeof(_prefs->cad_offset)); // 298
ok = ok && prefs_read(&file, &_prefs->probe_interval, sizeof(_prefs->probe_interval)); // 299
ok = ok && prefs_read(&file, &_prefs->cad_busycap, sizeof(_prefs->cad_busycap)); // 300
ok = ok && prefs_read(&file, _prefs->extra_sf, sizeof(_prefs->extra_sf)); // 301-303
if (!ok) {
LOG_WRN("Prefs file %s truncated, some fields use defaults", path);
}
fs_close(&file);
/* Only the explicit "off" magic disables LEDs; a legacy AGC interval, an
* unwritten byte, or a truncated file all mean "on". */
_prefs->leds_disabled = (leds_byte == LEDS_PREF_OFF) ? 1 : 0;
// Sanitise bad pref values
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0.0f, 20.0f);
_prefs->tx_delay_factor = constrain(_prefs->tx_delay_factor, 0.0f, 2.0f);
_prefs->direct_tx_delay_factor = constrain(_prefs->direct_tx_delay_factor, 0.0f, 2.0f);
/* Migrate uninitialized pad bytes: NaN or out-of-range → default 0.2.
* 0.0 is valid (disables reactive backoff). Old firmware upgrading
* with zeroed pad bytes will get 0.0 = disabled; user can set explicitly. */
if (_prefs->backoff_multiplier != _prefs->backoff_multiplier ||
_prefs->backoff_multiplier < 0.0f || _prefs->backoff_multiplier > 10.0f) {
_prefs->backoff_multiplier = 0.2f;
}
_prefs->backoff_multiplier = constrain(_prefs->backoff_multiplier, 0.0f, 2.0f);
/* af is the Arduino airtime budget factor: duty% = 100 / (af + 1).
* Range matches upstream (0..9). Values >9 (from a previous build that
* stored af as a percentage) get clamped to 9 → 10% effective. */
_prefs->airtime_factor = constrain(_prefs->airtime_factor, 0.0f, 9.0f);
_prefs->freq = constrain(_prefs->freq, 150.0f, 2500.0f);
_prefs->bw = constrain(_prefs->bw, 7.8f, 500.0f);
_prefs->sf = constrain(_prefs->sf, (uint8_t)5, (uint8_t)12);
_prefs->cr = constrain(_prefs->cr, (uint8_t)5, (uint8_t)8);
_prefs->tx_power_dbm = constrain(_prefs->tx_power_dbm, (int8_t)-9, (int8_t)30);
#ifdef CONFIG_ZEPHCORE_MAX_TX_POWER_DBM
if (_prefs->tx_power_dbm > CONFIG_ZEPHCORE_MAX_TX_POWER_DBM) {
_prefs->tx_power_dbm = (int8_t)CONFIG_ZEPHCORE_MAX_TX_POWER_DBM;
}
#endif
_prefs->multi_acks = constrain(_prefs->multi_acks, (uint8_t)0, (uint8_t)1);
_prefs->adc_multiplier = constrain(_prefs->adc_multiplier, 0.0f, 30000.0f);
_prefs->path_hash_mode = constrain(_prefs->path_hash_mode, (uint8_t)0, (uint8_t)2);
_prefs->powersaving_enabled = constrain(_prefs->powersaving_enabled, (uint8_t)0, (uint8_t)1);
_prefs->gps_enabled = constrain(_prefs->gps_enabled, (uint8_t)0, (uint8_t)1);
_prefs->advert_loc_policy = constrain(_prefs->advert_loc_policy, (uint8_t)0, (uint8_t)2);
_prefs->rx_boost = constrain(_prefs->rx_boost, (uint8_t)0, (uint8_t)1);
_prefs->rx_duty_cycle = constrain(_prefs->rx_duty_cycle, (uint8_t)0, (uint8_t)1);
_prefs->flood_max_unscoped = constrain(_prefs->flood_max_unscoped, (uint8_t)0, (uint8_t)64);
_prefs->flood_max_advert = constrain(_prefs->flood_max_advert, (uint8_t)0, (uint8_t)64);
_prefs->meshtimesync = constrain(_prefs->meshtimesync, (uint8_t)0, (uint8_t)1);
_prefs->cad_auto = constrain(_prefs->cad_auto, (uint8_t)0, (uint8_t)1);
_prefs->cad_offset = constrain(_prefs->cad_offset, (int8_t)CAD_OFFSET_MIN, (int8_t)CAD_OFFSET_MAX);
if (_prefs->probe_interval != 0 && _prefs->probe_interval < 10) {
_prefs->probe_interval = 10;
}
_prefs->cad_busycap = constrain(_prefs->cad_busycap, (uint8_t)0, (uint8_t)90);
LOG_INF("Loaded prefs from %s", path);
}
void CommonCLI::savePrefs(const char* path) {
// Remove old file first
fs_unlink(path);
struct fs_file_t file;
fs_file_t_init(&file);
if (fs_open(&file, path, FS_O_CREATE | FS_O_WRITE) < 0) {
LOG_ERR("Failed to open %s for write", path);
return;
}
uint8_t pad[16];
memset(pad, 0, sizeof(pad));
fs_write(&file, &_prefs->airtime_factor, sizeof(_prefs->airtime_factor));
fs_write(&file, &_prefs->node_name, sizeof(_prefs->node_name));
fs_write(&file, pad, 4);
fs_write(&file, &_prefs->node_lat, sizeof(_prefs->node_lat));
fs_write(&file, &_prefs->node_lon, sizeof(_prefs->node_lon));
fs_write(&file, &_prefs->password[0], sizeof(_prefs->password));
fs_write(&file, &_prefs->freq, sizeof(_prefs->freq));
fs_write(&file, &_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm));
fs_write(&file, &_prefs->disable_fwd, sizeof(_prefs->disable_fwd));
fs_write(&file, &_prefs->advert_interval, sizeof(_prefs->advert_interval));
fs_write(&file, pad, 1);
fs_write(&file, &_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base));
fs_write(&file, &_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor));
fs_write(&file, &_prefs->guest_password[0], sizeof(_prefs->guest_password));
fs_write(&file, &_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor));
fs_write(&file, &_prefs->backoff_multiplier, sizeof(_prefs->backoff_multiplier));
fs_write(&file, &_prefs->sf, sizeof(_prefs->sf));
fs_write(&file, &_prefs->cr, sizeof(_prefs->cr));
fs_write(&file, &_prefs->allow_read_only, sizeof(_prefs->allow_read_only));
fs_write(&file, &_prefs->multi_acks, sizeof(_prefs->multi_acks));
fs_write(&file, &_prefs->bw, sizeof(_prefs->bw));
/* 120: leds_disabled, magic-encoded (was agc_reset_interval). */
{
uint8_t leds_byte = _prefs->leds_disabled ? LEDS_PREF_OFF : LEDS_PREF_ON;
fs_write(&file, &leds_byte, sizeof(leds_byte));
}
fs_write(&file, &_prefs->path_hash_mode, sizeof(_prefs->path_hash_mode));
fs_write(&file, &_prefs->loop_detect, sizeof(_prefs->loop_detect));
fs_write(&file, pad, 1);
fs_write(&file, &_prefs->flood_max, sizeof(_prefs->flood_max));
fs_write(&file, &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval));
fs_write(&file, &_prefs->interference_threshold, sizeof(_prefs->interference_threshold));
fs_write(&file, pad, 1); // bridge_enabled
fs_write(&file, pad, 2); // bridge_delay
fs_write(&file, pad, 1); // bridge_pkt_src
fs_write(&file, pad, 4); // bridge_baud
fs_write(&file, pad, 1); // bridge_channel
fs_write(&file, pad, 16); // bridge_secret
fs_write(&file, &_prefs->powersaving_enabled, sizeof(_prefs->powersaving_enabled));
fs_write(&file, pad, 3);
fs_write(&file, &_prefs->gps_enabled, sizeof(_prefs->gps_enabled));
fs_write(&file, &_prefs->gps_interval, sizeof(_prefs->gps_interval));
fs_write(&file, &_prefs->advert_loc_policy, sizeof(_prefs->advert_loc_policy));
fs_write(&file, &_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp));
fs_write(&file, &_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier));
fs_write(&file, _prefs->owner_info, sizeof(_prefs->owner_info));
fs_write(&file, &_prefs->rx_boost, sizeof(_prefs->rx_boost));
fs_write(&file, &_prefs->rx_duty_cycle, sizeof(_prefs->rx_duty_cycle));
/* 292-293: RESERVED — formerly APC, written back unchanged. */
fs_write(&file, &_prefs->_reserved_apc_enabled, sizeof(_prefs->_reserved_apc_enabled));
fs_write(&file, &_prefs->_reserved_apc_margin, sizeof(_prefs->_reserved_apc_margin));
fs_write(&file, &_prefs->flood_max_unscoped, sizeof(_prefs->flood_max_unscoped));
fs_write(&file, &_prefs->flood_max_advert, sizeof(_prefs->flood_max_advert));
fs_write(&file, &_prefs->meshtimesync, sizeof(_prefs->meshtimesync));
fs_write(&file, &_prefs->cad_auto, sizeof(_prefs->cad_auto));
fs_write(&file, &_prefs->cad_offset, sizeof(_prefs->cad_offset));
fs_write(&file, &_prefs->probe_interval, sizeof(_prefs->probe_interval));
fs_write(&file, &_prefs->cad_busycap, sizeof(_prefs->cad_busycap));
fs_write(&file, _prefs->extra_sf, sizeof(_prefs->extra_sf));
fs_close(&file);
LOG_INF("Saved prefs to %s", path);
}
#define MIN_LOCAL_ADVERT_INTERVAL 60
void CommonCLI::savePrefs() {
-2
View File
@@ -147,8 +147,6 @@ public:
k_work_init_delayable(&_reboot_work, rebootWorkHandler);
}
void loadPrefs(const char* path);
void savePrefs(const char* path);
void handleCommand(uint32_t sender_timestamp, const char* command, char* reply);
uint8_t buildAdvertData(uint8_t node_type, uint8_t* app_data);
};