Improve companion BLE delivery and idempotent remote CLI retries, make FPF7 persistence atomic with FPF6 migration, verify staged OTA data on resume, and clarify filter policy wildcard and BlackHole semantics.
Improve the response message for the `alert test` command to clarify
that a successful test send does not guarantee automatic alerts are
enabled. This change helps prevent confusion for operators regarding
the status of the alert system after testing.
Port the neighbor-discovery state machine from mqtt-bridge-implementation-flex,
adapted to this branch's MyMesh (WebConfig members shifted the insertion points;
applied by content).
- Two-stage periodic refresh in loop() driven by mqtt_neighbors_interval:
stage 1 is a zero-hop sendNodeDiscoverReq() (reuses the existing 60s window),
stage 2 (startNeighborDiscover) fires one anon-regions scope query per heard
neighbour, then finishNeighborDiscover() builds the table JSON via
MQTTMessageBuilder::buildNeighborsMessage and hands it to
bridge->requestPublishNeighbors().
- Peer overlay at NEIGHBOR_DISCOVER_PEER_BASE lets scope-query RESPONSE packets
from non-ACL neighbours decrypt: searchPeersByHash prepends heard neighbours
(bounded by MAX_CLIENTS), getPeerSharedSecret derives the secret on the fly,
and onPeerDataRecv routes both overlay-index and ACL-client-that-is-a-neighbour
responses into handleNeighborDiscoverResponse.
- Entries ordered most- to least-useful (recent, then stronger SNR) so the JSON
builder's tail-drop keeps the useful head.
- `discover.scopes` CLI command (manual trigger), with a WITH_MQTT_BRIDGE stub
replying "requires PSRAM" on non-PSRAM builds.
- Reports schedule to the bridge each loop via setNeighborsSchedule().
- Uses ArduinoJson v7 JsonDocument (not deprecated DynamicJsonDocument).
All gated on WITH_MQTT_NEIGHBORS. Reuses the existing MQTTBridge* member.
Verified: T_Beam_S3_Supreme_SX1262_repeater_observer_mqtt builds [SUCCESS].
First upstream merge since the 2026-06-06 base (191 upstream commits). 14 files
conflicted; resolutions below.
Fleet-critical check (Constraint 1): upstream reordered NodePrefs members
(rx_boosted_gain / path_hash_mode moved to the struct tail) but did NOT change
/com_prefs. Persistence is written field-by-field at explicit offsets, so member
order is in-memory only. Verified the fork's writeCommonPrefsImage() is
byte-identical to upstream's inline writer at every offset (79 pad, 121, 122,
290-294). No migration needed.
Resolutions:
- CommonCLI.h: kept the fork's NodePrefs (superset) and adopted upstream's
setRxBoostedGain(bool)->bool signature change, which CommonCLI.cpp now uses to
report unsupported. Corrected a stale comment claiming rx_boosted_gain lives at
offset 79 (it is a pad; the field is at 290).
- CommonCLI.cpp: kept the fork's legacy /com_prefs migration and the extracted
writeCommonPrefsImage() call.
- UITask.cpp: three-way merge - upstream's drawTextCentered + powering-off
screen, plus the fork's WITH_WEBCONFIG portal/reboot screens.
- ESP32Board.cpp, MeshCore.h, platformio.ini: kept both sides (fork OTA additions
alongside upstream powerOff/enterDeepSleep and Packet.cpp).
- MicroNMEALocationProvider.h: took upstream's claim/release and added the
_claims member they depend on.
- MyMesh.cpp/.h (repeater + room server): kept the fork's superset defaults.
- Removed duplicate declarations auto-merge produced: RadioLibWrapper::_cad_enabled
and MyMesh::getCADEnabled().
Verification: native suite 15/15 (incl. upstream's new test_mesh_tables), both
MQTT smoke builds green, ArduinoJson pin check passes. Hardware validation next.