nRF5 IoT SDK  v0.9.0
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
CoAP client/server

Nordic's smartCoAP library supports both the client role, the server role, and a mixed role of the Constrained Application Protocol (CoAP).

Applications can use this library to generate CoAP request messages and to set up servers by setting up CoAP endpoints. The memory management for the requests and responses is handled by the library, as is the token matching on responses due to a request message. This token matching will issue a call to an application-provided function that can handle the request.

Endpoints are composed by linking resources in a linked-list manner, each resource pointing to its children. This way it is possible to dynamically locate a given resource based on the CoAP URI-path options and issue a call to a specific endpoint callback function. The linked list also allows to generate a CoRE Link Format Resource Discovery string according to RFC6690.

Client role

The illustration in Figure 1 shows the flow of sending a request message from a CoAP client.

msc_coap_request_flow
Figure 1. smartCoAP request message flow.

First, the message to be sent is created and configured using smartCoAP library calls. Next, the message is scheduled for transmission by calling the send function in the library. Scheduling the message for transmission creates a copy of the serialized CoAP message and puts this copy in an internal message queue, along with some metadata that is associated with the message. Information like transport layer socket, token number, and other values is stored with the raw CoAP message. This information will be used to match the received response message with the messages in the internal queue. If the message is a confirmable request (CON request), the message will be retransmitted if no response was received within the receive time-out.

When receiving the response, the smartCoAP library will match the token of the response message, compare it against the messages in the transmission queue, issue a callback to the application function that was registered along with the request creation, and return.

The original request message in its serialized format is backed up before it is added to the transmission queue. Therefore, the request can safely be deleted at any time. Deleting a CoAP request will free only the memory allocated during creation of the request, not the serialized copy in the smartCoAP message transmission queue. This way, the application can keep the application-created request and reuse the message without having to create the message again. If token and message ID are the only values that change between requests, the request with its options and payload can be reused several times, and new serialized versions of the requests will be generated when calling the send function in the library.

Server role

The illustration in Figure 2 shows the flow of receiving a request message from a remote CoAP client. The CoAP server responds to the request after calling the method callback function of the endpoint resource.

msc_coap_response_flow
Figure 2. smartCoAP remote request message flow.

First, the endpoint resources are registered, forming a linked-list hierarchy. The first node that is registered acts as the root for subsequent operations on the endpoint resources. Next, a method callback function is set to the endpoint. (Figure 2 uses an endpoint named "light" for illustration.) This way, the client can make method calls on this resource.

When receiving the remote request, the smartCoAP library will resolve the resource that was registered earlier. It will traverse recursively through the hierarchy of resource entities and match the names against the URI-paths in the request message. When the correct resource is found, the library calls the resource method handler function that has been set by the application when registering the resource. Right before the callback is issued, a response message is created by the library. Message type and token ID are copied over to the generated response message and passed to the callback along with the original request. The method handler function can override the response message by setting a new response code, add options, or by adding a payload. When the function returns, the constructed response will be transmitted over UDP as a CoAP response message.

Endpoints

All CoAP endpoints in smartCoAP are called resources. An endpoint can be anything from a resource that is listed in the well-known URI ".well-known/core" on the CoAP server to an endpoint that controls an LED. The resources must be defined in such a way that they stay in memory during the lifetime of the application.

After coap_init has been called, any number of resources can be added. There is no extra memory needed for a resource besides the memory that is used during its declaration. All declared resources are linked together in a hierarchy using the smartCoAP library functions.

Resource Hierarchy

The first resource that is created always forms the root of the hierarchy. The coap_init function clears this information and unassigns the root again. Creating a resource does not allocate any additional memory, but rather copies the provided string into the resource and initializes the resource structure.

After the resource is created, it can be linked to another. If a child is linked to a parent, the parent will form a linked list with children, using a front and a back pointer. Each new child that is added to the same parent will be added in the back. The back pointer of the last sibling that was added is then redirected to the new child.

