CoAP#

The Wi-SUN CoAP component offers an application layer implementation built on top of the Wi-SUN stack and its socket API. The CoAP protocol is specifically designed as an Internet Application Protocol for constrained devices operating in lossy networks (as defined in RFC 7252). Wi-SUN FAN networks precisely fit this definition.

The CoAP implementation relies on the UDP transport layer for sending and receiving packets. Within the component, you'll find a set of helper functions that assist in building CoAP payloads, parsing CoAP packets, and freeing CoAP packets. Additionally, the CoAP Resource Handler service manages registered resources.

For resource discovery, the Resource Discovery request provides an interface to retrieve information about available resources. These resources have additional attributes beyond the URI (Uniform Resource Identifier) path, which can be selectively filtered using specific Resource Discovery requests.

Furthermore, the CoAP Notification service allows the creation and schedule of notifications for the remote host. The schedule time and send conditions can be customized based on the application requirements. To incorporate the CoAP component into the application, simply add it to the project and initialize it using sl_wisun_coap_init().

The CoAP component is compatible with third-party implementations, such as the libcoap server and client binaries.

The following block diagram shows the architecture of CoAP component:

coapcoap

The following example shows the CoAP resource and notification initialization:

#include <string.h>
#include "sl_wisun_coap.h"
#include "sl_wisun_coap_rhnd.h"
#include "sl_wisun_coap_notify.h"

#define NOTIFY_URI_PATH "notify/temperature"

// CoAP Resource Handler callback
static sl_wisun_coap_packet_t *
callback_to_handle_requests(const sl_wisun_coap_packet_t * const req_packet) {
  sl_wisun_coap_packet_t *resp_packet = NULL;

  // Build pre-initialized CoAP packet with content response message code
  resp_packet = sl_wisun_coap_build_response(req_packet, COAP_MSG_CODE_RESPONSE_CONTENT);
  if (resp_packet == NULL) {
    return NULL;
  }

  // Build your CoAP payload (resp_packet->payload_ptr)
  // and set the payload length (resp_packet->payload_len)

  return resp_packet;
}

static bool condition_callback(const sl_wisun_coap_notify_t * notify) {
  // Build your notification condition and return the check result
  (void) notify;
  return true;
}

static sl_wisun_coap_packet_t *
callback_to_build_packet(const sl_wisun_coap_notify_t *notify) {
  // Initialize a CoAP Packet
  static sl_wisun_coap_packet_t pkt = {
    .msg_code = COAP_MSG_CODE_REQUEST_PUT, // Message Code: PUT request
    .msg_id = 1234, // Message ID
    .msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE, // Message type
    .content_format = COAP_CT_TEXT_PLAIN, // Content format
    .uri_path_ptr = NULL, // URI Path pointer
    .uri_path_len = 0, // URI Path length
    .payload_ptr = NULL, // Payload pointer
    .payload_len = 0, // Payload length
    .token_ptr = NULL, // Token pointer
    .token_len = 0, // Token length
    .options_list_ptr = NULL // Option list pointer
  };

  (void) notify;

  // Set the URI path
  pkt.uri_path_ptr = (uint8_t *)NOTIFY_URI_PATH;
  pkt.uri_path_len = strlen(NOTIFY_URI_PATH);

  // Set your notificaiton payload content
  // pkt.payload_ptr = your_prebuilt_buf;
  // pkt.payload_len = your_payload_length;

  // Return with the notification packet
  return &pkt;
}


