Loading...
Searching...
No Matches

Implementation details of unicoap More...

Detailed Description

Implementation details of unicoap

Warning
Do not call any of these APIs and do not interact with any of unicoap's private types, unless you know what you are doing. You risk corrupting unicoap's internal state.

Topics

 State Management
 

Files

file  private.h
 Private API.
 
file  messaging.h
 Messaging API.
 
file  packet.h
 Packet.
 

Data Structures

struct  unicoap_state_t
 Container the unicoap stacks keeps state in. More...
 
union  unicoap_exchange_arg_t
 Argument passed to exchange-layer processing function. More...
 
struct  unicoap_packet_t
 A type acting as an envelope for a message and data connected, like endpoints. More...
 

Functions

static unicoap_proto_t unicoap_packet_proto (const unicoap_packet_t *packet)
 Retrieves protocol number from packet.
 
static const void * _packet_get_dtls_session (unicoap_packet_t *packet)
 Retrieves transport session from packet.
 
static void _packet_set_dtls_session (unicoap_packet_t *packet, const unicoap_sock_dtls_session_t *dtls_session)
 Sets DTLS transport session of packet.
 

Private Messaging API

enum  unicoap_messaging_flags_t { UNICOAP_MESSAGING_FLAG_RELIABLE = 0x01 }
 Messaging layer result after initial treatment of an inbound message. More...
 
enum  unicoap_preprocessing_result_t {
  UNICOAP_PREPROCESSING_ERROR_INVALID_CODE_CLASS = -0x1001 , UNICOAP_PREPROCESSING_ERROR_UNSUPPORTED = -0x1002 , UNICOAP_PREPROCESSING_ERROR_RESPONSE_UNEXPECTED = -0x1004 , UNICOAP_PREPROCESSING_ERROR_NOTIFICATION_UNEXPECTED = -0x100c ,
  UNICOAP_PREPROCESSING_ERROR_TRUNCATED = -0x1010 , UNICOAP_PREPROCESSING_ERROR_REQUEST = -0x1020 , UNICOAP_PREPROCESSING_SUCCESS_RESPONSE = 0x1001 , UNICOAP_PREPROCESSING_SUCCESS_REQUEST = 0x1002
}
 Result of unicoap_exchange_preprocess. More...
 
unicoap_preprocessing_result_t unicoap_exchange_preprocess (unicoap_packet_t *packet, unicoap_messaging_flags_t *flags, unicoap_exchange_arg_t *arg, bool truncated)
 Performs initial processing of a CoAP packet after it has been parsed.
 
int unicoap_exchange_process (unicoap_packet_t *packet, unicoap_exchange_arg_t arg)
 Processes message.
 
int unicoap_exchange_release_endpoint_state (const unicoap_endpoint_t *endpoint)
 Releases all buffers and state allocated in connection with the given endpoint.
 
int unicoap_messaging_process_rfc7252 (const uint8_t *pdu, size_t size, bool truncated, unicoap_packet_t *packet)
 Internal RFC 7252 messaging inbound processor.
 
int unicoap_messaging_send (unicoap_packet_t *packet, unicoap_messaging_flags_t flags)
 Forwards packet to messaging layer and the corresponding driver for further message processing, encoding, and transport I/O.
 
int unicoap_messaging_send_rfc7252 (unicoap_packet_t *packet, unicoap_messaging_flags_t flags)
 Sends CoAP over UDP or DTLS packet, see unicoap_messaging_send.
 
void unicoap_generate_token (uint8_t *token)
 Generates new token.
 
static unicoap_messaging_flags_t _messaging_flags_resource (unicoap_resource_flags_t resource_flags)
 Retrieves the part of a resource flags bitfield relevant for the messaging driver.
 
#define UNICOAP_MESSAGING_FLAGS_DEFAULT   (0)
 The messaging flags the stack uses when no source for messaging flags is available.
 

Debugging

void unicoap_assist_emit_diagnostic_missing_driver (unicoap_proto_t proto)
 Emit a diagnostic stating that a driver is missing.
 
#define UNICOAP_DEBUG_PREFIX   "coap"
 Debug log prefix.
 
#define DEBUG_ENDPOINT(endpoint)
 Debug print endpoint.
 
#define DEBUG_FLAGS(flags, role)
 Debug print flags.
 

Thread