There is no API for removing a child resource. Therefore, the resource hierarchy must be determined during the design of the application. This resources hierarchy can also serve as basis for generating the .well-known/core string.

The example below demonstrates how to link four resources together, forming a hierarchy of resources: one root with two children, where one of the children has a child (grandchild0).

uint32_t err_code = coap_init();
APP_ERROR_CHECK(err_code);
static coap_resource_t root;
static coap_resource_t child0;
static coap_resource_t grandchild0;
static coap_resource_t child1;
// Create root.
err_code = coap_resource_create(&root, "/");
APP_ERROR_CHECK(err_code);
// Create children.
err_code = coap_resource_create(&child0, "light");
APP_ERROR_CHECK(err_code);
err_code = coap_resource_create(&grandchild0, "led0");
APP_ERROR_CHECK(err_code);
err_code = coap_resource_create(&child1, "temp");
APP_ERROR_CHECK(err_code);
// Add root of all endpoints. The first resource to be
// added will be treated as the root of the resources.
err_code = coap_resource_child_add(&root, &child0);
APP_ERROR_CHECK(err_code);
err_code = coap_resource_child_add(&root, &child1);
APP_ERROR_CHECK(err_code);
err_code = coap_resource_child_add(&child0, &grandchild0);
APP_ERROR_CHECK(err_code);

The image below shows how the resources are linked together to form a resource hierarchy. You can use this hierarchy to locate endpoints when a remote request is sent to an smartCoAP server. The image also shows how the resources in the example code above are conceptually linked together in the linked list.

coap_resource_layout.png
Figure 3. smartCoAP resource hierarchy with four registered resources.

Callback

The smartCoAP endpoints can have a callback function, which is called whenever a CoAP request that has a URI path matching with the registered resources in smartCoAP is detected. If no callback is registered for the URI path, a reply with a "404 (Not Found)" code is returned.

void resource_callback_func(coap_resource_t * p_resource, coap_message_t * p_request)
{
uint32_t err_code = coap_message_new(&p_response, &response_config);
APP_ERROR_CHECK(err_code);
...
err_code = coap_message_remote_addr_set(p_response, &p_request->remote);
APP_ERROR_CHECK(err_code);
...
switch (p_request->header.code)
{
{
p_response->header.code = COAP_CODE_205_CONTENT;
uint8_t payload[] = {1};
coap_message_payload_set(p_response, payload, sizeof(payload));
...
break;
}
case default:
{
p_response->header.code = COAP_CODE_405_METHOD_NOT_ALLOWED;
...
break;
}
}
uint32_t msg_handle;
err_code = coap_message_send(&msg_handle, p_response);
APP_ERROR_CHECK(err_code);
err_code = coap_message_delete(p_response);
APP_ERROR_CHECK(err_code);
}
...
static coap_resource_t resource;
err_code = coap_resource_create(&resource, "resource");
APP_ERROR_CHECK(err_code);
resource.callback = resource_callback_func;

Permissions

Each endpoint can be configured with different access permissions. Each method can be allowed or not allowed; if no permissions are explicitly defined, the default is to not allow any methods on the endpoint.

The example below demonstrates how to set the permissions of a fictive "resource" endpoint. The permission settings allow GET and PUT requests, but deny all other methods. Requests to other methods will be rejected and replied to with a "405 (Method Not Allowed)" code. The endpoint callback function will not be called but handled internally in the smartCoAP library.

static coap_resource_t resource;
err_code = coap_resource_create(&resource, "resource");
APP_ERROR_CHECK(err_code);

.well-known/core

The smartCoAP library provides an easy-to-use function for collecting the resource names to be used in a .well-known/core resource endpoint. The memory is provided from the application and must be large enough to hold all name strings of all resources plus the link format syntax. If the provided buffer does not satisfy the needed size of the generated well-known string, an error code is returned.

The function coap_resource_well_known_generate should be run once during the start-up of the application, to populate the buffer. Traversing the resource hierarchy is a costly operation if the number of resources is great. Therefore, it is assumed that the resources do not change names during the lifetime of the application.

