Parsing and Serialization

Tools for parsing PDUs and serializing messages and options. More...

Detailed Description

Tools for parsing PDUs and serializing messages and options.

Parsing

To parse a message on your own, use one of the parsers in Message APIs and unicoap_parser_result_t. The parsed message structure helps you allocate everything needed in one go.

// Parse an RFC 7252 PDU
uint8_t pdu[] = {
0x40, 0x02, 0xfe, 0xb1, 0xb9, 0x61, 0x63, 0x74, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x04, 0x6c, 0x65, 0x64, 0x73, 0x11, 0x32, 0x37, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x67, 0x21, 0x32, 0xff, 0x6d, 0x6f, 0x64, 0x65, 0x3d, 0x6f, 0x6e
};
unicoap_parser_result_t parsed = { 0 }; // Zero-initialize everything
// Parse message
ssize_t res = unicoap_pdu_parse_rfc7252_result(pdu, sizeof(pdu), &parsed);
// Handle errors
if (res < 0) {
// eat error
}
// parsed.message contains the parsed message
static ssize_t unicoap_pdu_parse_rfc7252_result(uint8_t *pdu, size_t size, unicoap_parser_result_t *parsed)
Helper method for manually parsing a PDU.
Definition: message.h:1272
Helper structure for parsing PDUs manually.
Definition: message.h:1117

Serializing

To serialize a message on your own, decide whether you need vectored data or contiguous data. To get vectored data, you use unicoap_pdu_buildv_* functions, depending on the CoAP transport you intend to use. Vectored data is represented using an iolist_t. If you want to build a contiguous storage body, refer to the unicoap_pdu_build_* methods, also depending on the transport.

// Build an RFC 7252 PDU
uint8_t pdu[MY_CAPACITY] = { 0 };
ssize_t size = unicoap_pdu_build_rfc7252(pdu, sizeof(pdu), message, properties);
// Handle errors
if (res < 0) {
// eat error
}
static ssize_t unicoap_pdu_build_rfc7252(uint8_t *pdu, size_t capacity, const unicoap_message_t *message, const unicoap_message_properties_t *properties)
Writes RFC 7252 PDU into buffer.
Definition: message.h:1311

Implementation

Parsing and serialization are each done in two steps:

  1. Message header up until options is parsed/serialized by driver
  2. Options are parsed/serialized by common unicoap implementation

Data Structures

struct  unicoap_parser_result_t
 Helper structure for parsing PDUs manually. More...
 

Parsing

typedef ssize_t(* unicoap_parser_t) (const uint8_t *pdu, size_t size, unicoap_message_t *message, unicoap_message_properties_t *properties)
 Common PDU parser. More...
 
ssize_t unicoap_pdu_parse_options_and_payload (uint8_t *cursor, const uint8_t *end, unicoap_message_t *message)
 Parses PDU starting at options. More...
 
ssize_t unicoap_pdu_parse_rfc7252 (uint8_t *pdu, size_t size, unicoap_message_t *message, unicoap_message_properties_t *properties)
 Parses RFC 7252 PDU. More...
 
static ssize_t unicoap_pdu_parse_rfc7252_result (uint8_t *pdu, size_t size, unicoap_parser_result_t *parsed)
 Helper method for manually parsing a PDU. More...
 

Serializing

ssize_t unicoap_pdu_build_options_and_payload (uint8_t *cursor, size_t remaining_capacity, const unicoap_message_t *message)
 Populates the given buffer with options and payload. More...
 
int unicoap_pdu_buildv_options_and_payload (uint8_t *header, size_t header_size, const unicoap_message_t *message, iolist_t iolists[UNICOAP_PDU_IOLIST_COUNT])
 Populates the given iolist with header, options, payload separator and payload. More...
 
ssize_t unicoap_pdu_build_header_rfc7252 (uint8_t *header, size_t capacity, const unicoap_message_t *message, const unicoap_message_properties_t *properties)
 Writes RFC 7252 PDU header in the given buffer. More...
 
