OpenThread_app
Loading...
Searching...
No Matches
TLV Message Buffer

TLV (Type-Length-Value) message serialization/deserialization API. More...

Macros

#define OT_APP_MSG_TLV_OK   (-1)
 Operation successful.
#define OT_APP_MSG_TLV_ERROR   (-2)
 Generic error (null ptr, invalid param).
#define OT_APP_MSG_TLV_ERROR_NO_SPACE   (-3)
 no space for new TLV
#define OT_APP_MSG_TLV_KEY_EXIST   (-4)
 Key already exists (duplicate add).
#define OT_APP_MSG_TLV_KEY_NO_EXIST   (-5)
 Key not found.
#define OT_APP_MSG_TLV_EMPTY_BUFFER   (-5)
 Buffer has no TLV data.

Functions

int8_t otapp_msg_tlv_keyAdd (uint8_t *buffer, const uint16_t bufferSize, const uint16_t key, const uint16_t valueLengthIn, uint8_t *valueIn)
 Add new TLV block to buffer if key unique and space available.
int8_t otapp_msg_tlv_keyGet (uint8_t *buffer, const uint16_t bufferSize, const uint16_t key, uint16_t *valueLengthOut, uint8_t *valueOut)
 Extract TLV value by key (optional copy to output).
int8_t otapp_msg_tlv_getBufferTotalFreeSpace (const uint8_t *buffer, const uint16_t bufferSize, uint16_t *freeBufSpaceOut)
 Get remaining free space in TLV buffer.
int8_t otapp_msg_tlv_getBufferTotalUsedSpace (const uint8_t *buffer, const uint16_t bufferSize, uint16_t *writtenBufSpaceOut)
uint16_t otapp_msg_tlv_calcualeBuffer (uint8_t keyDataLength, uint8_t cnt)

Detailed Description

TLV (Type-Length-Value) message serialization/deserialization API.

Overview

The TLV Message Buffer module provides serialization and deserialization of Type-Length-Value (TLV) data structures in a fixed-size user-provided byte buffer. Designed for constrained environments like OpenThread/CoAP payloads where dynamic allocation is avoided.

*Key features:**

  • Append unique TLV blocks (keyAdd()): key (u16) + length (u16) + value
  • Extract value by key (keyGet()): linear search with optional value copy
  • Query free space (freeBufSpaceGet()): remaining capacity calculation
  • 2-byte reserved header tracks total used bytes (writtenBytes counter)
  • Packed 4-byte TLV header (no padding): uint16_t key; uint16_t length;

*Buffer layout (exact byte-by-byte format):**

[0:1] writtenBytes (u16) | [2:5] TLV1: [key u16][len u16][value[len]] | [N:] TLV2... | [free space]
#define free
Definition unity_fixture_malloc_overrides.h:38

*Minimum size for 1 key: 2 + 4 + valueLength bytes**

*Example for valueLength=4 (TOTAL: 10 bytes minimum):**

Bytes Content Size Example Description
[0:1] writtenBytes 2B 0x000A (10) TLV data counter
[2:3] key 2B 0xAAA1 TLV identifier
[4:5] length 2B 0x0004 (4) Value bytes count
[6:9] value 4B [1,2,3,4] Actual data
TOTAL 10B Minimum buffer size

*Error handling:**

  • Strict validation: null pointers, buffer overflow, invalid sizes
  • Duplicate key detection during append
  • Empty/invalid buffer states

*Typical lifecycle:**

*Integration:**

  • CoAP options, OpenThread discovery payloads, device state serialization
  • Portable: ESP32/STM32 (little-endian, packed structs)
  • Thread-safe with external mutex (user-provided buffer)

Usage Example

This example demonstrates how to gather device URI resources, serialize them into TLV format using a thread-safe system buffer, and transmit them as a CoAP response.