Note
The smartCoAP does not currently support creation and deletion of resources at runtime.

The example below demonstrates how you can use the coap_resource_well_known_generate function. In this example, the well_known_core buffer is used as a global, because it can easily be accessed by both the main function that creates the resource hierarchy and the callback function for the ".well-known/core" endpoint.

static uint8_t well_known_core[100];
...
uint16_t size = sizeof(well_known_core);
err_code = coap_resource_well_known_generate(well_known_core, &size);
APP_ERROR_CHECK(err_code);

Initialization

In order to initialize coap the coap_init API call is used. The function takes two parameters:

  • A random seed. This seed is used as an initialization vector for automatic generation of message tokens.
  • List of port numbers. The list is used to create and listen on ports for CoAP. Size of the list is determined by COAP_PORT_COUNT.
Note
This API shall be called before using any other APIs of the module. If this API fails, none of the module APIs shall be used by the application.

On initialization, the transport layer for CoAP creates and listens on all the Client and Server ports. The define COAP_PORT_COUNT in the sdk_config.h of the application determines the number of ports that are reserved for CoAP communication.

Note
Onus is on the application to ensure that list size supplied as a parameter in this API is equal to the COAP_PORT_COUNT. A mismatch will result in undesirable behavior.

The example below demonstrates how to configure smartCoAP to use port 5683 as local port for CoAP.

#define COAP_PORT_COUNT 1 // From sdk_config.h.
...
// Table of ports used for CoAP server and/or client endpoints.
coap_port_t coap_ports[COAP_PORT_COUNT] =
{
{
.port_number = 5683
}
};
// CoAP transport parameters.
coap_transport_init_t transport_param =
{
.p_port_table = coap_ports
};
// Random token seed number.
uint32_t random_token_seed = 71;
// Initialization of CoAP.
err_code = coap_init(random_token_seed, &transport_param);
APP_ERROR_CHECK(err_code);

Client requests

Creating a request message

You can generate a request by using the coap_message_new API call. Use the supplied configuration as a base for creating the new message. Parts of the message can also be overridden by setting the structure members of coap_message_t after creating the request. The transport layer socket association will automatically be assigned during the creation of the request.

Note
If the id member of coap_message_conf_t is set to 0, an auto-generated message ID will be assigned to the new request message on creation.

The example below demonstrates how to create a Non-Confirmable (NON) request.

coap_message_t * request;
coap_message_conf_t message_conf;
// Set the CoAP message type to Non-Confirmable message.
message_conf.type = COAP_TYPE_NON;
// Set the CoAP method.
message_conf.code = COAP_CODE_PUT;
// Specify a token for the message.
message_conf.token[0] = 0x2;
message_conf.token[1] = 0x4;
message_conf.token_len = 2;
// Set local port number to use.
response_config.port.port_number = 5683;
// Register a callback to be run when a response for this message is received.
message_conf.response_callback = response_handle_func;
uint32_t err_code = coap_message_new(&request, &message_conf);
if (err_code == NRF_SUCCESS)
...

Setting the remote address

Before the send function is called, the remote destination must be set in the smartCoAP request message. The remote address must be set after creating the message, however, because creating the message wipes the allocated memory.

The example below demonstrates how to set the remote address. In this example, the remote address is set to [2003::4] on port number 5683.

static coap_remote_t remote;
remote.port_number = 5683;
remote.addr[0] = 0x20;
remote.addr[1] = 0x03;
remote.addr[15] = 0x04;
...
uint32_t err_code = coap_message_new(&request, &message_conf);
// Request is successfully created and memory allocation for the new request is OK.
if (err_code == NRF_SUCCESS)
{
...
// Set the remote address information.
coap_message_remote_addr_set(request, &remote);
...
// Send the message.
}

Sending the request

After a new request has been successfully created and the address and port number to the remote have been set, the message can be populated with options and payload. Then it would be ready for transmission. The function for sending a request also returns a handle by reference. There is no special usage for this handle today. On the other hand it is meant to be used in a future implementation in order to abort an ongoing confirmable message.

