Home IO Control
ESPHome add-on for IO-Homecontrol devices
Toggle main menu visibility
Loading...
Searching...
No Matches
hub_pairing.h
Go to the documentation of this file.
1
#pragma once
2
3
/// @file hub_pairing.h
4
/// @brief Internal pairing-state model for hub‑owned discovery and key‑exchange flows.
5
/// @ingroup hioc_hub
6
///
7
/// This header defines the state machine enum and context structures for the
8
/// three‑phase pairing procedure (the flow itself is implemented by PairingEngine),
9
/// which temporarily tracks a newly paired device in the controller's runtime
10
/// registry and installs the system key on the device:
11
///
12
/// Phase 1 — Discovery (broadcast 0x28 → device responds 0x29 → confirm 0x2C → ack 0x2D):
13
/// Controller broadcasts a discovery packet on the primary channel. A device in
14
/// pairing mode (PROG button pressed) responds with its node ID and type/subtype.
15
/// The controller validates the response and extracts device metadata, then sends a
16
/// discover-confirm (0x2C) directly to that device and — unless the `pairing_discover_confirm`
17
/// tuning mode is `skip` — waits up to a few seconds for its 0x2D before proceeding. This step
18
/// never fails the attempt; see PairingEngine::run_discover_confirm_step_().
19
///
20
/// Phase 2 — Authenticated Key Exchange (0x31 → 0x3C → 0x32 → 0x33):
21
/// The controller sends CMD_KEY_INIT (0x31) to the device. The device challenges
22
/// with CMD_CHALLENGE_REQ (0x3C). The controller proves knowledge of the system
23
/// key with CMD_CHALLENGE_RESP (0x3D) and simultaneously sends the encrypted system
24
/// key via CMD_KEY_TRANSFER (0x32). The device confirms with CMD_KEY_CONFIRM (0x33).
25
///
26
/// Phase 3 — Configuration (CMD_SET_CONFIG1):
27
/// The controller sends a configuration frame (0x6F) to enable automatic status
28
/// updates from the device. This phase completes even if the config frame fails;
29
/// the device will still operate in polled mode.
30
///
31
/// All frames use the standard authenticated exchange flow (state types in
32
/// hub_exchange.h, implementation in ExchangeEngine). PairingEngine serializes these
33
/// phases, logs the YAML metadata the user should add, and keeps the paired device
34
/// in the current runtime registry until reboot.
35
36
#include "
proto_device_model.h
"
37
#include "
proto_frame.h
"
38
#include "
radio_interface.h
"
39
#include <cstdint>
40
#include <string>
41
42
namespace
esphome
{
43
namespace
home_io_control
{
44
45
namespace
pairing
{
46
47
/// @brief State machine for the three‑phase pairing flow.
48
enum class
PairingState
: uint8_t {
49
IDLE,
///< No pairing in progress; idle state.
50
TX_DISCOVER
,
///< Discovery broadcast (0x28) sent; awaiting device response.
51
WAIT_DISCOVER_RESPONSE
,
///< Listening for discovery response (0x29) from a device in pairing mode.
52
TX_DISCOVER_CONFIRM
,
///< Discovery-confirm (0x2C) sent to the discovered device.
53
WAIT_DISCOVER_CONFIRM
,
///< Listening for the device's discovery-confirm ack (0x2D).
54
TX_KEY_INIT
,
///< Key‑init (0x31) sent to the discovered device.
55
WAIT_KEY_CHALLENGE
,
///< Waiting for challenge (0x3C) from device as part of key transfer.
56
TX_KEY_TRANSFER
,
///< Key‑transfer (0x32) sent with encrypted system key.
57
WAIT_KEY_CONFIRM
,
///< Waiting for key‑confirm (0x33) from device (key receipt acknowledgement).
58
REGISTER_DEVICE
,
///< Registering device in the runtime registry for the current boot.
59
COMPLETE
,
///< Pairing completed successfully; device ready for use.
60
FAILED
,
///< Pairing failed (timeout, radio error, or protocol violation).
61
};
62
63
/// @brief Context object that lives for the duration of a single pairing attempt.
64
struct
PairingContext
{
65
PairingState
state
{
PairingState::IDLE
};
///< Current state machine state.
66
IoDevice
device
{};
///< Resolved device metadata after discovery (node_id, type, subtype, etc.).
67
IoFrame
req
{};
///< Outbound frame buffer (reused across all phases).
68
IoFrame
resp
{};
///< Inbound frame buffer (holds key‑confirm response).
69
IoFrame
rx
{};
///< Raw RX frame during waiting phases (discovery, challenge, confirm).
70
IoFrame
key_init
{};
///< Key‑init frame retained for key‑transfer IV derivation.
71
RadioRxPacket
packet
{};
///< Raw radio capture for the current phase.
72
std::string
device_id
;
///< Hex string representation of the paired node ID.
73
bool
discovery_metadata_complete
{
false
};
///< True when discovery carried type/subtype bytes.
74
bool
discovery_low_power
{
false
};
///< True when discovery reported POWER_SAVE_LOW_POWER.
75
};
76
77
/// @brief What PairingEngine::run_discover_confirm_step_() actually observed.
78
///
79
/// Not stored in PairingContext — nothing downstream reads it, so it is returned directly to the
80
/// caller, which logs the details (reply channel, try number, elapsed time) and otherwise ignores
81
/// the result: the step never fails a pairing attempt (see run_discover_confirm_step_()'s doc).
82
enum class
DiscoverConfirmResult
: uint8_t {
83
SKIPPED
,
///< `pairing_discover_confirm` tuning mode is `skip` — no 0x2C was sent.
84
ACKED
,
///< The device answered with CMD_DISCOVER_CONFIRM_ACK (0x2D).
85
ERROR_REPLY
,
///< The device answered with CMD_ERROR_RESP.
86
NO_REPLY
,
///< Every try was silent (or every transmit failed).
87
};
88
89
}
// namespace pairing
90
91
/// @brief Get a short, log/telemetry-friendly name for a pairing state.
92
/// @param state Pairing state.
93
/// @return Null-terminated lowercase string such as "wait_key_challenge".
94
inline
const
char
*
pairing_stage_name
(
pairing::PairingState
state) {
95
switch
(state) {
96
case
pairing::PairingState::IDLE
:
97
return
"idle"
;
98
case
pairing::PairingState::TX_DISCOVER
:
99
return
"tx_discover"
;
100
case
pairing::PairingState::WAIT_DISCOVER_RESPONSE
:
101
return
"wait_discover_response"
;
102
case
pairing::PairingState::TX_DISCOVER_CONFIRM
:
103
return
"tx_discover_confirm"
;
104
case
pairing::PairingState::WAIT_DISCOVER_CONFIRM
:
105
return
"wait_discover_confirm"
;
106
case
pairing::PairingState::TX_KEY_INIT
:
107
return
"tx_key_init"
;
108
case
pairing::PairingState::WAIT_KEY_CHALLENGE
:
109
return
"wait_key_challenge"
;
110
case
pairing::PairingState::TX_KEY_TRANSFER
:
111
return
"tx_key_transfer"
;
112
case
pairing::PairingState::WAIT_KEY_CONFIRM
:
113
return
"wait_key_confirm"
;
114
case
pairing::PairingState::REGISTER_DEVICE
:
115
return
"register_device"
;
116
case
pairing::PairingState::COMPLETE
:
117
return
"complete"
;
118
case
pairing::PairingState::FAILED
:
119
default
:
120
return
"failed"
;
121
}
122
}
123
124
}
// namespace home_io_control
125
}
// namespace esphome
esphome::home_io_control::pairing
Definition
hub_pairing.h:45
esphome::home_io_control::pairing::DiscoverConfirmResult
DiscoverConfirmResult
What PairingEngine::run_discover_confirm_step_() actually observed.
Definition
hub_pairing.h:82
esphome::home_io_control::pairing::DiscoverConfirmResult::ERROR_REPLY
@ ERROR_REPLY
The device answered with CMD_ERROR_RESP.
Definition
hub_pairing.h:85
esphome::home_io_control::pairing::DiscoverConfirmResult::SKIPPED
@ SKIPPED
pairing_discover_confirm tuning mode is skip — no 0x2C was sent.
Definition
hub_pairing.h:83
esphome::home_io_control::pairing::DiscoverConfirmResult::NO_REPLY
@ NO_REPLY
Every try was silent (or every transmit failed).
Definition
hub_pairing.h:86
esphome::home_io_control::pairing::DiscoverConfirmResult::ACKED
@ ACKED
The device answered with CMD_DISCOVER_CONFIRM_ACK (0x2D).
Definition
hub_pairing.h:84
esphome::home_io_control::pairing::PairingState
PairingState
State machine for the three‑phase pairing flow.
Definition
hub_pairing.h:48
esphome::home_io_control::pairing::PairingState::REGISTER_DEVICE
@ REGISTER_DEVICE
Registering device in the runtime registry for the current boot.
Definition
hub_pairing.h:58
esphome::home_io_control::pairing::PairingState::TX_DISCOVER
@ TX_DISCOVER
Discovery broadcast (0x28) sent; awaiting device response.
Definition
hub_pairing.h:50
esphome::home_io_control::pairing::PairingState::WAIT_DISCOVER_RESPONSE
@ WAIT_DISCOVER_RESPONSE
Listening for discovery response (0x29) from a device in pairing mode.
Definition
hub_pairing.h:51
esphome::home_io_control::pairing::PairingState::COMPLETE
@ COMPLETE
Pairing completed successfully; device ready for use.
Definition
hub_pairing.h:59
esphome::home_io_control::pairing::PairingState::TX_DISCOVER_CONFIRM
@ TX_DISCOVER_CONFIRM
Discovery-confirm (0x2C) sent to the discovered device.
Definition
hub_pairing.h:52
esphome::home_io_control::pairing::PairingState::WAIT_KEY_CHALLENGE
@ WAIT_KEY_CHALLENGE
Waiting for challenge (0x3C) from device as part of key transfer.
Definition
hub_pairing.h:55
esphome::home_io_control::pairing::PairingState::WAIT_KEY_CONFIRM
@ WAIT_KEY_CONFIRM
Waiting for key‑confirm (0x33) from device (key receipt acknowledgement).
Definition
hub_pairing.h:57
esphome::home_io_control::pairing::PairingState::TX_KEY_INIT
@ TX_KEY_INIT
Key‑init (0x31) sent to the discovered device.
Definition
hub_pairing.h:54
esphome::home_io_control::pairing::PairingState::TX_KEY_TRANSFER
@ TX_KEY_TRANSFER
Key‑transfer (0x32) sent with encrypted system key.
Definition
hub_pairing.h:56
esphome::home_io_control::pairing::PairingState::IDLE
@ IDLE
No pairing in progress; idle state.
Definition
hub_pairing.h:49
esphome::home_io_control::pairing::PairingState::FAILED
@ FAILED
Pairing failed (timeout, radio error, or protocol violation).
Definition
hub_pairing.h:60
esphome::home_io_control::pairing::PairingState::WAIT_DISCOVER_CONFIRM
@ WAIT_DISCOVER_CONFIRM
Listening for the device's discovery-confirm ack (0x2D).
Definition
hub_pairing.h:53
esphome::home_io_control
Definition
device_registry.cpp:13
esphome::home_io_control::ExchangeOutcome::FAILED
@ FAILED
No usable reply; the device may never have heard the request.
Definition
exchange_engine.h:62
esphome::home_io_control::pairing_stage_name
const char * pairing_stage_name(pairing::PairingState state)
Get a short, log/telemetry-friendly name for a pairing state.
Definition
hub_pairing.h:94
esphome
Definition
device_registry.cpp:12
proto_device_model.h
IO-Homecontrol device-type model, capabilities and runtime device state.
proto_frame.h
IO-Homecontrol 2W frame container: control bytes, IoFrame and (de)serialization.
radio_interface.h
Radio abstraction layer for IO-Homecontrol.
esphome::home_io_control::IoDevice
Runtime state of a paired IO‑Homecontrol device.
Definition
proto_device_model.h:321
esphome::home_io_control::IoFrame
Parsed IO‑Homecontrol frame (CTRL0/1 + addresses + command + data).
Definition
proto_frame.h:93
esphome::home_io_control::RadioRxPacket
Raw packet received from the radio.
Definition
radio_interface.h:115
esphome::home_io_control::pairing::PairingContext
Context object that lives for the duration of a single pairing attempt.
Definition
hub_pairing.h:64
esphome::home_io_control::pairing::PairingContext::req
IoFrame req
Outbound frame buffer (reused across all phases).
Definition
hub_pairing.h:67
esphome::home_io_control::pairing::PairingContext::discovery_low_power
bool discovery_low_power
True when discovery reported POWER_SAVE_LOW_POWER.
Definition
hub_pairing.h:74
esphome::home_io_control::pairing::PairingContext::state
PairingState state
Current state machine state.
Definition
hub_pairing.h:65
esphome::home_io_control::pairing::PairingContext::resp
IoFrame resp
Inbound frame buffer (holds key‑confirm response).
Definition
hub_pairing.h:68
esphome::home_io_control::pairing::PairingContext::packet
RadioRxPacket packet
Raw radio capture for the current phase.
Definition
hub_pairing.h:71
esphome::home_io_control::pairing::PairingContext::device
IoDevice device
Resolved device metadata after discovery (node_id, type, subtype, etc.).
Definition
hub_pairing.h:66
esphome::home_io_control::pairing::PairingContext::key_init
IoFrame key_init
Key‑init frame retained for key‑transfer IV derivation.
Definition
hub_pairing.h:70
esphome::home_io_control::pairing::PairingContext::device_id
std::string device_id
Hex string representation of the paired node ID.
Definition
hub_pairing.h:72
esphome::home_io_control::pairing::PairingContext::discovery_metadata_complete
bool discovery_metadata_complete
True when discovery carried type/subtype bytes.
Definition
hub_pairing.h:73
esphome::home_io_control::pairing::PairingContext::rx
IoFrame rx
Raw RX frame during waiting phases (discovery, challenge, confirm).
Definition
hub_pairing.h:69
components
home_io_control
hub_pairing.h
Generated by
1.18.0