Repository navigation
Conversation
Event-driven step functions for one guest-key poll of a direct neighbor and for the admin removal drill, with host tests driving them against a scripted repeater.
Guest polling has to match the repeater login, request, PATH teach, and setperm plaintexts, and must not treat telemetry as an admin login.
Port CoreScope's clamps, kill switches, and owner freshness rules so a scheduled poll can be decided without JSON or a clock.
Accept login answers from the moment a login is handed to the owner, holding them until its TX report. An admin answer is taken at any point after that, overriding a held or accepted guest answer, and ends the poll. The admin drill holds a verifying answer that beats its login's TX report.
…ndows; never emit invalid UTF-8
Keep the fields runtime-only so an upgrade does not rewrite /mqtt.json on nodes that have never configured polling.
Refuse the commands until the poller enables them, and turn polling off when url, slot, or consent is cleared.
Claims publish on meshcore/<IATA>/<pubkey>/polling. MeshRank does not consume that topic.
…our login is not dropped
… it reaches flash
…xt save writes over it
…a packet the queue refused
Guest passwords arrive without the two-byte packet MAC. Check the full tag before decrypting, and accept only a short zero-terminated password so a bad block cannot be treated as blank.
A malformed envelope is marked bad so the caller does not fall back to a blank password. Extra targets are kept up to the free capacity, ranked by role and key rather than JSON order.
Absence fails closed: forget a target when a valid owners answer omits it, when roles lapse, or when the https opt-in stops. A new envelope wipes the decrypted password so a refusal is not retried.
…urgent states in the signature
…ed path, and use the own key at once in a JSON mode
…icy names, and hold polling without one
…ker hosts can pick the slot
…y reply without voltage as a success
…t off the loop stack
… after an admin answer
…ners-brief helpers
…ive local targets their seats at once
…l points at the matched broker An automatic claim or reading kept only the slot number, so a reconfigure could send it to a broker the policy never named. The mailbox now carries the matched host and the MQTT task refuses the send when that host is no longer the slot's broker. The poller object was already 5540 bytes, past the 5204 ceiling, so this environment could not build. The ceiling matches that size. This change adds no poller fields.
A valid prefix plus the owners and policy query no longer fit in the old 352-byte buffer, so those GETs failed before connecting.
The retry stamp was forced one millisecond ahead, so a same-tick check wrapped and treated the wait as already over.
A wrong host left the claim unsent and the reading held, but neither waited out its retry before trying again.
A plain memset after the last read of a password copy is a dead store, so the bytes can outlive the handler and the scratch.
… requests are accepted
…pe is re-encrypted The repeater ACL entry belongs to the polling key, so a new ciphertext must not drop the fast path or cancel a poll already running.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds guest-key repeater polling to repeater observers. An observer keeps a short list of neighbor repeaters, logs in to each as a guest under a separate polling identity, and requests battery and telemetry on a schedule. A CoreScope server coordinates which observer polls which repeater. The behavior mirrors the openHop plugin "CoreScope Observer Plus" v0.11.1 (guest-key path only).
Off by default. Nothing is sent until an operator sets an analyzer URL and runs
set poll on. Against a CoreScope server the operator also sets an MQTT slot for claims, gives consent to the key upload, and adds targets.A second mode serves analyzers that do not want to hold polling keys (written for Beacon). The analyzer selects it with a policy field; the observer then publishes each reading as JSON over MQTT and never uploads its polling key. See "Reading modes" below.
What is in here
src/helpers/poll/: packet codec and reply parsers, schedule and backoff, policy gate and standby decisions, claims, registration, state store, HTTP framing and JSON parsing for the control client.examples/simple_repeater/RepeaterPoller.{h,cpp}: login, route teach, request, admin stop and removal drill, flash state (learned passwords, admin stops, saved gate, tag high-water).set poll on|off,set poll.url|slot|interval|status|community|consent,poll add|remove|clear|list|pw|enable|now,get poll,get poll.status <n>,get poll.control,get poll.key.Built only where
WITH_REPEATER_POLLis derived (ESP32, MQTT bridge, neighbor table, PSRAM); other builds are unchanged.Reading modes (added after the first draft)
The policy answer may carry
reading_format. Absent means the CoreScope behavior above, unchanged: same HTTP calls apart from two added query parameters (client,client_version), same claim bytes, same registration and shared-key behavior.With
reading_formatset tojsonortelemetry:.../battery(v1) or.../telemetry(v2, with the LPP records), each with the request tag and the reply's packet hash. A reading that could not be published is held in RAM and retried no more often than every 60 s.poll.slotunset, the slot is the first one whose broker host is in the policy'smqtt_hosts. No match means no claim, no reading and no poll. A publication carries the host it was matched to and is refused if the slot has been pointed elsewhere in the meantime.key:"own", per-node state, misses, last attempt and last success, plusaccepts_requestsandrequest_slots.poll pw <target> set <password>(1 to 15 printable ASCII characters). Stored with the target, never published, discarded after an admin answer.set poll.requests on, default off, https only). The owners answer may name targets the operator did not configure, each with an optional password encrypted to the observer's node key (X25519, HMAC-SHA256 key derivation and tag, one AES-128 block). They share the eight target seats with local targets, which have priority; they live in RAM only and are dropped when the opt-in, URL, mode or owners answer no longer supports them. Two failed logins refuse that password version until the version changes. An admin answer is a persistent stop.New CLI:
set poll.requests on|off,poll pw <target> set <password>;get pollandget poll.statusshow the mode, the slot and how it was chosen, and requested targets.Deliberate differences from the plugin
poll nowchecks with CoreScope first when the session spacing allows.Testing
Native: 1234 test cases pass (whole native suite).
Builds:
heltec_v4_repeater_observer_mqtt,Heltec_v3_repeater_observer_mqtt,Waveshare_S3_LR1121_repeater_observer_mqtt(83.7 % of the app partition),Heltec_v3_room_server_observer_mqtt.Bench, Heltec V4 poller with a Heltec V3 and a Waveshare LR1121 as targets, against a local CoreScope stand-in:
poll nowwaiting on a CoreScope check, and dropped when polling is switched off;One HTTPS control session against a real CoreScope server: owners, policy and shared key returned 200.
Bench of the reading modes at
c1466cb63(requested-target session at9b005a940), same boards, stand-in extended with the new fields:poll nowrefused), and recovery once the host list is corrected;Not done yet
Reading modes, on hardware: operator password via
poll pw ... set; admin answer from a requested target; a slot reconfigured between queueing and publishing; requests over real https; a local target taking the last seat from a requested one.Settings written by this build (
poll.requests, operator passwords) are dropped by an older build of this branch on downgrade.Overnight soak of this tip.
On hardware: the TLS guard and stop acknowledgment under a link flap or bridge stop; loop-task stack high-water; key lost mid-run (empty claim); URL change with a different shared key; expired shared key; policy lists longer than the parser limits (all host-tested).
The TLS connect to the real server took 9.97 s against a 12 s limit with five slots up.
Whether the server reads a claim with an empty node list as a retraction, and whether it expires stale claims.
A node with no key and a due target still opens a control session every control period; a 404 registration is retried only after a fixed delay.
Docs (
docs/cli_commands.md), rename ofnamespace poll(clashes with POSIXpoll()in translation units that include socket headers), decision on non-PSRAM boards.