void unicoap_state_lock (void)
 Locks internal state lock.
 
void unicoap_state_unlock (void)
 Unlocks internal state lock.
 
#define UNICOAP_THREAD_IDENTIFIER   "unicoap"
 Name of background thread spawned upon calls to unicoap_init.
 

State and initialization

static void unicoap_set_listeners (unicoap_state_t *state, unicoap_listener_t *listeners)
 Sets listener array on state object to listeners.
 
static unicoap_listener_tunicoap_get_listeners (unicoap_state_t *state)
 Gets listener array from state object.
 
int unicoap_init_udp (event_queue_t *queue)
 Initializes the CoAP over UDP driver on the given queue.
 
int unicoap_deinit_udp (event_queue_t *queue)
 Deinitializes the CoAP over UDP driver on the given queue.
 
int unicoap_init_dtls (event_queue_t *queue)
 Initializes the CoAP over DTLS over UDP driver on the given queue.
 
int unicoap_deinit_dtls (event_queue_t *queue)
 Deinitializes the CoAP over DTLS over UDP driver on the given queue.
 
int unicoap_init_rfc7252_common (event_queue_t *queue)
 Initializes the common RFC 7252 driver on the given queue.
 
int unicoap_deinit_rfc7252_common (event_queue_t *queue)
 DeiInitializes the common RFC 7252 driver on the given queue.
 

Resource-request matching

int unicoap_resource_find (const unicoap_packet_t *packet, const unicoap_resource_t **resource_ptr, const unicoap_listener_t **listener_ptr)
 Tries to find a resource for the given packet.
 
int unicoap_resource_match_request_default (const unicoap_listener_t *listener, const unicoap_resource_t **resource_ptr, const unicoap_message_t *request, const unicoap_endpoint_t *endpoint)
 Default request-resource matcher for listeners.
 
int unicoap_resource_handle_well_known_core (unicoap_message_t *message, const unicoap_aux_t *aux, unicoap_request_context_t *ctx, void *arg)
 Default resource handler for /.well-known/core
 

Other Utils

static bool unicoap_transport_truncate_received (size_t *chunk_size, size_t received)
 Determines whether the chunk of the given size must be truncated to fit into a buffer of size CONFIG_UNICOAP_PDU_SIZE_MAX.
 
#define UNICOAP_DECL_RECEIVER_STORAGE    uint8_t unicoap_receiver_buffer[CONFIG_UNICOAP_PDU_SIZE_MAX]
 Declares internal receiver storage buffer.
 
#define UNICOAP_DECL_RECEIVER_STORAGE_EXTERN   extern UNICOAP_DECL_RECEIVER_STORAGE
 extern declaration of UNICOAP_DECL_RECEIVER_STORAGE
 

Server

int unicoap_server_process_request (unicoap_packet_t *packet, const unicoap_resource_t *resource)
 Informs the unicoap server a new packet has been preprocessed and can be handled.
 
int unicoap_server_send_response_body (unicoap_packet_t *packet, const unicoap_resource_t *resource)
 Sends entire response body, may be split into parts and then sent.
 

Macro Definition Documentation

◆ DEBUG_ENDPOINT

#define DEBUG_ENDPOINT ( endpoint)
Value:
void unicoap_print_endpoint(const unicoap_endpoint_t *endpoint)
Prints the given CoAP endpoint.

Debug print endpoint.

Definition at line 80 of file private.h.

◆ DEBUG_FLAGS

#define DEBUG_FLAGS ( flags,
role )
Value:
unicoap_print_flags(flags, role)

Debug print flags.

Definition at line 84 of file private.h.

◆ UNICOAP_DEBUG_PREFIX

#define UNICOAP_DEBUG_PREFIX   "coap"

Debug log prefix.

Definition at line 48 of file private.h.

◆ UNICOAP_DECL_RECEIVER_STORAGE

#define UNICOAP_DECL_RECEIVER_STORAGE    uint8_t unicoap_receiver_buffer[CONFIG_UNICOAP_PDU_SIZE_MAX]

Declares internal receiver storage buffer.

This buffer is used by sock network backends not emitting contiguous data

Definition at line 258 of file private.h.

◆ UNICOAP_DECL_RECEIVER_STORAGE_EXTERN

#define UNICOAP_DECL_RECEIVER_STORAGE_EXTERN   extern UNICOAP_DECL_RECEIVER_STORAGE