The example below demonstrates how to send the message:

uint32_t err_code = coap_message_new(&request, &message_conf);
if (err_code == NRF_SUCCESS)
{
...
// Trigger the message to be sent.
uint32_t msg_handle;
err_code = coap_message_send(&msg_handle, request);
if (err_code != NRF_SUCCESS)
{
// Skip it or try again.
}
}

Deleting the request

After the message has been scheduled for transmission, it can be cleaned up, so that all of its memory allocations are freed. This function must be explicitly called unless the application reuses the created message.

The example below demonstrates how to delete the message:

coap_message_t * request;
coap_message_conf_t message_conf;
...
uint32_t err_code = coap_message_new(&request, &message_conf);
...
// Clean up the memory used by the request message.
err_code = coap_message_delete(request);
APP_ERROR_CHECK(err_code);

Full client example

The code below sends a CoAP NON request to coap://[2004::b1]:5683/light/led0, doing a PUT with a one-byte payload.

void response_handler(uint32_t status, void * arg, coap_message_t * p_response)
{
if (status == NRF_SUCCESS)
{
...
}
}
coap_message_t * request;
coap_message_conf_t message_conf;
// Set remote address to 2004::b1 to the CoAP server.
remote.addr[0] = 0x20;
remote.addr[1] = 0x04;
remote.addr[15] = 0xb1;
// Set port number of the CoAP server.
remote.port_number = 5683;
// Set the CoAP message type to Non-confirmable message.
message_conf.type = COAP_TYPE_NON;
// Set the CoAP method.
message_conf.code = COAP_CODE_PUT;
// Specify a token for the message.
message_conf.token[0] = 0x3;
message_conf.token[1] = 0x4;
message_conf.token_len = 2;
// Set local port number to use.
response_config.port.port_number = 5683;
// Register a callback to be run when a response for this message is received.
message_conf.response_callback = response_handler;
uint32_t err_code = coap_message_new(&request, &message_conf);
if (err_code == NRF_SUCCESS)
{
// Set remote address and port number to the CoAP server.
coap_message_remote_addr_set(request, &remote);
// Add URI path to the endpoint.
err_code = coap_message_opt_str_add(request, COAP_OPT_URI_PATH, (uint8_t *)"light", 5);
APP_ERROR_CHECK(err_code);
err_code = coap_message_opt_str_add(request, COAP_OPT_URI_PATH, (uint8_t *)"led0", 4);
APP_ERROR_CHECK(err_code);
// Add the PUT payload.
uint8_t payload[] = {1};
err_code = coap_message_payload_set(request, payload, sizeof(payload));
APP_ERROR_CHECK(err_code);
// Trigger the message to be sent.
uint32_t msg_handle;
err_code = coap_message_send(&msg_handle, request);
if (err_code != NRF_SUCCESS)
{
// Skip it or try again.
}
// Clean up the memory used by the request message.
err_code = coap_message_delete(request);
APP_ERROR_CHECK(err_code);
}

Message retransmission

In order to handle retransmission and time-outs, smartCoAP has to be provided with a continuous tick. The coap_time_tick API function has to be called every second from the application. The function will go through any outstanding messages in the transmission queue and retransmit them if needed. Or, smartCoAP will flag to the application that a time-out has occurred and remove the message from the transmission queue.

DTLS-Secured CoAP

Nordic's smartCoAP library implements secure transport for CoAP transactions using DTLS. The library submodule that implements DTLS as an optional transport for CoAP is coap_transport_dtls.c.

When using DTLS as a transport for CoAP, additional configuration of COAP_MAX_REMOTE_SESSION in the sdk_config.h is needed. This parameter determines the number of simultaneous DTLS sessions that can be managed by the transport layer for both server and client roles. There is no direct correlation between the COAP_PORT_COUNT and the COAP_MAX_REMOTE_SESSION.