static void init_resource_and_notification(void) {
  // Return value
  int32_t ret = 0;

  // Resource descriptor allocation
  sl_wisun_coap_rhnd_resource_t coap_resource = { 0 };

  // Notification handler allocation
  sl_wisun_coap_notify_t notify = { 0 };

  // Prepare resource with default content
  sl_wisun_coap_rhnd_resource_init(&coap_resource);

  // Resource URI path
  coap_resource.data.uri_path = "/sensor/temperature";

  // Resource type
  coap_resource.data.resource_type = "temp";

  // Interface
  coap_resource.data.interface = "i2c-sensor";

  // Function pointer to handle requests, like temperature measurement and response packet build.
  // Pointer type is sl_wisun_coap_packet_t * (*)(const sl_wisun_coap_packet_t * const req_packet)
  coap_resource.auto_response = callback_to_handle_requests;

  // You can initialize an extended callback instead of the standard callback type.
  // The extended callback receives the source address of the requests.
  // The function pointer type is
  // sl_wisun_coap_packet_t * (*)(const sockaddr_in6_t * const src_addr, const sl_wisun_coap_packet_t * const req_packet)
  // coap_resource.auto_response_ext = extended_callback_to_handle_requests;

  // Redirect response
  // The callback performs a response redirection. You can build your new destination address
  // and retrieve the new_addr argument
  // Pointer type is
  // void (*)(sockaddr_in6_t * const new_addr,const sl_wisun_coap_packet_t * const req_packet)
  // coap_resource.redirect_response = NULL;

  // Resource is discoverable. You can get information with resource discovery request
  // GET /.well-known/core
  coap_resource.discoverable = true;

  // Add resource to the resource list
  assert(sl_wisun_coap_rhnd_resource_add(&coap_resource) == SL_STATUS_OK);

  // Set the notification ID
  notify.id = "my-notification";

  // Set the destination address of notification
  ret = inet_pton(AF_INET6,
                  "2001:db8::1",
                  &notify.remote_addr.sin6_addr);
  assert(ret == 1);
  notify.remote_addr.sin6_port = htons(5683);

  // Set the schedule time of the notification, 1s is in the example
  notify.schedule_time_ms = 1000;

  // Initialize the condition callback.
  // The callback checks the condition whether the created CoAP packet should be sent
  // The function pointer type is bool (*)(const sl_wisun_coap_notify_t * notify)
  notify.condition_cb = condition_callback;

  // Initialize the notification handler that builds the CoAP packet
  // The function pointer type is
  // sl_wisun_coap_packet_t * (*)(const sl_wisun_coap_notify_t * notify)
  notify.hnd_cb = callback_to_build_packet;

  // Add the notification to the notification list
  assert(sl_wisun_coap_notify_add(&notify) == SL_STATUS_OK);
}

Modules#

Configurations

Type definitions

CoAP Resource Handler API

CoAP Notification API

Functions#

sl_wisun_coap_build_response(const sl_wisun_coap_packet_t *req, sl_wisun_coap_message_code_t msg_code)

Build generic response for request wrapper function.

int16_t
sl_wisun_coap_builder(uint8_t *dest_buff, const sl_wisun_coap_packet_t *message)

CoAP message builder Wi-SUN.

uint16_t
sl_wisun_coap_builder_calc_size(const sl_wisun_coap_packet_t *message)

CoAP packet calc size wrapper.

void
sl_wisun_coap_destroy_packet(sl_wisun_coap_packet_t *packet)

Destroy packet.

__STATIC_INLINE void

Destroy payload string.

__STATIC_INLINE void

Destroy URI path string.

void
sl_wisun_coap_free(void *addr)

Free Wi-SUN CoAP.

Get the library handler pointer from the internal handler structure.

char *
sl_wisun_coap_get_payload_str(const sl_wisun_coap_packet_t *const packet)

Prepare payload string.

char *
sl_wisun_coap_get_uri_path_str(const sl_wisun_coap_packet_t *const packet)

Prepare URI path string.

void
sl_wisun_coap_init(const sl_wisun_coap_tx_callback tx_callback, const sl_wisun_coap_rx_callback rx_callback, const sl_wisun_coap_version_t version)

Initialize Wi-SUN CoAP.

__STATIC_INLINE void

Initialize Wi-SUN CoAP default.

void *
sl_wisun_coap_malloc(uint16_t size)

Implement malloc.

sl_wisun_coap_parser(uint16_t packet_data_len, uint8_t *packet_data)

CoAP parser wrapper function.

void
sl_wisun_coap_print_packet(const sl_wisun_coap_packet_t *packet, const bool hex_format)

Print CoAP packets and all of attached buffer, payload, token, uri_path.

Macros#

#define

CoAP Service loop.

Function Documentation#

sl_wisun_coap_build_response#

sl_wisun_coap_packet_t * sl_wisun_coap_build_response (const sl_wisun_coap_packet_t * req, sl_wisun_coap_message_code_t msg_code)

Build generic response for request wrapper function.

Parameters
[in]req

request

[in]msg_code

message code to build

Used sn_coap_build_response. Returns

  • sl_wisun_coap_header_t* built packet ptr on the heap


Definition at line 235 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_builder#

int16_t sl_wisun_coap_builder (uint8_t * dest_buff, const sl_wisun_coap_packet_t * message)

CoAP message builder Wi-SUN.

Parameters
[out]dest_buff

destination buffer for raw message

[in]message

message structure