extern declaration of UNICOAP_DECL_RECEIVER_STORAGE

Definition at line 264 of file private.h.

◆ UNICOAP_MESSAGING_FLAGS_DEFAULT

#define UNICOAP_MESSAGING_FLAGS_DEFAULT   (0)

The messaging flags the stack uses when no source for messaging flags is available.

These flags are used if the server needs to send a 4.04 Path Not Found response, or the message is truncated.

Definition at line 110 of file messaging.h.

◆ UNICOAP_THREAD_IDENTIFIER

#define UNICOAP_THREAD_IDENTIFIER   "unicoap"

Name of background thread spawned upon calls to unicoap_init.

Definition at line 122 of file private.h.

Enumeration Type Documentation

◆ unicoap_messaging_flags_t

Messaging layer result after initial treatment of an inbound message.

/
| Application
/ /|\
Stack < | API
\ \|/
| Request/response layer ------+
\ ^ \ Events
| / (truncated, expected, deferred, ...)
/ Messaging layer (driver) <---+
| ^
/ |
Driver(s) < Parser (driver)
\ ^
| |
\ Network (driver)
Fig. 1: Inbound message path through the stack
Remarks
You can always use a compile-time bitwise OR to check for multiple flags to check for generally acceptable or unacceptable messages.

Flags for sending a message communicated by the unicoap stack to the messaging driver

Each time the stack wants to send a message, unicoap_messaging_send will be called, which, in turn, invokes the messaging driver implementation.

Warning
Bits other than those defined as enum cases are RFU. Do not use them or make assumptions on their value.

These flags are intended for messaging and transmission options. Messaging options may change the CoAP message flow (e.g., waiting for an acknowledgement) or transmission behavior (e.g., using an optional reliability layer of the underlying transport protocol or implementation).

Relationship with Exchange-Layer Flags

Messaging flags are provided as part of client and resource flags. The (TODO: ref) unicoap_client_flags_t and unicoap_resource_flags_t are separated into

  • exchange flags needed for features building on top the request/response level and
  • messaging flags.

The stack communicates only the messaging flags to the driver, in the form of this bitfield.

Enumerator
UNICOAP_MESSAGING_FLAG_RELIABLE 

Messaging flag indicating the stack wants this message to be transmitted reliably.

For transport protocol that already provide reliability, the messaging driver can ignore this flag. If the CoAP messaging layer of your driver supports optional reliability, such as the RFC 7252 driver, turn on this behavior if you are given this flag.

Example

The RFC 7252 (CoAP over UDP and DTLS) supports optional reliability in the form of confirmable message. In contrast to non-confirmable messages, confirmable messages elicit an acknowledgement message sent by the receiver. The sender retransmits the original confirmable message using an exponential back-of mechanism until it receives the acknowledgement.

Definition at line 83 of file messaging.h.

◆ unicoap_preprocessing_result_t

Result of unicoap_exchange_preprocess.

Enumerator
UNICOAP_PREPROCESSING_ERROR_INVALID_CODE_CLASS 

The given message's code class is not valid.

Currently considered valid:

  • 0.xx Requests, except 0.00
  • 2.xx, 4.xx, and 5.xx Responses
  • 7.xx Signals
UNICOAP_PREPROCESSING_ERROR_UNSUPPORTED 

The given message cannot be processed due to being unsupported.

UNICOAP_PREPROCESSING_ERROR_RESPONSE_UNEXPECTED 

The given message is unexpected and cannot be processed.

There's no known client exchange running.

UNICOAP_PREPROCESSING_ERROR_NOTIFICATION_UNEXPECTED 

Unexpected notification, no known client exchange (observation)

There's no known client exchange, i.e., observation, running.

UNICOAP_PREPROCESSING_ERROR_TRUNCATED 

The given message is truncated and can thus not be handled.

UNICOAP_PREPROCESSING_ERROR_REQUEST 

The given message cannot be handled, disregarded.

UNICOAP_PREPROCESSING_SUCCESS_RESPONSE 

The given message can be processed.

There's an active client exchange.

UNICOAP_PREPROCESSING_SUCCESS_REQUEST 

The given message can be processed.

There's a resource that can handle this request

Definition at line 124 of file messaging.h.

Function Documentation

◆ _messaging_flags_resource()