static ssize_t unicoap_pdu_build_rfc7252 (uint8_t *pdu, size_t capacity, const unicoap_message_t *message, const unicoap_message_properties_t *properties)
 Writes RFC 7252 PDU into buffer. More...
 
static ssize_t unicoap_pdu_buildv_rfc7252 (uint8_t *header, size_t header_capacity, const unicoap_message_t *message, const unicoap_message_properties_t *properties, iolist_t iolists[UNICOAP_PDU_IOLIST_COUNT])
 Populates the given iolist with header according to RFC 7252, options, and payload. More...
 
#define UNICOAP_PDU_IOLIST_COUNT   (4)
 Number of iolists in the iolist buffer that must be passed to unicoap_pdu_buildv_options_and_payload.
 

Typedef Documentation

◆ unicoap_parser_t

typedef ssize_t(* unicoap_parser_t) (const uint8_t *pdu, size_t size, unicoap_message_t *message, unicoap_message_properties_t *properties)

Common PDU parser.

The parser should call unicoap_pdu_parse_options_and_payload when it's finished parsing the PDU header.

Parameters
[in]pduPDU buffer
sizePDU size
[in,out]messagePre-allocated message
[in,out]propertiesPre-allocated properties
Precondition
message is allocated
properties is allocated

Definition at line 1109 of file message.h.

Function Documentation

◆ unicoap_pdu_build_header_rfc7252()

ssize_t unicoap_pdu_build_header_rfc7252 ( uint8_t *  header,
size_t  capacity,
const unicoap_message_t message,
const unicoap_message_properties_t properties 
)

Writes RFC 7252 PDU header in the given buffer.

Parameters
[in,out]headerBuffer the header will be written into
capacityNumber of usable bytes in the header buffer
[in]messageMessage to construct header from (use code or payload_size)
[in]propertiesMessage properties to serialize into the header
Returns
Header size
Return values
<tt>-ENOBUFS</tt>Buffer too small

◆ unicoap_pdu_build_options_and_payload()

ssize_t unicoap_pdu_build_options_and_payload ( uint8_t *  cursor,
size_t  remaining_capacity,
const unicoap_message_t message 
)

Populates the given buffer with options and payload.

Call this method with the remaining capacity after you have written the CoAP header into a PDU buffer

Parameters
[in]cursorPointer to first byte after header
remaining_capacityCapacity remaining for options, payload marker, and payload
[in]messageMessage containing options and payload
Returns
Number of bytes written
-ENOBUFS if buffer is too small

◆ unicoap_pdu_build_rfc7252()

static ssize_t unicoap_pdu_build_rfc7252 ( uint8_t *  pdu,
size_t  capacity,
const unicoap_message_t message,
const unicoap_message_properties_t properties 
)
inlinestatic

Writes RFC 7252 PDU into buffer.

Parameters
[in,out]pduBuffer
capacityPDU buffer capacity
[in]messageMessage
[in]propertiesMessage properties containing ID and type
Returns
Size of PDU
Negative integer one error
Return values
<tt>-ENOBUFS</tt>Buffer too small

Definition at line 1311 of file message.h.

◆ unicoap_pdu_buildv_options_and_payload()

int unicoap_pdu_buildv_options_and_payload ( uint8_t *  header,
size_t  header_size,
const unicoap_message_t message,
iolist_t  iolists[UNICOAP_PDU_IOLIST_COUNT] 
)

Populates the given iolist with header, options, payload separator and payload.

Use this method to construct a vector message for vectored send functions in your transport driver.

Parameters
[in]headerEncoded CoAP header
header_sizeSize of header
[in]messageMessage containing options and payload
[in,out]iolistsBuffer of iolists, pre-allocated, size must be UNICOAP_PDU_IOLIST_COUNT
Precondition
iolists is allocated
Returns
Zero on success, negative error number otherwise

◆ unicoap_pdu_buildv_rfc7252()

static ssize_t unicoap_pdu_buildv_rfc7252 ( uint8_t *  header,
size_t  header_capacity,
const unicoap_message_t message,
const unicoap_message_properties_t properties,
iolist_t  iolists[UNICOAP_PDU_IOLIST_COUNT] 
)
inlinestatic