For example, an application playing the client role, one port may be sufficient to communicate with serveral servers, therefore COAP_PORT_COUNT is 1. However, the application must ensure that the COAP_MAX_REMOTE_SESSION is equal to the number of remote CoAP servers that it needs to communicate with securely.

Note
The DTLS transport for CoAP ensures one DTLS session between local and remote endpoints. Therefore, an application acting as a client and server using the same local port towards the same peer endpoint (same address and port) would have a single DTLS session for communication for both server and client roles. If this behavior is undesirable, the application shall use different local ports for server and client roles and configure the COAP_MAX_REMOTE_SESSION to ensure simultaneous connections for each role.

The code below demonstrates how the port configuration could be set to use one common local port for two clients. Each client targetting a different peer server.

// Configuration in sdk_config.h
#define COAP_PORT_COUNT 1
#define COAP_MAX_REMOTE_SESSION 2
...
coap_port_t local_port_list[COAP_PORT_COUNT] =
{
{
.port_number = 5684
}
};
port_list.p_port_table = local_port_list;
uint32_t err_code = coap_init(17, &port_list);
APP_ERROR_CHECK(err_code);

Setting up a DTLS session

In order that CoAP messages are secured using DTLS transport, setting up necessary security parameters are required using the coap_security_setup API. This API configures the key settings and role for the DTLS session for a local endpoint. For the client role, the remote server needs to be identified with the DTLS session. On the other hand, for the server role, since it is not possible to identify the clients that will connect to it, no remote client identification is expected.

For the client role, coap_security_setup will trigger DTLS handshake with the remote server. For the server role, no DTLS procedures are triggered until a remote client transmits a message to the local server endpoint.

Note
If no security parameters are set-up, the transport will default to non secure UDP.
Currently, only Pre-Shared Keys are supported for DTLS.

Acting as DTLS client

The code below demonstrates how to configure a secure session and trigger initiating the DTLS handshake as a client using DTLS Pre-Shared Key mode.

remote.addr = ...
remote.port_number = ...
...
char key_identity[] = "identity";
char key_secret[] = "topsecret";
m_preshared_key.p_identity = (uint8_t *)key_identity;
m_preshared_key.identity_len = strlen(key_identity);
m_preshared_key.p_secret_key = (uint8_t *)key_secret;
m_preshared_key.secret_key_len = strlen(key_secret);
key_settings.p_psk = &preshared_key;
// Allocate DTLS instance and initiate a handshake with the remote peer.
err_code = coap_security_setup(5684,
&remote,
&key_settings);
APP_ERROR_CHECK(err_code);

Acting as DTLS server

When the application is acting as a DTLS server, the remote is not required as it not known in advance what the remote peer address and port number it will use. This is handled by just passing a NULL pointer as parameter for the remote.

The code below demonstrates how to configure a secure session as a server waiting for remote peers to initiate connection using DTLS Pre-Shared Key mode.

char key_identity[] = "identity";
char key_secret[] = "topsecret";
m_preshared_key.p_identity = (uint8_t *)key_identity;
m_preshared_key.identity_len = strlen(key_identity);
m_preshared_key.p_secret_key = (uint8_t *)key_secret;
m_preshared_key.secret_key_len = strlen(key_secret);
key_settings.p_psk = &preshared_key;
// Allocate DTLS instance and wait for connections to be initiated by remote clients.
err_code = coap_security_setup(5684,
NULL, // No remote identification.
&key_settings);
APP_ERROR_CHECK(err_code);
Note
For the client role, security setup has to be performed for each remote server it wishes to communicate with securely. Therefore, it is possible for a client application to multiplex secure and non-secure communication on the same local endpoint based on the remote server it is communicating with. However, for the server role, the security set-up for the local endpoint and therefore all remote clients communicating with the server on its local secure port must initiate DTLS procedures to successfully communicate with the server.

