mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 14:58:12 +00:00
feat(repeater): default network profile, band-matched to companion freq
Enabling the repeater now defaults to a dedicated radio profile rather than relaying on the companion's current frequency: same-network repeating isn't the MeshCore community norm. The default profile is seeded with a frequency in the same legal band as the companion's own network (433/868/915 MHz, via defaultRepeaterFreqForBand()) rather than a flat firmware constant, so it can't land outside what's allowed for the operator's region. Also fixes a gap where a true first boot (no prefs file yet) never hit the DataStore.cpp migration fallback and stayed on repeater_use_profile=0. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
20
FEATURES.md
20
FEATURES.md
@@ -447,8 +447,10 @@ On-device repeater for the Solo companion, scoped to the SX1262 boards (Wio
|
||||
Tracker L1 OLED/e-ink, GAT562 30S). All on `feature/companion-repeater-presets`.
|
||||
|
||||
- **Repeater toggle** (`client_repeat`, Tools › Repeater) — the companion relays
|
||||
flood/direct traffic on its **current** frequency (no dedicated band), still
|
||||
working as a normal companion. `MyMesh::allowPacketForward` gates it; loop
|
||||
flood/direct traffic, still working as a normal companion. By default it
|
||||
switches to a dedicated band on enable (see profile note below) rather than
|
||||
relaying on whatever network it's chatting on. `MyMesh::allowPacketForward`
|
||||
gates it; loop
|
||||
detection (`isRepeatLooped`, ported from `simple_repeater`) and an advert
|
||||
flood-depth cap are always applied. Packet pool bumped 16→32 to match the
|
||||
repeater workload (a too-small pool starved channel/DM reception once relaying
|
||||
@@ -464,8 +466,18 @@ Tracker L1 OLED/e-ink, GAT562 30S). All on `feature/companion-repeater-presets`.
|
||||
equal to the companion = "same network", a different one = drop onto a separate
|
||||
repeater network. `MyMesh::applyRepeaterRadio()` is the single decision point,
|
||||
called at boot and on every toggle/edit; `repeaterProfileValid()` gates it.
|
||||
Schema sentinel `0xC0DE0010`, profile cleared to off if load finds an invalid
|
||||
config (stray bytes from older files).
|
||||
Schema sentinel `0xC0DE0010`. **Custom is the default**: a never-configured
|
||||
device (or one upgrading from a pre-`0x10` file, which has no saved profile)
|
||||
turns the profile on and seeds `repeater_sf/bw/cr` from `LORA_SF/BW/CR` plus
|
||||
a band-matched `repeater_freq` — relaying on the same network the operator is
|
||||
chatting on isn't the MeshCore community norm, so "Current" stays opt-in.
|
||||
`defaultRepeaterFreqForBand()` (`NodePrefs.h`) buckets the companion's own
|
||||
`freq` into whichever of the three license-exempt bands MeshCore's app-driven
|
||||
repeat toggle historically restricted to (433.000 / 869.495 / 918.000 MHz —
|
||||
see `repeat_freq_ranges` in `MyMesh.cpp`), so the seeded default can't land
|
||||
outside what's legal for wherever the companion's own network already is.
|
||||
`LORA_FREQ/BW/SF/CR` fallback `#define`s moved from `MyMesh.h` to
|
||||
`NodePrefs.h` so `DataStore.cpp`'s migration code can see them too.
|
||||
- **Politeness knobs** (all opt-in, default off, flood-only — a direct route's
|
||||
named next hop is never dropped). Shown only while the repeater is on:
|
||||
- **Skip advert** — don't re-flood adverts (highest-volume flood).
|
||||
|
||||
@@ -319,14 +319,14 @@ The counters make the repeater behaviour observable: **Forwarded** confirms the
|
||||
|
||||
## Repeater
|
||||
|
||||
Turns the companion into a packet **repeater** while it keeps working as a normal companion — no separate firmware. By default it relays on its **current** frequency, or you can give it a dedicated radio profile to switch to while relaying (see **Network** below). Loop-detection and an advert flood-depth cap are always applied. This screen keeps the toggle, the network/profile, and its flood-filter options together; live forwarding stats are on **Tools › Diagnostics**.
|
||||
Turns the companion into a packet **repeater** while it keeps working as a normal companion — no separate firmware. By default, enabling it switches the radio to a dedicated repeater profile rather than relaying on whatever network you're chatting on (see **Network** below) — that matches the MeshCore community norm of repeaters sitting on a standard channel, not a private one. Loop-detection and an advert flood-depth cap are always applied. This screen keeps the toggle, the network/profile, and its flood-filter options together; live forwarding stats are on **Tools › Diagnostics**.
|
||||
|
||||
Navigate with **UP/DOWN**; change a value with **LEFT/RIGHT** (or **Enter** for toggles). **Cancel/Back** saves and returns to Tools.
|
||||
|
||||
| Setting | Options | Notes |
|
||||
| -------------- | --------------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| Repeater | ON / OFF | Master switch. The options below appear only while it is ON. |
|
||||
| Network | Current / Custom | **Current**: relay on the companion's own frequency (default). **Custom**: enabling the repeater switches the radio to a dedicated profile (below) and disabling restores the companion's settings — so you can drop onto a separate repeater network and come back. Switching to Custom seeds the profile from your current settings. |
|
||||
| Network | Current / Custom | **Custom** _(default)_: enabling the repeater switches the radio to a dedicated profile (below) and disabling restores the companion's settings — so you can drop onto a separate repeater network and come back. A never-configured device seeds Custom with a frequency in the same band as your own network (433/868/915 MHz region), not a flat one-size-fits-all default — so it can't land outside what's legal for your region. Switching to Custom afterwards (if it was OFF and unconfigured) seeds it from your current settings instead. **Current**: relay on the companion's own frequency — opt-in; not the community norm. |
|
||||
| Rpt preset | named presets | _(Custom only)_ **Enter** picks a community/saved preset for the repeater profile. |
|
||||
| Rpt freq | chip range | _(Custom only)_ **Enter** opens the digit-by-digit editor (chip-validated bounds). |
|
||||
| Rpt SF / BW / CR | 5–12 / 7.8–500 kHz / 5–8 | _(Custom only)_ **LEFT/RIGHT** to adjust the profile's spreading factor, bandwidth, coding rate. |
|
||||
|
||||
@@ -356,16 +356,23 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
|
||||
rd(&_prefs.repeater_bw, sizeof(_prefs.repeater_bw));
|
||||
rd(&_prefs.repeater_sf, sizeof(_prefs.repeater_sf));
|
||||
rd(&_prefs.repeater_cr, sizeof(_prefs.repeater_cr));
|
||||
// Pre-0x10 files leave stray sentinel bytes here. If the profile fields aren't a
|
||||
// valid radio config, force the profile off so the repeater can't switch to junk.
|
||||
// Pre-0x10 files leave stray sentinel bytes here, same as a never-configured
|
||||
// device. Either way there's no valid saved profile, so default to a profile
|
||||
// in the same band as the companion's own network (_prefs.freq, already read
|
||||
// above) rather than "Current" — a repeater silently following the companion
|
||||
// onto whatever private network it later joins isn't the MeshCore community
|
||||
// norm; that stays opt-in. Band-matched rather than a flat frequency so the
|
||||
// default can't land outside what's legal where the companion is set up.
|
||||
if (_prefs.repeater_use_profile > 1) _prefs.repeater_use_profile = 0;
|
||||
if (!(_prefs.repeater_freq >= 100.0f && _prefs.repeater_freq <= 960.0f
|
||||
&& _prefs.repeater_sf >= 5 && _prefs.repeater_sf <= 12
|
||||
&& _prefs.repeater_cr >= 5 && _prefs.repeater_cr <= 8
|
||||
&& _prefs.repeater_bw >= 7.0f && _prefs.repeater_bw <= 510.0f)) {
|
||||
_prefs.repeater_use_profile = 0;
|
||||
_prefs.repeater_freq = _prefs.repeater_bw = 0.0f;
|
||||
_prefs.repeater_sf = _prefs.repeater_cr = 0;
|
||||
_prefs.repeater_use_profile = 1;
|
||||
_prefs.repeater_freq = defaultRepeaterFreqForBand(_prefs.freq);
|
||||
_prefs.repeater_bw = LORA_BW;
|
||||
_prefs.repeater_sf = LORA_SF;
|
||||
_prefs.repeater_cr = LORA_CR;
|
||||
}
|
||||
// → 0xC0DE000B: append bot_commands_enabled + quiet-hours. Older files leave
|
||||
// stray bytes here; clamp so upgraders fall back to off / no quiet hours.
|
||||
|
||||
@@ -1307,6 +1307,14 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
|
||||
_prefs.bw = LORA_BW;
|
||||
_prefs.cr = LORA_CR;
|
||||
_prefs.tx_power_dbm = LORA_TX_POWER;
|
||||
// Repeater profile default for a true first boot (no prefs file yet, so
|
||||
// loadPrefs() below is a no-op) — same band-matched seed as the upgrade
|
||||
// path in DataStore.cpp, kept in sync rather than left at memset's 0/Current.
|
||||
_prefs.repeater_use_profile = 1;
|
||||
_prefs.repeater_freq = defaultRepeaterFreqForBand(_prefs.freq);
|
||||
_prefs.repeater_bw = LORA_BW;
|
||||
_prefs.repeater_sf = LORA_SF;
|
||||
_prefs.repeater_cr = LORA_CR;
|
||||
_prefs.gps_enabled = 0; // GPS disabled by default
|
||||
_prefs.gps_interval = 0; // No automatic GPS updates by default
|
||||
_prefs.display_brightness = 2; // medium brightness by default
|
||||
|
||||
@@ -41,18 +41,7 @@ class UITask;
|
||||
|
||||
/* ---------------------------------- CONFIGURATION ------------------------------------- */
|
||||
|
||||
#ifndef LORA_FREQ
|
||||
#define LORA_FREQ 915.0
|
||||
#endif
|
||||
#ifndef LORA_BW
|
||||
#define LORA_BW 250
|
||||
#endif
|
||||
#ifndef LORA_SF
|
||||
#define LORA_SF 10
|
||||
#endif
|
||||
#ifndef LORA_CR
|
||||
#define LORA_CR 5
|
||||
#endif
|
||||
// LORA_FREQ/BW/SF/CR fallbacks now live in NodePrefs.h (DataStore.cpp needs them too).
|
||||
#ifndef LORA_TX_POWER
|
||||
#define LORA_TX_POWER 20
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,37 @@
|
||||
#include <cstdint>
|
||||
#include <stdio.h>
|
||||
|
||||
// Firmware's own boot-default radio params — used both as the companion's
|
||||
// initial freq/sf/bw/cr (MyMesh.cpp) and, here, as the seed for a never-
|
||||
// configured repeater profile (DataStore.cpp). Kept above any per-board
|
||||
// target.h include so a board can still override via -D before this file
|
||||
// is reached.
|
||||
#ifndef LORA_FREQ
|
||||
#define LORA_FREQ 915.0
|
||||
#endif
|
||||
#ifndef LORA_BW
|
||||
#define LORA_BW 250
|
||||
#endif
|
||||
#ifndef LORA_SF
|
||||
#define LORA_SF 10
|
||||
#endif
|
||||
#ifndef LORA_CR
|
||||
#define LORA_CR 5
|
||||
#endif
|
||||
|
||||
// Bucket a companion frequency into whichever of the three license-exempt
|
||||
// bands MeshCore's app-driven repeat toggle historically restricted to (see
|
||||
// repeat_freq_ranges in MyMesh.cpp: 433.000 / 869.495 / 918.000 MHz). Used to
|
||||
// seed a never-configured repeater profile in the same legal band as the
|
||||
// companion's own network (MyMesh.cpp begin(), DataStore.cpp) — a flat
|
||||
// single frequency could land outside the bands allowed where the operator
|
||||
// actually lives.
|
||||
static inline float defaultRepeaterFreqForBand(float companion_freq) {
|
||||
if (companion_freq < 500.0f) return 433.000f;
|
||||
if (companion_freq < 890.0f) return 869.495f;
|
||||
return 918.000f;
|
||||
}
|
||||
|
||||
#define TELEM_MODE_DENY 0
|
||||
#define TELEM_MODE_ALLOW_FLAGS 1 // use contact.flags
|
||||
#define TELEM_MODE_ALLOW_ALL 2
|
||||
@@ -176,7 +207,11 @@ struct NodePrefs { // persisted to file
|
||||
// Optional dedicated radio profile for repeater mode. When repeater_use_profile
|
||||
// is 1, enabling the repeater switches the radio to repeater_freq/bw/sf/cr and
|
||||
// disabling restores the companion's freq/bw/sf/cr (the fields above). 0 = the
|
||||
// repeater stays on the current companion frequency (default — no switch).
|
||||
// repeater stays on the current companion frequency. Default (a never-configured
|
||||
// device) is 1, seeded via defaultRepeaterFreqForBand(freq) + LORA_SF/BW/CR —
|
||||
// repeating on whatever private network the companion later joins isn't the
|
||||
// community norm, and the seed stays in the same legal band as the companion's
|
||||
// own network rather than a flat frequency.
|
||||
uint8_t repeater_use_profile;
|
||||
float repeater_freq;
|
||||
float repeater_bw;
|
||||
|
||||
@@ -6,10 +6,14 @@
|
||||
// and keeps the relaying controls next to the numbers that show them working.
|
||||
//
|
||||
// Network modes:
|
||||
// - Current — repeat on the companion's current frequency (default).
|
||||
// - Current — repeat on the companion's current frequency. Opt-in only:
|
||||
// relaying on whatever network the operator is chatting on
|
||||
// isn't the MeshCore community norm.
|
||||
// - Custom — enabling the repeater switches the radio to a dedicated profile
|
||||
// (preset or manual), and disabling restores the companion params.
|
||||
// Set the profile equal to the companion's for "same network".
|
||||
// Default for a never-configured device, seeded with a frequency
|
||||
// in the same band as the companion's own network (so the default
|
||||
// can't land outside what's legal for the operator's region).
|
||||
// Included by UITask.cpp.
|
||||
|
||||
#include <helpers/ui/DisplayDriver.h>
|
||||
|
||||
Reference in New Issue
Block a user