static unicoap_messaging_flags_t _messaging_flags_resource ( unicoap_resource_flags_t resource_flags)
inlinestatic

Retrieves the part of a resource flags bitfield relevant for the messaging driver.

Parameters
resource_flagsResource flags
Returns
Messaging flags extracted from the given bitfield

Definition at line 286 of file messaging.h.

◆ _packet_get_dtls_session()

static const void * _packet_get_dtls_session ( unicoap_packet_t * packet)
inlinestatic

Retrieves transport session from packet.

Parameters
[in,out]packetPacket to retrieve session from
Returns
Transport session

Definition at line 99 of file packet.h.

◆ _packet_set_dtls_session()

static void _packet_set_dtls_session ( unicoap_packet_t * packet,
const unicoap_sock_dtls_session_t * dtls_session )
inlinestatic

Sets DTLS transport session of packet.

Parameters
[in,out]packetwhose session to set
dtls_sessionDTLS session

Definition at line 115 of file packet.h.

◆ unicoap_exchange_preprocess()

unicoap_preprocessing_result_t unicoap_exchange_preprocess ( unicoap_packet_t * packet,
unicoap_messaging_flags_t * flags,
unicoap_exchange_arg_t * arg,
bool truncated )

Performs initial processing of a CoAP packet after it has been parsed.

The processing of a CoAP message is divided into two parts: preprocessing and the actual processing. This design was chosen to allow the messaging driver to implement networking logic in between.

Example: The RFC 7252 messaging driver sends an ACK for every confirmable response received at the client. Waiting for the application to handle the response could delay the ACK, possibly lead to retransmissions or even open a timing-based side channel.

Parameters
[in,out]packetPacket received
[out]flagsMessaging flags associated with resource or client exchange
[out]argArgument to be passed to the processor
truncatedA boolean value indicating whether the given PDU was truncated, but could still be parsed (i.e., a valid message)
Returns
unicoap_preprocessing_result_t

◆ unicoap_exchange_process()

int unicoap_exchange_process ( unicoap_packet_t * packet,
unicoap_exchange_arg_t arg )

Processes message.

Call this after you have preprocessed the message using unicoap_exchange_preprocess.

Parameters
[in,out]packetCoAP packet
[in]argArgument returned (via out parameter) by unicoap_exchange_preprocess
Return values
Zeroif processing succeeds
Negativeerror number if processing failed

◆ unicoap_exchange_release_endpoint_state()

int unicoap_exchange_release_endpoint_state ( const unicoap_endpoint_t * endpoint)

Releases all buffers and state allocated in connection with the given endpoint.

Call this function from your driver if you encounter a severe error with a given endpoint

Parameters
[in]endpointRemote endpoint to release buffers for
Returns
Negative error integer or zero on success.
Return values
`-ENOENT`if no state is currently associated with the given endpoint

◆ unicoap_generate_token()

void unicoap_generate_token ( uint8_t * token)

Generates new token.

Token will be CONFIG_UNICOAP_GENERATED_TOKEN_LENGTH bytes long.

Parameters
[in,out]tokenBuffer for generated token, must have a minimum capacity of CONFIG_UNICOAP_GENERATED_TOKEN_LENGTH

◆ unicoap_get_listeners()

static unicoap_listener_t * unicoap_get_listeners ( unicoap_state_t * state)
inlinestatic

Gets listener array from state object.

Definition at line 164 of file private.h.

◆ unicoap_messaging_process_rfc7252()

int unicoap_messaging_process_rfc7252 ( const uint8_t * pdu,
size_t size,
bool truncated,
unicoap_packet_t * packet )

Internal RFC 7252 messaging inbound processor.

Parameters
[in]pduBuffer containing PDU
sizeSize of PDU in bytes
truncatedA boolean value indicating whether the message has been truncated by the transport layer
[in]packetPacket to process
Returns
Negative error number in case of a failure, zero otherwise.

This function forwards the truncated characteristic to the exchange layer, which can handle that scenario appropriately, such as by setting a Size option.

Remarks
While it is not advised to call private API, you might want to consider calling this function in a very constrained environment or when using sock is not an option.

◆ unicoap_messaging_send()

int unicoap_messaging_send ( unicoap_packet_t * packet,
unicoap_messaging_flags_t flags )

Forwards packet to messaging layer and the corresponding driver for further message processing, encoding, and transport I/O.

