Files
agessaman eaf28e28b7 feat(mqtt): periodic neighbours publication with serialized scope discovery
Python port of the firmware's WITH_MQTT_NEIGHBORS feature (MeshCore PR #35 plus
the aba571ed pacing rework). Each cycle refreshes the zero-hop neighbour table
with a node-discovery broadcast, asks every neighbour for its region scopes, and
publishes the assembled table to the MQTT neighbors topic.

- NeighborScopeHelper: client side of the anon-regions request (the server side
  already existed in openhop_core). Queries are strictly serialized -- firing
  them as a burst makes the responses collide, which is what the firmware fix
  addressed. router.inject_packet resolves at the firmware's logTx/logTxFail
  boundary, so the response deadline is armed only once the request is on air
  and the firmware's QUEUED/PENDING state machine collapses into an await.
  The response window is sized from radio parameters, mirroring
  neighborDiscoverQueryTimeoutMs().
- NeighborsPublisher: owns the schedule, the immutable per-cycle snapshot, and
  the payload. The snapshot merges live discovery responses over the stored
  table because get_neighbors() serves a 60s cache that store_advert() does not
  invalidate.
- packet_router: offer PAYLOAD_TYPE_RESPONSE to the scope helper before the
  companion fan-out; it consumes only on an authenticated tag match.
- Per-broker `neighbors: true` opt-in (default off) plus a
  mqtt_brokers.neighbors.enabled master switch; interval is 12-336h as in
  firmware, rejected rather than clamped.
- `discover.scopes` mesh CLI command triggers one cycle immediately.

The whole zero-hop table is published including neighbours that did not answer
(timeout / send_failed), matching the firmware payload. No 10 KB cap: that
existed for a fixed PSRAM buffer.
2026-07-28 21:53:22 -07:00

22 lines
533 B
Python

"""Handler helper modules for openHop Repeater."""
from .advert import AdvertHelper
from .discovery import DiscoveryHelper
from .login import LoginHelper
from .neighbor_scopes import NeighborScopeHelper
from .path import PathHelper
from .protocol_request import ProtocolRequestHelper
from .text import TextHelper
from .trace import TraceHelper
__all__ = [
"TraceHelper",
"DiscoveryHelper",
"AdvertHelper",
"LoginHelper",
"NeighborScopeHelper",
"TextHelper",
"PathHelper",
"ProtocolRequestHelper",
]