modules/woz_matter/include/matter_tlv.h
openaliro/openaliro
Module

matter_tlv.h

Matter TLV codec (Matter Core spec, Appendix A).

modules/woz_matter/include/matter_tlv.h3 documented symbols

Overview

Matter TLV codec (Matter Core spec, Appendix A). This is NOT the BER/DER-TLV in modules/woz_aliro_stack/src/protocol/tlv.h. Matter uses its own encoding: one control byte carrying a 3-bit tag control and a 5-bit element type, then 0-8 tag octets, then the value, all little-endian. The two share a name and nothing else, so they stay separate.

depends on matter_status.h  ·  used by matter_im.h matter_attest.c matter_case.c matter_fabric.c matter_pase.c matter_tlv.c

API

Ctypedef uint64_t matter_tlv_tag_t

modules/woz_matter/include/matter_tlv.h:53

TLV tag type: a 64-bit unsigned integer encoding context, tag form, and tag number.

Cstruct matter_tlv_writer

modules/woz_matter/include/matter_tlv.h:109

Encoder state. Errors are STICKY: the first failure is latched into rc and every later put becomes a no-op, so a long encode sequence is checked once at matter_tlv_writer_finish() instead of after every call. That is the shape that keeps call sites readable, and it cannot silently truncate -- finish() returns the latched error.

Cstruct matter_tlv_reader

modules/woz_matter/include/matter_tlv.h:190

---------------------------------------------------------------- decoder --- Every byte here arrives from a peer, so the decoder's job is as much refusal as decoding. Two properties it must hold, and both are structural rather than checked: 1. NO RECURSION. Skipping an unentered container walks forward with a nesting counter capped at MATTER_TLV_MAX_DEPTH. A recursive-descent skip would let a peer choose this firmware's stack depth, on a part where the system work queue was measured with 528 B to spare. 2. NO COPYING. Strings and octet strings are returned as a pointer into the caller's buffer, so decoding allocates nothing and cannot truncate. The pointer is valid exactly as long as that buffer is. Iteration is CHIP-shaped because the shape is right: next() moves along the current level and steps OVER a container it was not told to enter; enter() descends; exit() skips whatever is left of the current container and lands just past its end marker.

##define MATTER_TLV_SPECIAL_PROFILE 0xFFFFFFFFu

modules/woz_matter/include/matter_tlv.h:44

Profile ID reserved for anonymous and context-specific tags (TLVTags.h:74).

##define MATTER_TLV_COMMON_PROFILE 0x00000000u

modules/woz_matter/include/matter_tlv.h:46

The Matter common profile (TLVTags.h:97).

##define MATTER_TLV_ANON_TAG_NUM 0x00000100u

modules/woz_matter/include/matter_tlv.h:48

One past kContextTagMaxNum, so it cannot collide with a context tag (TLVTags.h:34-35).

##define MATTER_TLV_ANON MATTER_TLV_TAG(MATTER_TLV_SPECIAL_PROFILE, MATTER_TLV_ANON_TAG_NUM)

modules/woz_matter/include/matter_tlv.h:59

Anonymous tag: no tag octets on the wire.

##define MATTER_TLV_CTX(n) MATTER_TLV_TAG(MATTER_TLV_SPECIAL_PROFILE, (uint8_t)(n))

modules/woz_matter/include/matter_tlv.h:61

Context-specific tag, 0..255. The common case inside a structure.

##define MATTER_TLV_COMMON(n) MATTER_TLV_TAG(MATTER_TLV_COMMON_PROFILE, (n))

modules/woz_matter/include/matter_tlv.h:63

Common-profile tag.

##define MATTER_TLV_PROFILE(profile, n) MATTER_TLV_TAG((profile), (n))

modules/woz_matter/include/matter_tlv.h:65

Explicit profile tag. Encodes implicit if it matches the writer's implicit profile.

##define MATTER_TLV_STRUCTURE 0x15u

modules/woz_matter/include/matter_tlv.h:68

Container element types, values as on the wire (TLVTypes.h:83-85).

##define MATTER_TLV_ARRAY 0x16u

modules/woz_matter/include/matter_tlv.h:69

##define MATTER_TLV_LIST 0x17u

modules/woz_matter/include/matter_tlv.h:70

##define MATTER_TLV_END MATTER_END

modules/woz_matter/include/matter_tlv.h:77

##define MATTER_TLV_OK MATTER_OK

modules/woz_matter/include/matter_tlv.h:78

##define MATTER_TLV_E_NOSPACE MATTER_E_NOSPACE

modules/woz_matter/include/matter_tlv.h:79

##define MATTER_TLV_E_INVAL MATTER_E_INVAL

modules/woz_matter/include/matter_tlv.h:80

##define MATTER_TLV_E_DEPTH MATTER_E_DEPTH

modules/woz_matter/include/matter_tlv.h:81

##define MATTER_TLV_E_STATE MATTER_E_STATE

modules/woz_matter/include/matter_tlv.h:82

##define MATTER_TLV_E_TRUNC MATTER_E_TRUNC

modules/woz_matter/include/matter_tlv.h:83

##define MATTER_TLV_E_TYPE MATTER_E_TYPE

modules/woz_matter/include/matter_tlv.h:84

##define MATTER_TLV_MAX_DEPTH 10

modules/woz_matter/include/matter_tlv.h:100

Fvoid matter_tlv_writer_init(struct matter_tlv_writer *w, uint8_t *buf, size_t cap)

modules/woz_matter/include/matter_tlv.h:120