Populates the given iolist with header according to RFC 7252, options, and payload.

Parameters
[in]headerHeader buffer
header_capacityCapacity of header buffer
[in]messageMessage containing options and payload
[in]propertiesMessage properties containing ID and type
[in,out]iolistsBuffer of iolists, pre-allocated, size must be be UNICOAP_PDU_IOLIST_COUNT
Precondition
iolists is allocated
Returns
0 on success
Negative integer one error
Return values
<tt>-ENOBUFS</tt>Buffer too small

Definition at line 1341 of file message.h.

◆ unicoap_pdu_parse_options_and_payload()

ssize_t unicoap_pdu_parse_options_and_payload ( uint8_t *  cursor,
const uint8_t *  end,
unicoap_message_t message 
)

Parses PDU starting at options.

Call this method after you have parsed the CoAP header.

Parameters
[in]cursorStart of options buffer
[out]endPointer to after last buffer element
[in,out]messagePre-allocated message to write options and payload into. Must have valid options pointer
Precondition
message is allocated
Returns
0 on success
Negative errno on failure
Note
This function does not mutate or copy the buffer pointed at by cursor. However, it does escape pointers into the buffer pointed at by cursor in message . This is necessary to create a lookup array for options, i.e., to avoid re-parsing the options buffer. You will need to decide whether you treat the message's options as constant or not. This depends on whether the buffer cursor passed to this function is considered constant by you.

As unicoap cannot guarantee you won't add/insert/remove options later, cursor is not qualified by const. That hypothetical const depends on your usage of the message and its options. That hypothetical const depends on your usage of the message and its options.

◆ unicoap_pdu_parse_rfc7252()

ssize_t unicoap_pdu_parse_rfc7252 ( uint8_t *  pdu,
size_t  size,
unicoap_message_t message,
unicoap_message_properties_t properties 
)

Parses RFC 7252 PDU.

Parameters
pduBuffer containing PDU to parse
sizeSize of PDU in bytes
[out]messagePre-allocated message to populate, should have options set
[out]propertiesPre-allocated properties structure to populate
Precondition
message is allocated
properties is allocated
Returns
Zero on success or negative errno on failure
Return values
<tt>-EBADOPT</tt>Bad option
<tt>-ENOBUFS</tt>Options buffer in unicoap_message_t::options (unicoap_options_t) too small
Remarks
To allocate everything needed in one go, use unicoap_pdu_parse_rfc7252_result instead.
Note
This function does not mutate or copy the buffer pointed at by pdu. However, it does escape pointers into the buffer pointed at by pdu in message . This is necessary to create a lookup array for options, i.e., to avoid re-parsing the options buffer. You will need to decide whether you treat the message's options as constant or not. This depends on whether the buffer pdu passed to this function is considered constant by you.

As unicoap cannot guarantee you won't add/insert/remove options later, pdu is not qualified by const. That hypothetical const depends on your usage of the message and its options.

◆ unicoap_pdu_parse_rfc7252_result()

static ssize_t unicoap_pdu_parse_rfc7252_result ( uint8_t *  pdu,
size_t  size,
unicoap_parser_result_t parsed 
)
inlinestatic

Helper method for manually parsing a PDU.

Parameters
[in]pduPDU buffer
sizePDU size in bytes
[out]parsedPre-allocated parsed message structure
Precondition
parsed is allocated
Returns
Zero on success or negative errno on failure
Return values
<tt>-EBADOPT</tt>Bad option
<tt>-ENOBUFS</tt>Options buffer in unicoap_message_t::options (unicoap_options_t) too small
Note
This function does not mutate or copy the buffer pointed at by pdu. However, it does escape pointers into the buffer pointed at by pdu in message . This is necessary to create a lookup array for options, i.e., to avoid re-parsing the options buffer. You will need to decide whether you treat the message's options as constant or not. This depends on whether the buffer pdu passed to this function is considered constant by you.

As unicoap cannot guarantee you won't add/insert/remove options later, pdu is not qualified by const. That hypothetical const depends on your usage of the message and its options.

Definition at line 1272 of file message.h.