It is also possible to use a local port configured to use DTLS-Secured CoAP for non-secure CoAP messages. Even if the secure session is set up and in use, it is possible to send CoAP messages using the same port to a different peer address. If the peer address is matching the one already registered to be secure, it will be sent as secure CoAP message using DTLS. The same applies if the DTLS session is not yet set up or used. If the remote peer address is not indicated to be using secure CoAP messages, it will default to use the port sending it as non-secure.

Removing a DTLS session

In order to tear down a secure session established between the local and remote endpoints set up, the coap_security_destroy API is used. It is also possible to tear down all sessions associated with a local endpoint, irrespective of the role, by setting the remote endpoint to NULL.

Behavipr of this API is independent of the roles played on the local port. And it is possible to tear down either a specific DTLS session or all DTLS sessions associated with the local endpoint.

The code below shows how to clean up a specific session.

remote.addr = ...
remote.port_number = ...
...
// Remove the specific session on local port 5683 associated with the remote provided.
err_code = coap_security_destroy(5684, &remote);
APP_ERROR_CHECK(err_code);

The code below shows how to clean up for all sessions assocated with the local port.

remote.addr = ...
remote.port_number = ...
...
// Remove the specific session on local port 5683 associated with the remote provided.
err_code = coap_security_destroy(5684, NULL);
APP_ERROR_CHECK(err_code);

Configuration parameters

The following configuration parameters should be defined in sdk_config.h.

COAP_DISABLE_LOGS

Disables debug tracing in the module. To enable tracing, this flag must be set to 0 and ENABLE_DEBUG_LOG_SUPPORT must be set to 1.

Description Value
Enable debug trace 0
Disable debug trace 1
Dependencies ENABLE_DEBUG_LOG_SUPPORT

COAP_DISABLE_API_PARAM_CHECK

Disables API parameter checks in the module. Set this define to 1 to disable checks on API parameters in the module.

API parameter checks are added to ensure that the correct parameters are passed to the module. These checks are useful during development phase, but they might be redundant when the application is finalized. Disabling these checks might improve performance.

Description Value
Enable API parameters check 0
Disable API parameters check 1
Dependencies None

COAP_VERSION

Default version number used in a CoAP packet.

Restriction Value
Minimum value 0
Maximum value 3
Recommended value 1
Dependencies None

COAP_PORT_COUNT

Maximum number of client/server ports used by the application. One socket will be created for each port.

Restriction Value
Minimum value 0
Maximum value UDP6_MAX_SOCKET_COUNT
Dependencies UDP6_MAX_SOCKET_COUNT

COAP_MAX_NUMBER_OF_OPTIONS

Maximum number of options that the smartCoAP library can process. If the maximum limit is reached, the library will treat the package as unprocessable.

Restriction Value
Minimum value 1
Maximum value 255
Dependencies None

COAP_MESSAGE_DATA_MAX_SIZE

Maximum size of a smartCoAP message excluding the mandatory CoAP header.

Restriction Value
Minimum value 1
Maximum value 65535
Dependencies None

COAP_MESSAGE_QUEUE_SIZE

Maximum number of smartCoAP messages that can be in transmission at a time.

smartCoAP uses the Memory Manager that is also used by the underlying transport protocol. Therefore, if you increase this value, you should also increase the number of buffers. Depending on the COAP_MESSAGE_DATA_MAX_SIZE + 4 byte CoAP header, you must increase either MEMORY_MANAGER_SMALL_BLOCK_COUNT or MEMORY_MANAGER_MEDIUM_BLOCK_COUNT to ensure that there are additional buffers for the CoAP message queue. Which macro must be increased, depends on the size of the buffer that is sufficient for the CoAP message.

Restriction Value
Minimum value 1
Maximum value 65535
Recommended value 4
Dependencies MEMORY_MANAGER_SMALL_BLOCK_COUNT
MEMORY_MANAGER_MEDIUM_BLOCK_COUNT
MEMORY_MANAGER_SMALL_BLOCK_SIZE
MEMORY_MANAGER_MEDIUM_BLOCK_SIZE