Bind an output buffer. Always succeeds; a NULL buffer just latches E_INVAL on first use.

Fvoid matter_tlv_writer_set_implicit_profile(struct matter_tlv_writer *w, uint32_t profile)

modules/woz_matter/include/matter_tlv.h:126

Nominate a profile ID to encode with the shorter implicit tag control. Without this every profile tag is written fully qualified.

Fint matter_tlv_put_bool(struct matter_tlv_writer *w, matter_tlv_tag_t tag, bool v)

modules/woz_matter/include/matter_tlv.h:128

Fint matter_tlv_put_null(struct matter_tlv_writer *w, matter_tlv_tag_t tag)

modules/woz_matter/include/matter_tlv.h:129

Fint matter_tlv_put_i64(struct matter_tlv_writer *w, matter_tlv_tag_t tag, int64_t v)

modules/woz_matter/include/matter_tlv.h:132

Signed integer, encoded in the smallest width that holds the value.

Fint matter_tlv_put_u64(struct matter_tlv_writer *w, matter_tlv_tag_t tag, uint64_t v)

modules/woz_matter/include/matter_tlv.h:134

Unsigned integer, encoded in the smallest width that holds the value.

Fint matter_tlv_put_utf8(struct matter_tlv_writer *w, matter_tlv_tag_t tag, const char *s, size_t len)

modules/woz_matter/include/matter_tlv.h:137

UTF-8 string. Not validated as UTF-8; the caller owns that.

Fint matter_tlv_put_bytes(struct matter_tlv_writer *w, matter_tlv_tag_t tag, const uint8_t *b, size_t len)

modules/woz_matter/include/matter_tlv.h:139

Fint matter_tlv_put_encoded(struct matter_tlv_writer *w, matter_tlv_tag_t tag, const uint8_t *elem, size_t len)

modules/woz_matter/include/matter_tlv.h:156

Copy an already-encoded element, re-tagged. For a value this node stored but never decoded -- an ACL is a list of structures, and re-encoding one would mean understanding a shape that only the commissioner cares about. Both tags must be context tags, which reduces re-tagging to a one-byte substitution; anything else would require rebuilding a header around a value whose type is unknown here, which is the exact thing this exists to avoid. @param elem one complete element, control byte first. @return MATTER_TLV_OK, or E_INVAL if either tag is not context-specific.

Fint matter_tlv_start_container(struct matter_tlv_writer *w, matter_tlv_tag_t tag, uint8_t type)

modules/woz_matter/include/matter_tlv.h:159

Fint matter_tlv_end_container(struct matter_tlv_writer *w)

modules/woz_matter/include/matter_tlv.h:160

Fint matter_tlv_writer_finish(struct matter_tlv_writer *w, size_t *out_len)

modules/woz_matter/include/matter_tlv.h:168

Close out the encoding. @param out_len receives the encoded length on success; untouched on failure. @return MATTER_TLV_OK, or the first error latched during encoding, or MATTER_TLV_E_STATE if a container is still open.

Fvoid matter_tlv_reader_init(struct matter_tlv_reader *r, const uint8_t *buf, size_t len)

modules/woz_matter/include/matter_tlv.h:212

Fvoid matter_tlv_reader_set_implicit_profile(struct matter_tlv_reader *r, uint32_t profile)

modules/woz_matter/include/matter_tlv.h:219

Supply the profile ID that implicit-profile tags decode to. Without it, an implicit tag is rejected rather than guessed -- there is no safe default, and inventing one would silently mislabel a tag.

Fint matter_tlv_next(struct matter_tlv_reader *r)

modules/woz_matter/include/matter_tlv.h:225

Advance to the next element at the current level. @return MATTER_TLV_OK, MATTER_TLV_END at the end of the level, or an error.

Fmatter_tlv_tag_t matter_tlv_tag(const struct matter_tlv_reader *r)

modules/woz_matter/include/matter_tlv.h:228

Tag of the loaded element. Undefined unless the last next() returned OK.

Fuint8_t matter_tlv_element_type(const struct matter_tlv_reader *r)

modules/woz_matter/include/matter_tlv.h:230

Raw wire element type of the loaded element.

Fbool matter_tlv_is_container(const struct matter_tlv_reader *r)

modules/woz_matter/include/matter_tlv.h:231

Fint matter_tlv_get_bool(const struct matter_tlv_reader *r, bool *out)

modules/woz_matter/include/matter_tlv.h:233

Fint matter_tlv_get_u64(const struct matter_tlv_reader *r, uint64_t *out)

modules/woz_matter/include/matter_tlv.h:234

Fint matter_tlv_get_i64(const struct matter_tlv_reader *r, int64_t *out)

modules/woz_matter/include/matter_tlv.h:235

Fint matter_tlv_get_bytes(const struct matter_tlv_reader *r, const uint8_t **out, size_t *len)

modules/woz_matter/include/matter_tlv.h:237

Octet string. @param out receives a pointer INTO the caller's buffer; nothing is copied.

Fint matter_tlv_get_utf8(const struct matter_tlv_reader *r, const char **out, size_t *len)

modules/woz_matter/include/matter_tlv.h:239

UTF-8 string, not NUL-terminated and not validated as UTF-8. Borrowed like get_bytes.

Fint matter_tlv_enter(struct matter_tlv_reader *r)

modules/woz_matter/include/matter_tlv.h:242

Descend into the loaded container.

Fint matter_tlv_exit(struct matter_tlv_reader *r)

modules/woz_matter/include/matter_tlv.h:244

Skip whatever remains of the current container and land just past its end marker.