InboundAuthState
Progress stages of inbound authentication (device‑initiated commands).
@ WAIT_CHALLENGE_RESPONSE
Timer running; waiting for device's HMAC proof (0x3D).
@ VERIFIED
Device successfully authenticated; command is trusted.
@ TX_CHALLENGE
Challenge (0x3C) sent to device; awaiting 0x3D response.
@ IDLE
No inbound authentication in progress.
OutboundExchangeState
Progress stages of an outbound authenticated exchange (non‑pairing).
@ TX_REQUEST
Request frame transmitted; awaiting first response from device.
@ TX_AUTH_RESPONSE
Auth response (0x3D) transmitted; awaiting device's final reply.
@ IDLE
No active exchange; idle state.
@ BUILD_AUTH_RESPONSE
Building the 0x3D challenge response after receiving 0x3C.
@ FAILED
Exchange failed (timeout, retries exhausted, or radio error).
@ SUCCESS
Exchange completed successfully; device acknowledged.
@ WAIT_FIRST_RESPONSE
Listening for first response. This may be a challenge (0x3C) or the final response.
@ WAIT_FINAL_RESPONSE
Listening for the authenticated final response (e.g., status frame).
std::function< ReplyDisposition(const IoFrame *parsed, const RadioRxPacket &packet)> ReplyHandler
Invoked for every packet the radio delivers during a listen, before the listen decides whether to kee...
ReplyDisposition
What the caller wants done with the frame a listen just received.
@ ACCEPT
This is the frame the caller was waiting for — stop listening, return ACCEPTED.
@ ABORT
An explicit refusal (e.g. CMD_ERROR_RESP) — stop listening, return ABORTED.
@ IGNORE
Unparsable / not ours / wrong exchange — keep listening.
ListenPolicy
Which channels a listen covers.
@ ROTATE_SKIPPING_REQUEST
The two channels that are not the request channel. Roll-call.
@ ROTATE_ALL_CHANNELS
CH1->CH2->CH3->CH1. Broadcast whose reply channel is unknown.
@ HOLD_REQUEST_CHANNEL
Never retunes, never slices. Unicast replies.
ListenOutcome
How one call to ExchangeEngine::listen() ended.
@ ABORTED
The handler returned ReplyDisposition::ABORT for some received frame.
@ ACCEPTED
The handler returned ReplyDisposition::ACCEPT for some received frame.
@ TIMED_OUT
spec.window_ms elapsed with no ACCEPT/ABORT.
IO-Homecontrol 2W frame container: control bytes, IoFrame and (de)serialization.
Radio abstraction layer for IO-Homecontrol.
Parsed IO‑Homecontrol frame (CTRL0/1 + addresses + command + data).
How one listen window is to be spent — everything ExchangeEngine::listen() needs; everything else is ...
uint32_t request_freq
Channel the request went out on (Hz).
uint32_t window_ms
Total time budget for this listen, in milliseconds.
uint32_t linger_dwell_ms
Length of the preamble/sync extension, in milliseconds.
ListenPolicy policy
Which channels this listen covers.
bool linger_on_preamble
Extend the listen instead of hopping while the chip reports a preamble or sync word,...
uint32_t dwell_ms
Per-channel dwell for the ROTATE_* policies, in milliseconds; ignored by ListenPolicy::HOLD_REQUEST_C...
bool hop_after_ignored_frame
Hop after a frame the handler ignored.
std::function< void()> on_hop
Called on every hop, for callers that count hops in their own telemetry (pairing does; the exchange l...
Raw packet received from the radio.
Context for a single inbound authentication (device‑initiated command).
IoFrame challenge
The 0x3C challenge frame we sent (needed to verify 0x3D response).
InboundAuthState state
Current authentication state.
Context carried across one outbound authenticated exchange.
uint32_t first_response_ms
Timestamp when the first valid response arrived (for RTT/timing).
uint8_t try_index
Current retry attempt (1‑based within EXCHANGE_RETRY_COUNT).
IoFrame rx
Most recent candidate frame received during the exchange.
uint32_t exchange_start_ms
Timestamp when the exchange attempt began (millis).
uint32_t wait_ms
Current timeout window for the active wait (ms).
OutboundExchangeState state
Current state machine state.
bool saw_challenge
True if a 0x3C challenge was received during this exchange.