#include "ot_app_msg_tlv.h"
#include "ot_app_buffer.h"
#include "ot_app_drv.h"
// Example CoAP handler implementation that sends a TLV-encoded URI list as a response.
void ad_temp_uri_well_knownCoreHandle(void *aContext, otMessage *request, const otMessageInfo *aMessageInfo)
{
int8_t result = 0;
otapp_coap_uri_t *urisList = NULL;
ot_app_size_t uriListSize = 0;
uint8_t *buffer = NULL;
uint16_t bufferSize = 0;
if (request && devDrv_)
{
// Retrieve the URI list defined in the device driver
urisList = devDrv_->uriGetList_clb();
uriListSize = devDrv_->uriGetListSize;
if(urisList == NULL || uriListSize == 0) return;
// Acquire access to the thread-safe global buffer
bufferSize = otapp_pair_uriResourcesCalculateBufSize(urisList, uriListSize);
if(buffer == NULL || bufferSize == 0)
{
OTAPP_PRINTF(TAG, "ERROR well-known/core: buffer = NULL");
return;
}
// Serialize URI data into TLV format
result = otapp_pair_uriResourcesCreate(urisList, uriListSize, buffer, &bufferSize);
if(result == OTAPP_PAIR_OK)
{
// Send the populated TLV buffer as a CoAP response
otapp_coap_sendResponse(request, aMessageInfo, buffer, bufferSize);
OTAPP_PRINTF(TAG, "well-known/core: sent resources size: %d\n", bufferSize);
}else
{
OTAPP_PRINTF(TAG, "ERROR well-known/core: uriResourcesCreate \n");
}
// unlock the buffer
}
}
// Helper function to create a TLV structure from a URI list.
int8_t otapp_pair_uriResourcesCreate(otapp_coap_uri_t *uri, uint8_t uriSize, uint8_t *bufferOut, uint16_t *bufferSizeInOut)
{
if(uri == NULL || bufferOut == NULL || bufferSizeInOut == NULL || uriSize == 0 || uriSize > OTAPP_PAIR_URI_MAX)
{
}
uint16_t writtenBufSpace;
// Add TLV block containing the number of available URIs
otapp_msg_tlv_keyAdd(bufferOut, *bufferSizeInOut, OTAPP_PAIR_KEY_URIS_COUNT, sizeof(uriSize), &uriSize);
// Iterate through the list and append device types and URI paths as TLV blocks
for (size_t i = 0; i < uriSize; i++) // quantity_of_uris | uri1_dt | uri1_path | uri2_dt | uri2_path | uri3_dt | uri3_path | ...
{
// Add device type using an incremented key
otapp_msg_tlv_keyAdd(bufferOut, *bufferSizeInOut, OTAPP_PAIR_KEY_PATTERN + 2*i + 1, sizeof(uri[i].devType), (uint8_t *)&uri[i].devType);
// Add URI path string as the subsequent TLV block
otapp_msg_tlv_keyAdd(bufferOut, *bufferSizeInOut, OTAPP_PAIR_KEY_PATTERN + 2*i + 2, strlen(uri[i].resource.mUriPath), (uint8_t *)uri[i].resource.mUriPath);
}
// Retrieve the final count of written bytes from the buffer header
if(otapp_msg_tlv_getBufferTotalUsedSpace(bufferOut, *bufferSizeInOut, &writtenBufSpace) == OT_APP_MSG_TLV_ERROR)
{
}
*bufferSizeInOut = writtenBufSpace;
return OTAPP_PAIR_OK;
}
#define OTAPP_BUF_KEY_1
Key 1: General purpose buffer. Used by otapp_pair_uriParseMessage() and otapp_pair_uriResourcesCreate...
Definition ot_app_buffer.h:56
int8_t otapp_buf_writeUnlock(uint16_t key)
Unlocks a slot previously locked by otapp_buf_getWriteOnly_ptr.
Definition ot_app_buffer.c:133
uint8_t * otapp_buf_getWriteOnly_ptr(uint16_t key, uint16_t required_size)
Requests a write-only pointer for direct memory access (Zero-Copy).
Definition ot_app_buffer.c:245
void ad_temp_uri_well_knownCoreHandle(void *aContext, otMessage *request, const otMessageInfo *aMessageInfo)
Definition ot_app_coap_uri.c:90
void otapp_coap_sendResponse(otMessage *requestMessage, const otMessageInfo *aMessageInfo, const uint8_t *responseContent, uint16_t responseLength)
Sends a generic CoAP response with a payload.
Definition ot_app_coap.c:135
#define OTAPP_PRINTF
Definition ot_app.h:39
ot_app_devDrv_t * otapp_getDevDrvInstance(void)
Retrieves the singleton instance of the Device Driver.
Definition ot_app.c:121
uriGet_callback_t uriGetList_clb
Callback function to retrieve the list of URIs.
Definition ot_app_drv.h:288
uint8_t ot_app_size_t
Definition ot_app_drv.h:236
ot_app_size_t uriGetListSize
Number of URIs in the URI list.
Definition ot_app_drv.h:363
int8_t otapp_msg_tlv_getBufferTotalUsedSpace(const uint8_t *buffer, const uint16_t bufferSize, uint16_t *writtenBufSpaceOut)
Definition ot_app_msg_tlv.c:200
#define OT_APP_MSG_TLV_ERROR
Generic error (null ptr, invalid param).
Definition ot_app_msg_tlv.h:159
int8_t otapp_msg_tlv_keyAdd(uint8_t *buffer, const uint16_t bufferSize, const uint16_t key, const uint16_t valueLengthIn, uint8_t *valueIn)
Add new TLV block to buffer if key unique and space available.
Definition ot_app_msg_tlv.c:60
#define OTAPP_PAIR_ERROR
Generic error.
Definition ot_app_pair.h:51
uint16_t otapp_pair_uriResourcesCalculateBufSize(otapp_coap_uri_t *uri, uint8_t uriSize)
Calculates the buffer size needed to serialize a list of URIs.
Definition ot_app_pair.c:503
#define OTAPP_PAIR_URI_MAX
Max number of URIs per device (from ot_app.h).
Definition ot_app_pair.h:61
#define OTAPP_PAIR_OK
Operation successful.
Definition ot_app_pair.h:48
int8_t otapp_pair_uriResourcesCreate(otapp_coap_uri_t *uri, uint8_t uriSize, uint8_t *bufferOut, uint16_t *bufferSizeInOut)
Serializes a list of device URI resources into a TLV-encoded byte buffer.
Definition ot_app_pair.c:519
#define NULL
Definition hro_utils.h:73
Thread-safe shared buffer management for the OpenThread Application Framework.
Main API for OpenThread hardware application device driver.
TLV (Type-Length-Value) message serialization/deserialization API.
#define OTAPP_PAIR_KEY_URIS_COUNT
Definition ot_app_pair.c:501
#define OTAPP_PAIR_KEY_PATTERN
Definition ot_app_pair.c:500
#define TAG
Definition ot_app_port_nvs.c:30
Definition ot_app_drv.h:242
Definition mock_ip6.h:93
Definition mock_ip6.h:96
Definition ot_app_coap.h:66
Version
0.1
Date
29-01-2026
Author
Jan Łukaszewicz (plhar.nosp@m.eo@g.nosp@m.mail..nosp@m.com)