The driver needs to encode the given message into a serialized PDU and use its own means of transmitting the packet to the packet's remote endpoint.

This function calls the individual driver messaging implementation.

Parameters
[in,out]packetPacket to send
flagsMessaging flags
Returns
Zero on success or negative error value. See unicoap_messaging_send_rfc7252.

◆ unicoap_packet_proto()

static unicoap_proto_t unicoap_packet_proto ( const unicoap_packet_t * packet)
inlinestatic

Retrieves protocol number from packet.

Parameters
[in]packetPacket to read protocol number from
Returns
Protocol number

Definition at line 87 of file packet.h.

◆ unicoap_resource_find()

int unicoap_resource_find ( const unicoap_packet_t * packet,
const unicoap_resource_t ** resource_ptr,
const unicoap_listener_t ** listener_ptr )

Tries to find a resource for the given packet.

The resource and listener variables passed by reference will be set to the respective resource and encompassing listener, if found.

This method calls each listeners unicoap_listener_t::request_matcher to check whether the given resource can be matched to the given packet.

Note
The default request matcher is unicoap_resource_match_request_default
Parameters
[in]packetPacket to find resource for
[in]resource_ptrPointer to a resource variable
[in]listener_ptrPointer to a listener variable
Return values
`0`if found
orunicoap_status_t if not found, method mismatch, or server error

◆ unicoap_resource_handle_well_known_core()

int unicoap_resource_handle_well_known_core ( unicoap_message_t * message,
const unicoap_aux_t * aux,
unicoap_request_context_t * ctx,
void * arg )

Default resource handler for /.well-known/core

See also
unicoap_request_handler_t

◆ unicoap_resource_match_request_default()

int unicoap_resource_match_request_default ( const unicoap_listener_t * listener,
const unicoap_resource_t ** resource_ptr,
const unicoap_message_t * request,
const unicoap_endpoint_t * endpoint )

Default request-resource matcher for listeners.

The resource variable passed by reference will be set to the respective resource, if found.

Parameters
[in]listenerListener
[out]resource_ptrPointer to a resource variable
[in]requestRequest message
[in]endpointRemote endpoint the request originates from
Return values
`0`if found
Anunicoap_status_t if not found, method mismatch, or server error

◆ unicoap_server_process_request()

int unicoap_server_process_request ( unicoap_packet_t * packet,
const unicoap_resource_t * resource )

Informs the unicoap server a new packet has been preprocessed and can be handled.

This function handles block-wise transfers.

Parameters
[in,out]packetPacket that will be processed by the server
[in,out]resourceResource
Return values
`0`on success
Negativeerrno on failure

◆ unicoap_server_send_response_body()

int unicoap_server_send_response_body ( unicoap_packet_t * packet,
const unicoap_resource_t * resource )

Sends entire response body, may be split into parts and then sent.

Parameters
[in,out]packetResponse packet to send
[in]resourcemandatory resource which is sending this response
Returns
Zero on success, negative integer otherwise

◆ unicoap_set_listeners()

static void unicoap_set_listeners ( unicoap_state_t * state,
unicoap_listener_t * listeners )
inlinestatic

Sets listener array on state object to listeners.

Definition at line 154 of file private.h.

◆ unicoap_transport_truncate_received()

static bool unicoap_transport_truncate_received ( size_t * chunk_size,
size_t received )
inlinestatic

Determines whether the chunk of the given size must be truncated to fit into a buffer of size CONFIG_UNICOAP_PDU_SIZE_MAX.

Use this method when receiving fragmented/scattered data, e.g., when reading from a socket.

This method returns false if a chunk of the given chunk_size can still be copied into a buffer of size CONFIG_UNICOAP_PDU_SIZE_MAX when received bytes are already stored in that buffer.

If said buffer cannot store a chunk of the given size while also holding received bytes already saved, the chunk needs to be truncated. In this case, true is returned and the chunk size is truncated to the largest chunk size that is still acceptable. Stop your receiver loop as further calls to this function will, consequently, also return true and yield a chunk_size of zero (buffer is full).

Parameters
[in,out]chunk_sizeNumber of bytes in the currently received chunk. Written to if chunk does not fit into buffer.
receivedNumber of bytes already stored in the buffer (received byte count)
Returns
Boolean value indicating whether the chunk, and therefore also its size, needed to be truncated.

Definition at line 290 of file private.h.