Home IO Control
ESPHome add-on for IO-Homecontrol devices
Loading...
Searching...
No Matches
proto_sizes.h
Go to the documentation of this file.
1#pragma once
2
3/// @file proto_sizes.h
4/// @brief Fundamental IO-Homecontrol frame and crypto size constants.
5/// @ingroup hioc_protocol
6///
7/// These sizes are the lowest layer of the protocol model: node-ID widths,
8/// AES/HMAC sizes and frame bounds. They live in their own header so the other
9/// protocol headers can depend on them without pulling in the full frame API.
10
11#include <cstdint>
12
13namespace esphome {
14namespace home_io_control {
15
16// ============================================================================
17// Frame and Crypto Sizes
18// ============================================================================
19
20static constexpr uint8_t NODE_ID_SIZE = 3; ///< Device/node addresses are 3 bytes (e.g., "123ABC")
21static constexpr uint8_t NODE_ID_STRING_SIZE = (NODE_ID_SIZE * 2) + 1; ///< Uppercase hex node ID plus null terminator
22static constexpr uint8_t HMAC_SIZE = 6; ///< Authentication HMAC is 6 bytes (truncated AES output)
23static constexpr uint8_t AES_KEY_SIZE = 16; ///< AES-128 key size
24static constexpr uint8_t AES_BLOCK_SIZE = 16; ///< AES block size
25static constexpr uint8_t IV_SIZE = 16; ///< Initialization vector size for AES
26static constexpr uint8_t IV_PADDING = 0x55; ///< Padding byte used in IV construction
27static constexpr uint8_t BITS_PER_BYTE = 8; ///< Number of bits in one protocol byte
28
29static constexpr uint8_t FRAME_MIN_SIZE = 9; ///< Minimum frame: CTRL0+CTRL1+DST(3)+SRC(3)+CMD(1)
30
31/// Largest frame length CTRL0's 5-bit length field (bits [4:0], `length - 1`) can express.
32/// This is the wire-format bound on the *declared* portion of a frame — the part CTRL0's length
33/// bits describe and `parse()`/`serialize()`/`set_cmd()` size against. It is not expressed here
34/// as `CTRL0_LENGTH_MASK + 1` because `CTRL0_LENGTH_MASK` lives in `proto_frame.h`, which
35/// includes this header — referencing it back here would be a circular include. `proto_frame.h`
36/// carries a `static_assert` tying the two together right next to `CTRL0_LENGTH_MASK`'s
37/// declaration, so this literal cannot silently drift from the mask that actually defines it.
38static constexpr uint8_t FRAME_MAX_DECLARED_SIZE = 32;
39
40// `FRAME_MAX_DECLARED_SIZE` below (and a handful of chip constants in the radio headers) is a
41// plain code span, not \ref: doxygen 1.18 cannot resolve \ref to a namespace-scope constexpr in
42// a whole-project build (it resolves fine in isolation). Restoring \ref fails the build under
43// WARN_AS_ERROR — leave these as code spans; autolinking still picks them up.
44/// Historical name for `FRAME_MAX_DECLARED_SIZE`, kept as an alias rather than a second
45/// literal so the two names can never disagree — most call sites (`set_cmd`, `serialize`,
46/// `parse`, every fixed-size frame buffer that only ever holds a declared-length frame) predate
47/// the trailer/wire distinction and still read most naturally as "the max frame size".
48static constexpr uint8_t FRAME_MAX_SIZE = FRAME_MAX_DECLARED_SIZE;
49
50static constexpr uint8_t FRAME_MAX_DATA_SIZE = 23; ///< Maximum data bytes after command ID (declared length - header)
51static constexpr uint8_t FRAME_CMD_OFFSET = 8; ///< Byte offset of the command ID in a raw wire buffer
52
53/// Size of the on-air CRC-CCITT trailer appended after every frame (declared bytes, plus the
54/// out-of-length MAC trailer when present).
55static constexpr uint8_t FRAME_CRC_SIZE = 2;
56
57/// Largest out-of-length authenticator a frame can carry. A 1W CMD 0x30 "add controller" payload
58/// (enc_key[16] + man_id[1] + data[1] + sequence[2] = 20 bytes) plus its 9-byte header is 29
59/// bytes — already representable in CTRL0's 5-bit field — but its 6-byte MAC does not fit inside
60/// the same field's remaining headroom (29 declared + 6 MAC = 35, unrepresentable in 5 bits), so
61/// the MAC rides after the declared length instead, still under the CRC. The iohomecontrol
62/// reference implementation's `_p0x30` packet struct omits an `hmac` field entirely (unlike its
63/// `_p0x2e`, whose MAC sits inside the declared length).
64static constexpr uint8_t FRAME_MAX_TRAILER_SIZE = HMAC_SIZE;
65
66/// Largest number of bytes a buffer must hold to receive or transmit any frame this project
67/// knows about, trailer and CRC included: `FRAME_MAX_DECLARED_SIZE` (what CTRL0 can declare)
68/// + @ref FRAME_MAX_TRAILER_SIZE (the out-of-length MAC, when present) + @ref FRAME_CRC_SIZE.
69/// This is the *wire* bound — distinct from `FRAME_MAX_DECLARED_SIZE`, which is the
70/// *declared* bound `set_cmd()` still enforces. A buffer sized to the declared bound alone
71/// truncates a MAC-bearing frame; use this constant for any buffer that must survive one intact.
73
74} // namespace home_io_control
75} // namespace esphome
static constexpr uint8_t FRAME_MAX_DECLARED_SIZE
Largest frame length CTRL0's 5-bit length field (bits [4:0], length - 1) can express.
Definition proto_sizes.h:38
static constexpr uint8_t BITS_PER_BYTE
Number of bits in one protocol byte.
Definition proto_sizes.h:27
static constexpr uint8_t NODE_ID_SIZE
Device/node addresses are 3 bytes (e.g., "123ABC").
Definition proto_sizes.h:20
static constexpr uint8_t AES_BLOCK_SIZE
AES block size.
Definition proto_sizes.h:24
static constexpr uint8_t FRAME_MIN_SIZE
Minimum frame: CTRL0+CTRL1+DST(3)+SRC(3)+CMD(1).
Definition proto_sizes.h:29
static constexpr uint8_t FRAME_MAX_DATA_SIZE
Maximum data bytes after command ID (declared length - header).
Definition proto_sizes.h:50
static constexpr uint8_t HMAC_SIZE
Authentication HMAC is 6 bytes (truncated AES output).
Definition proto_sizes.h:22
static constexpr uint8_t FRAME_MAX_SIZE
Historical name for FRAME_MAX_DECLARED_SIZE, kept as an alias rather than a second literal so the two...
Definition proto_sizes.h:48
static constexpr uint8_t NODE_ID_STRING_SIZE
Uppercase hex node ID plus null terminator.
Definition proto_sizes.h:21
static constexpr uint8_t FRAME_MAX_WIRE_SIZE
Largest number of bytes a buffer must hold to receive or transmit any frame this project knows about,...
Definition proto_sizes.h:72
static constexpr uint8_t FRAME_CRC_SIZE
Size of the on-air CRC-CCITT trailer appended after every frame (declared bytes, plus the out-of-leng...
Definition proto_sizes.h:55
static constexpr uint8_t FRAME_MAX_TRAILER_SIZE
Largest out-of-length authenticator a frame can carry.
Definition proto_sizes.h:64
static constexpr uint8_t AES_KEY_SIZE
AES-128 key size.
Definition proto_sizes.h:23
static constexpr uint8_t IV_PADDING
Padding byte used in IV construction.
Definition proto_sizes.h:26
static constexpr uint8_t IV_SIZE
Initialization vector size for AES.
Definition proto_sizes.h:25
static constexpr uint8_t FRAME_CMD_OFFSET
Byte offset of the command ID in a raw wire buffer.
Definition proto_sizes.h:51