Macro Definition Documentation

◆ OT_APP_MSG_TLV_EMPTY_BUFFER

#define OT_APP_MSG_TLV_EMPTY_BUFFER   (-5)

Buffer has no TLV data.

◆ OT_APP_MSG_TLV_ERROR

#define OT_APP_MSG_TLV_ERROR   (-2)

Generic error (null ptr, invalid param).

◆ OT_APP_MSG_TLV_ERROR_NO_SPACE

#define OT_APP_MSG_TLV_ERROR_NO_SPACE   (-3)

no space for new TLV

◆ OT_APP_MSG_TLV_KEY_EXIST

#define OT_APP_MSG_TLV_KEY_EXIST   (-4)

Key already exists (duplicate add).

◆ OT_APP_MSG_TLV_KEY_NO_EXIST

#define OT_APP_MSG_TLV_KEY_NO_EXIST   (-5)

Key not found.

◆ OT_APP_MSG_TLV_OK

#define OT_APP_MSG_TLV_OK   (-1)

Operation successful.

Function Documentation

◆ otapp_msg_tlv_calcualeBuffer()

uint16_t otapp_msg_tlv_calcualeBuffer ( uint8_t keyDataLength,
uint8_t cnt )

◆ otapp_msg_tlv_getBufferTotalFreeSpace()

int8_t otapp_msg_tlv_getBufferTotalFreeSpace ( const uint8_t * buffer,
const uint16_t bufferSize,
uint16_t * freeBufSpaceOut )

Get remaining free space in TLV buffer.

Calculates: bufferSize - reserved(2B) - writtenBytes.

Parameters
bufferPointer to TLV buffer.
bufferSizeTotal size.
freeBufSpaceOutOUT: Free bytes available.
Returns
OT_APP_MSG_TLV_OK or error.

◆ otapp_msg_tlv_getBufferTotalUsedSpace()

int8_t otapp_msg_tlv_getBufferTotalUsedSpace ( const uint8_t * buffer,
const uint16_t bufferSize,
uint16_t * writtenBufSpaceOut )

◆ otapp_msg_tlv_keyAdd()

int8_t otapp_msg_tlv_keyAdd ( uint8_t * buffer,
const uint16_t bufferSize,
const uint16_t key,
const uint16_t valueLengthIn,
uint8_t * valueIn )

Add new TLV block to buffer if key unique and space available.

Appends a TLV entry: key (u16) + length (u16) + value bytes. Updates internal writtenBytes counter. Validates space, duplicates, and parameters.

Parameters
bufferPointer to buffer (user-allocated).
bufferSizeTotal buffer size in bytes. (must >= reserved 2B + TLV).
keyUnique 16-bit key identifier.
valueLengthInValue length in bytes (0 invalid).
valueInPointer to value data to copy.
Returns
OT_APP_MSG_TLV_OK on success, error code otherwise.
Note
Buffer must have >= 2B + (x * TLV struct + keys valueLength)) bytes free.
Existing keys rejected (use update if needed).

◆ otapp_msg_tlv_keyGet()

int8_t otapp_msg_tlv_keyGet ( uint8_t * buffer,
const uint16_t bufferSize,
const uint16_t key,
uint16_t * valueLengthOut,
uint8_t * valueOut )

Extract TLV value by key (optional copy to output).

Linear scan from buffer start. Validates buffer integrity and key presence. Copies value if pointers provided.

Parameters
bufferPointer to TLV buffer.
bufferSizeTotal buffer size.
key16-bit key to find.
valueLengthOutOUT: Value length (NULL to skip).
valueOutOUT: Value copy destination (NULL to skip).
Returns
OT_APP_MSG_TLV_KEY_EXIST on found (with copy if requested), OT_APP_MSG_TLV_KEY_NO_EXIST if missing, error otherwise.