Used sl_wisun_coap_builder. Returns

  • int16_t On success bytes of built message, on failure -1 if CoAP header structure is wrong -2 if NULL ptr set as argument


Definition at line 225 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_builder_calc_size#

uint16_t sl_wisun_coap_builder_calc_size (const sl_wisun_coap_packet_t * message)

CoAP packet calc size wrapper.

Parameters
[in]message

message ptr

Used sn_coap_builder_calc_needed_packet_data_size. Returns

  • uint16_t size


Definition at line 214 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_destroy_packet#

void sl_wisun_coap_destroy_packet (sl_wisun_coap_packet_t * packet)

Destroy packet.

Parameters
N/Apacket

packet

It must be used to avoid memory leaks! Free the all of allocated buffer for packet


Definition at line 278 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_destroy_payload_str#

__STATIC_INLINE void sl_wisun_coap_destroy_payload_str (char * str)

Destroy payload string.

Parameters
[in]str

String

'\0' terminated string in the heap, it must be freed


Definition at line 293 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_destroy_uri_path_str#

__STATIC_INLINE void sl_wisun_coap_destroy_uri_path_str (const char * uri_str)

Destroy URI path string.

Parameters
[in]uri_str

URI string ptr

Call free on allocated pointer


Definition at line 260 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_free#

void sl_wisun_coap_free (void * addr)

Free Wi-SUN CoAP.

Parameters
N/Aaddr

address ptr

OS-dependent thread-safe implementation.


Definition at line 196 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_get_lib_handler#

const sl_wisun_coap_handle_t * sl_wisun_coap_get_lib_handler (void )

Get the library handler pointer from the internal handler structure.

Parameters
N/A

Not thread safe! It is needed only to use Pelion mbed-coap library functions Returns

  • const sl_wisun_coap_handle_t* pointer to the lib handler


Definition at line 270 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_get_payload_str#

char * sl_wisun_coap_get_payload_str (const sl_wisun_coap_packet_t *const packet)

Prepare payload string.

Parameters
[in]packet

Packet

'\0' terminated string in the heap, it must be freed Returns

  • char* payload string, NULL on error


Definition at line 286 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_get_uri_path_str#

char * sl_wisun_coap_get_uri_path_str (const sl_wisun_coap_packet_t *const packet)

Prepare URI path string.

Parameters
[in]packet

Packet

'\0' terminated string in the heap, it must be freed Returns

  • char* URI path string, NULL on error


Definition at line 253 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_init#

void sl_wisun_coap_init (const sl_wisun_coap_tx_callback tx_callback, const sl_wisun_coap_rx_callback rx_callback, const sl_wisun_coap_version_t version)

Initialize Wi-SUN CoAP.

Parameters
[in]tx_callback

TX callback, if it's NULL, the default callback is applied

[in]rx_callback

RX callback, if it's NULL, the default callback is applied

[in]version

CoAP version

Set the Wi-SUN CoAP internal descriptor.


Definition at line 170 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_init_default#

__STATIC_INLINE void sl_wisun_coap_init_default (void )

Initialize Wi-SUN CoAP default.

Parameters
N/A

Initializes the internal descriptor with default values.


Definition at line 178 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_malloc#

void * sl_wisun_coap_malloc (uint16_t size)

Implement malloc.

Parameters
N/Asize

size for malloc

OS-dependent thread-safe implementation. Returns

  • void* the memory pointer


Definition at line 189 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_parser#

sl_wisun_coap_packet_t * sl_wisun_coap_parser (uint16_t packet_data_len, uint8_t * packet_data)

CoAP parser wrapper function.

Parameters
[in]packet_data_len

packet data size

[in]packet_data

packet data ptr

Used sn_coap_parser Returns

  • sl_wisun_coap_packet_t* Parsed packet pointer


Definition at line 205 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

sl_wisun_coap_print_packet#

void sl_wisun_coap_print_packet (const sl_wisun_coap_packet_t * packet, const bool hex_format)

Print CoAP packets and all of attached buffer, payload, token, uri_path.

Parameters
[in]packet

packet to print

[in]hex_format

hex format bool to decide buffer print format

Pretty printer function, with hex format option for buffers


Definition at line 244 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h

Macro Definition Documentation#

SL_COAP_SERVICE_LOOP#

#define SL_COAP_SERVICE_LOOP
Value:
()

CoAP Service loop.


Definition at line 62 of file /mnt/raid/workspaces/ws.obQFDUprC/overlay/gsdk/app/wisun/component/coap/sl_wisun_coap.h