COAP_RESOURCE_MAX_NAME_LEN

Maximum length of the resource name that can be supplied from the application.

Note
One extra byte will be added to the resource name to make sure that the provided string is zero terminated.
Restriction Value
Minimum value 1
Maximum value 65535
Dependencies None

COAP_RESOURCE_MAX_DEPTH

Maximum number of resource depth levels that smartCoAP will use. The number is used when adding resources to the resource structure or when traversing the resources for a matching resource name given in a request. Each added level increases the stack usage runtime with 4 bytes.

Restriction Value
Minimum value 1
Maximum value 255
Recommended value 1 - 10
Dependencies None

COAP_MAX_RETRANSMIT_COUNT

Maximum number of transmit attempts for a Confirmable message.

Restriction Value
Minimum value 0
Maximum value 255
Recommended value 4
Dependencies None

COAP_MAX_TRANSMISSION_SPAN

Maximum time from the first transmission of a Confirmable message to its last retransmission.

Restriction Value
Minimum value 0
Maximum value 65535
Recommended value 45
Dependencies None

COAP_ACK_TIMEOUT

Minimum spacing before another retransmission.

Restriction Value
Minimum value 0
Maximum value COAP_MAX_TRANSMISSION_SPAN / COAP_MAX_RETRANSMIT_COUNT
Recommended value 2
Dependencies None

COAP_ACK_RANDOM_FACTOR

Random factor to calculate the initial time-out value for a Confirmable message.

Restriction Value
Minimum value 0
Maximum value COAP_MAX_TRANSMISSION_SPAN / COAP_MAX_RETRANSMIT_COUNT / COAP_ACK_TIMEOUT
Recommended value 1.5
Dependencies None

COAP_MAX_REMOTE_SESSION

The maximum number of simultanous DTLS-Secure CoAP connections the application can have.

Restriction Value
Minimum value 0
Maximum value NRF_TLS_MAX_INSTANCE_COUNT
Dependencies NRF_TLS_MAX_INSTANCE_COUNT

Specifics and limitations

The following sections describe the specifics and limitations to the current implementation.

Implemented features

  • CoAP message types CON, NON, ACK, and RESET.
  • Automatic generation of message ID.
  • Token matching on responses to a request generated by a local client.
  • Callback on response to a request generated by a local client.
  • Endpoint creation as resources.
  • Automatic lookup of requested endpoint when receiving a remote request.
  • Endpoint resource function callback to perform an action or to create response message.
  • Auto generation of 404 (Not Found) response message if the resource is not located among the registered resources.
  • Auto generation of 405 (Method Not Allowed) response message if the located endpoint has a permission scheme not allowing the method to be executed on the endpoint resource.
  • Permission setting on endpoints to select methods to be handled by the endpoint resource callback function.
  • CoAP ping (empty message).
  • NON request/reply.
  • CON request/reply (piggybacked).
  • ACK message generated automatically on CON requests.
  • Automatic generation of .well-known/core link format discovery string.
  • Content format support. Resource handlers have access to bitmask indicating which content format the requesting client accepts. Resources also have a bitmask indicating the supported content formats.
  • Simple CON retransmission implemented in order to generate TRANSMISSION_TIMEOUT events.
  • ACK and Reset messages are clearing the original request from the message queue on reception.
  • Messages in the transmission queue are trimmed off the queue if no matching token has been received. The value of COAP_MAX_TRANSMISSION_SPAN is used as max time-out for both NON and CON (in addition to retransmission count).

Limitations

  • Delete message type is not supported.
  • No resource creation on POST and PUT methods.
  • Duplicate message detection is not implemented in the current library.
  • No multicast support.
  • Not supporting the proxy role.
  • Generating unique tokens is left to the application in the current implementation of the library.
  • Currently Pre-Shared Key is the only supported mode when using DTLS-Secured CoAP.
  • No automatic handling of unrecognized critical options. The library does not detect and handle well known options. Therefore all handling of these options per resource, including error handling, is left to the application.

References