66 uint8_t payload[DEVICE_NAME_WRITE_PAYLOAD_SIZE],
67 std::string &normalized_name);
216 uint8_t
src[NODE_ID_SIZE]{};
383 "the Command Originator byte is the fourth byte of the last-command record; if one "
384 "offset moves the other must move with it");
468 [[nodiscard]]
bool ok()
const {
return status == TRANSFER_STATUS_ACCEPTED ||
status == TRANSFER_STATUS_ADAPTED; }
489bool decode_transfer_block(
const IoFrame &f, uint8_t handle, uint16_t chunk,
const uint8_t *&out, uint8_t &out_len);
constexpr uint8_t STATUS_UPDATE_EVENT_LENGTH_OFFSET
Number of event-data bytes that follow.
bool decode_limitation_status(const IoFrame &f, LimitationStatus &out)
Decode a limitation reply (assumed layout, see LimitationStatus).
uint8_t discovery_slot_count(const uint8_t addr[NODE_ID_SIZE])
Number of answer slots a discovery request opens.
static constexpr uint8_t ADDRESS_SUFFIX_DISCOVERY_255
Discovery suffix opening 255 slots.
OneWayMacStatus
Outcome of checking the out-of-length MAC trailer (IoFrame::has_mac) on a decoded CMD_ONEWAY_ADD_CONT...
@ NOT_PRESENT
frame.has_mac was false; nothing to verify.
bool decode_status_update_event(const IoFrame &frame, StatusUpdateEvent &out)
Decode the event header of a CMD_STATUS_UPDATE.
void encode_broadcast_address(DeviceType type, uint8_t out[NODE_ID_SIZE])
Encode a device type into its typed-broadcast destination address — the exact inverse of broadcast_ta...
uint32_t limitation_time_seconds(uint8_t time_raw)
Remaining time of a limitation in seconds.
OneWayAddControllerDecodeError decode_1w_add_controller(const IoFrame &frame, OneWayAdoptedKey &out)
Decode a CMD_ONEWAY_ADD_CONTROLLER (0x30) frame into a recovered controller identity.
static constexpr uint16_t LATIN1_CODEPOINT_MAX
Highest Unicode code point representable in Latin-1.
static constexpr uint8_t ADDRESS_SUFFIX_BROADCAST
Suffix for "all devices of this type" broadcast.
std::optional< float > oneway_intent_to_target(uint8_t main0, uint8_t main1)
Resolve a 1W main-byte pair to an optimistic IO target position, if unambiguous.
constexpr uint8_t STATUS_UPDATE_LAST_COMMAND_OFFSET
static constexpr uint8_t ADDRESS_SUFFIX_DISCOVERY
Suffix for discovery-related broadcasts.
const char * oneway_target_label(const OneWayFrameInfo &info)
The destination label a decoded 1W frame renders as in a log line.
bool decode_limitation_request(const IoFrame &f, LimitationType &type, uint8_t ¶meter_id)
Decode a limitation request (assumed layout [selector] [parameter id] [00]).
bool decode_sun_level_event(const IoFrame &frame, uint16_t &out)
Decode the sun value of an EVENT_LOCAL_SENSOR report.
DeviceType
IO-Homecontrol node types.
@ UNKNOWN
Unknown/unspecified device.
static constexpr uint8_t DISCOVERY_SLOTS_255
Window of ADDRESS_SUFFIX_DISCOVERY_255.
constexpr uint8_t STATUS_UPDATE_ORIGINATOR_OFFSET
Offset of the Command Originator byte in a CMD_STATUS_UPDATE (0x71) payload.
LastCommandRecord decode_last_command_record(const IoFrame &frame, uint8_t base)
Decode the last-command record at base from a status-bearing payload.
OneWayAddControllerDecodeError
Decoding outcome for decode_1w_add_controller().
@ WRONG_COMMAND
frame.cmd is not CMD_ONEWAY_ADD_CONTROLLER.
@ NOT_ONEWAY
CTRL0_PROTOCOL_1W is not set — not a 1W frame at all.
@ BAD_LENGTH
Declared payload is not exactly the expected 20 bytes.
@ KEY_UNWRAP_FAILED
crypto::crypt_1w_key() itself reported failure.
static constexpr uint8_t ADDRESS_SUFFIX_MASK
Well-known address suffix values in the broadcast address space.
OneWayFrameInfo decode_1w_frame(const IoFrame &frame)
Decode a parsed 1W frame into a structured OneWayFrameInfo.
static constexpr uint8_t DEVICE_NAME_WRITE_PAYLOAD_SIZE
Fixed write payload: 15 visible chars plus trailing null/padding.
void encode_discovery_address(DeviceType type, uint8_t out[NODE_ID_SIZE])
Encode a device type into its typed discovery address, the inverse of discovery_target_type().
const char * device_name_validation_error_name(DeviceNameValidationError error)
Return a stable symbolic name for a device-name validation result.
bool decode_transfer_open_reply(const IoFrame &f, TransferOpenReply &out)
Decode a transfer-open reply (layout verified against a VELUX KLR 200 copy session).
static constexpr uint8_t ADDRESS_SUFFIX_DISCOVERY_64
Discovery suffix opening 64 slots.
@ FAILED
No usable reply; the device may never have heard the request.
DeviceNameValidationError
Validation result for outbound device-name writes.
@ UNSUPPORTED_CHAR
Name contains characters outside Latin-1.
@ TOO_LONG
Name exceeds the 15-character write limit.
@ EMPTY
Name is empty after normalization.
@ INVALID_UTF8
Name contains malformed UTF-8 bytes.
std::string trim_ascii_whitespace(const std::string &value)
Trim leading and trailing ASCII whitespace from a string.
constexpr uint8_t STATUS_UPDATE_EVENT_DATA_OFFSET
First event-data byte.
constexpr uint8_t STATUS_UPDATE_EVENT_ID_OFFSET
Event id, big-endian, 2 bytes.
static constexpr uint8_t DISCOVERY_SLOTS_32
Window of ADDRESS_SUFFIX_DISCOVERY, and the fallback.
uint16_t transfer_chunk_count(uint16_t length)
Number of CMD_UNKNOWN4A_REQ chunks that cover length bytes: ceil(length / TRANSFER_BLOCK_SIZE).
static constexpr uint8_t DEVICE_NAME_WRITE_CHAR_LIMIT
Reference write limit before the trailing null.
DeviceNameValidationError encode_device_name_payload(const std::string &name, uint8_t payload[DEVICE_NAME_WRITE_PAYLOAD_SIZE], std::string &normalized_name)
Validate and encode a user-supplied UTF-8 device name into the fixed Latin-1 write payload.
AddressClass classify_address(const uint8_t addr[NODE_ID_SIZE])
Classify an IO-Homecontrol 3-byte address.
std::string decode_device_name_payload(const uint8_t *data, uint8_t len)
Decode a device-name payload from IO-homecontrol's Latin-1 wire format into UTF-8.
DeviceType broadcast_target_type(const uint8_t addr[NODE_ID_SIZE])
Extract the target device type from a typed broadcast address.
AddressClass
Address classification categories for diagnostic purposes.
@ UNKNOWN_BROADCAST
Broadcast pattern that does not match known suffixes.
@ UNICAST
Normal device-to-device unicast address (first byte != 0x00).
@ BROADCAST_TYPE
Broadcast to specific device type with non-standard suffix.
@ BROADCAST_ALL
Broadcast to all devices of a type (address suffix 0x3F).
@ DISCOVERY
Discovery-related broadcast (address suffix 0x3B).
const char * address_class_name(AddressClass address_class)
Get a human-readable name for an address classification.
bool decode_transfer_block(const IoFrame &f, uint8_t handle, uint16_t chunk, const uint8_t *&out, uint8_t &out_len)
Decode one CMD_UNKNOWN4A_RESP data block.
LimitationType
On-air selector byte (request data[0]) choosing which resulting limit to read.
static constexpr size_t ONEWAY_INTENT_BUFFER_SIZE
Buffer size for the decoded 1W main-intent string.
static constexpr uint8_t ADDRESS_SUFFIX_DISCOVERY_128
Discovery suffix opening 128 slots.
static constexpr uint8_t DISCOVERY_SLOTS_128
Window of ADDRESS_SUFFIX_DISCOVERY_128.
static constexpr uint8_t DISCOVERY_SLOTS_64
Window of ADDRESS_SUFFIX_DISCOVERY_64.
bool decode_battery_level_event(const IoFrame &frame, uint8_t &out)
Decode the level of an EVENT_BATTERY_LEVEL_CHANGE report as a percentage.
constexpr uint8_t PRIVATE_RESPONSE_LAST_COMMAND_OFFSET
Offset of the last-command record within each status-bearing payload.
DiscoveryResponseInfo decode_discovery_response(const IoFrame &frame, IoDevice &device, std::string &device_id)
Decode a discovery-response payload (CMD_DISCOVER_RESP 0x29 or CMD_DISCOVER_SPE_RESP 0x2B — both carr...
const char * device_name_validation_error_description(DeviceNameValidationError error)
Return a human-readable explanation for a device-name validation result.
void decode_1w_main_intent(uint8_t main0, uint8_t main1, char *out, size_t out_size)
Decode the "main" position/command bytes from a 1W execute payload.
DeviceType discovery_target_type(const uint8_t addr[NODE_ID_SIZE])
Extract the device type a discovery request is restricted to.
IO-Homecontrol command IDs, result codes and protocol enumerations.
IO-Homecontrol device-type model, capabilities and runtime device state.
Fundamental IO-Homecontrol frame and crypto size constants.
Extended discovery-response fields (manufacturer, Multi Information Byte, backbone address,...
bool has_extended
data_len >= DISCOVERY_RESP_FULL_SIZE (mfr/flags/timestamp present).
uint8_t backbone[NODE_ID_SIZE]
Backbone address as reported by the device.
bool metadata_complete
data_len >= DEVICE_METADATA_SIZE (type/subtype present).
uint8_t manufacturer
Raw manufacturer ID; name via manufacturer_name().
uint8_t flags
Multi Information Byte; decode with DISCOVERY_FLAGS_* masks.
uint16_t timestamp
Device timestamp field (advances between replies).
Parsed IO‑Homecontrol frame (CTRL0/1 + addresses + command + data).
One decoded last-command record.
uint8_t commander[NODE_ID_SIZE]
Controller that last commanded the device.
bool valid
False when the payload was too short, or the record was unpopulated.
uint8_t originator
That command's Command Originator (ORIGINATOR_*).
One decoded CMD_LIMITATION_STATUS_RESP payload.
uint8_t parameter_id
data[0]; LIMITATION_PARAM_MP for the main parameter.
uint8_t originator
data[3], Command Originator that imposed the limit (ORIGINATOR_*).
uint16_t value_raw
data[1..2], big-endian, position coding (STATUS_POS_MAX = 100 %).
uint8_t time_raw
data[4], remaining-time code; see limitation_time_seconds().
Recovered controller identity from a decoded CMD_ONEWAY_ADD_CONTROLLER (0x30) frame.
uint8_t manufacturer
Manufacturer ID byte from the payload (man_id).
OneWayMacStatus mac_status
MAC-verification outcome; see OneWayMacStatus.
uint8_t system_key[AES_KEY_SIZE]
Recovered network system key (crypto::crypt_1w_key() output).
uint8_t sender_node[NODE_ID_SIZE]
Sender's node address (frame.src) — the new identity's node.
uint16_t sequence
2-byte rolling sequence from the payload (big-endian on wire).
Decoded representation of a 1W remote frame.
bool has_intent
True if originator/ACEI/intent fields were decoded.
uint8_t originator
Command originator byte (e.g., ORIGINATOR_USER_REMOTE).
DeviceType target_type
Target device class from broadcast address.
uint8_t main0
Raw first main byte (has_intent only); feeds oneway_intent_to_target().
uint8_t acei_level
ACEI priority level (0–7).
uint8_t main1
Raw second main byte (has_intent only); feeds oneway_intent_to_target().
uint8_t cmd
Command ID (e.g., CMD_EXECUTE, CMD_ACTIVATE_MODE).
AddressClass address_class
Classification of the broadcast address.
char intent[ONEWAY_INTENT_BUFFER_SIZE]
Human-readable command intent (e.g., "CLOSE").
uint8_t src[NODE_ID_SIZE]
Remote source node ID (3 bytes).
uint8_t data_len
Raw data length (for commands without decoded intent).
The event header of a well-formed CMD_STATUS_UPDATE payload.
uint8_t data_len
Number of event-data bytes; equals the payload length minus the header.
uint8_t data_offset
Payload offset of the first event-data byte (STATUS_UPDATE_EVENT_DATA_OFFSET).
uint16_t event_id
EVENT_STATUS_CHANGE for a position update, any other id for a device event report.
One decoded CMD_TRANSFER_OPEN_RESP payload.
uint8_t status
data[1]; TRANSFER_STATUS_ACCEPTED / _ADAPTED, anything else is an error.
uint16_t length
data[2..3] big-endian: bytes available to read; 0 means nothing to read.
uint8_t handle
data[0]; the first byte of every CMD_UNKNOWN4A_REQ that follows.