Nanocoap Sock

Synchronous sock based messaging with nanocoap. More...

Detailed Description

Synchronous sock based messaging with nanocoap.

nanocoap sock uses the nanocoap CoAP library to provide a synchronous interface to RIOT's sock networking API to read and write CoAP messages. For a server, nanocoap sock accepts a list of resource paths with callbacks for writing the response. For a client, nanocoap sock provides a function to send a request and waits for the server response. nanocoap sock uses nanocoap's Buffer API to write message options.

Server Operation

See the nanocoap_server example, which is built on the nanocoap_server() function. A server must define an array of coap_resource_t resources for which it responds. See the declarations of coap_resources and coap_resources_numof. The array contents must be ordered by the resource path, specifically the ASCII encoding of the path characters (digit and capital precede lower case). Also see Server path matching in the base nanocoap documentation.

nanocoap itself provides the COAP_WELL_KNOWN_CORE_DEFAULT_HANDLER entry for /.well-known/core.

Handler functions

For each resource, you must implement a coap_handler_t handler function. nanocoap provides functions to help implement the handler. If the handler is called via nanocoap_server(), the response buffer provided to the handler reuses the buffer for the request. So, your handler must read the request thoroughly before writing the response.

To read the request, use the functions in the Header and Options Read sections of the nanocoap documentation. If the pkt payload_len attribute is a positive value, start to read it at the payload pointer attribute.

If a response does not require specific CoAP options, use coap_reply_simple(). If there is a payload, it writes a Content-Format option with the provided value.

For a response with additional CoAP options, start by calling coap_build_reply(). Then use the Buffer API to write the rest of the response. See the instructions in the section Write Options and Payload below.

Client Operation

Follow the instructions in the section Write Options and Payload below.

To send the message and await the response, see nanocoap_request() as well as nanocoap_get(), which additionally copies the response payload to a user supplied buffer. Finally, read the response as described above in the server Handler functions section for reading a request.

Write Options and Payload

For both server responses and client requests, CoAP uses an Option mechanism to encode message metadata that is not required for each message. For example, the resource URI path is required only for a request, and is encoded as the Uri-Path option.

nanocoap sock uses the nanocoap Buffer API for options. The caller must provide the last option number written as well as the buffer position. The caller is primarily responsible for tracking and managing the space remaining in the buffer.

Before starting, ensure the CoAP header has been initialized with coap_build_hdr(). For a response, coap_build_reply() includes a call to coap_build_hdr(). Use the returned length to track the next position in the buffer to write and remaining length.

Next, use the functions in the Options Write Buffer API section of nanocoap to write each option. These functions require the position in the buffer to start writing, and return the number of bytes written. Options must be written in order by option number (see "CoAP option numbers" in CoAP defines).

Note
You must ensure the buffer has enough space remaining to write each option. The API does not verify the safety of writing an option.

If there is a payload, append a payload marker (0xFF). Then write the payload to within the maximum length remaining in the buffer.

Create a Block-wise Response (Block2)

Block-wise is a CoAP extension (RFC 7959) to divide a large payload across multiple physical packets. This section describes how to write a block-wise payload for a response, and is known as Block2. (Block1 is for a block-wise payload in a request.) See _riot_board_handler() in the nanocoap_server example for an example handler implementation.

Start with coap_block2_init() to read the client request and initialize a coap_slicer_t struct with the size and location for this slice of the overall payload. Then write the block2 option in the response with coap_opt_put_block2(). The option includes an indicator ("more") that a slice completes the overall payload transfer. You may not know the value for more at this point, but you must initialize the space in the packet for the option before writing the payload. The option is rewritten later.

Next, use the coap_blockwise_put_xxx() functions to write the payload content. These functions use the coap_block_slicer_t to enable or disable actually writing the content, depending on the current position within the overall payload transfer.

Finally, use the convenience function coap_block2_build_reply(), which finalizes the packet and calls coap_block2_finish() internally to update the block2 option.

Files

file  nanocoap_sock.h
 nanocoap high-level API
 
file  nanocoap_vfs.h
 VFS NanoCoAP helper functions.
 

Data Structures

struct  coap_block_request_t
 Blockwise request helper struct. More...
 

Typedefs

typedef sock_udp_t nanocoap_sock_t
 nanocoap socket type
 

Functions

int nanocoap_server (sock_udp_ep_t *local, uint8_t *buf, size_t bufsize)
 Start a nanocoap server instance. More...
 
static int nanocoap_sock_connect (nanocoap_sock_t *sock, const sock_udp_ep_t *local, const sock_udp_ep_t *remote)
 Create a CoAP client socket. More...
 
int nanocoap_sock_url_connect (const char *url, nanocoap_sock_t *sock)
 Create a CoAP client socket by URL. More...
 
static void nanocoap_sock_close (nanocoap_sock_t *sock)
 Close a CoAP client socket. More...
 
ssize_t nanocoap_sock_get (nanocoap_sock_t *sock, const char *path, void *buf, size_t len)
 Simple synchronous CoAP (confirmable) GET. More...
 
ssize_t nanocoap_sock_put (nanocoap_sock_t *sock, const char *path, const void *request, size_t len, void *response, size_t len_max)
 Simple synchronous CoAP (confirmable) PUT. More...
 
ssize_t nanocoap_sock_post (nanocoap_sock_t *sock, const char *path, const void *request, size_t len, void *response, size_t len_max)
 Simple synchronous CoAP (confirmable) POST. More...
 
int nanocoap_sock_get_blockwise (nanocoap_sock_t *sock, const char *path, coap_blksize_t blksize, coap_blockwise_cb_t callback, void *arg)
 Performs a blockwise coap get request on a socket. More...
 
int nanocoap_get_blockwise_url (const char *url, coap_blksize_t blksize, coap_blockwise_cb_t callback, void *arg)
 Performs a blockwise coap get request to the specified url. More...
 
ssize_t nanocoap_get_blockwise_url_to_buf (const char *url, coap_blksize_t blksize, void *buf, size_t len)
 Performs a blockwise coap get request to the specified url, store the response in a buffer. More...
 
ssize_t nanocoap_sock_request (nanocoap_sock_t *sock, coap_pkt_t *pkt, size_t len)
 Simple synchronous CoAP request. More...
 
ssize_t nanocoap_sock_request_cb (sock_udp_t *sock, coap_pkt_t *pkt, coap_request_cb_t cb, void *arg)
 Simple synchronous CoAP request with callback. More...
 
ssize_t nanocoap_request (coap_pkt_t *pkt, const sock_udp_ep_t *local, const sock_udp_ep_t *remote, size_t len)
 Simple synchronous CoAP request. More...
 
ssize_t nanocoap_get (const sock_udp_ep_t *remote, const char *path, void *buf, size_t len)
 Simple synchronous CoAP (confirmable) get. More...
 
static int nanocoap_block_request_init (coap_block_request_t *ctx, const sock_udp_ep_t *remote, const char *path, uint8_t method, coap_blksize_t blksize)
 Initialize block request context. More...
 
static int nanocoap_block_request_init_url (coap_block_request_t *ctx, const char *url, uint8_t method, coap_blksize_t blksize)
 Initialize block request context by URL. More...
 
static void nanocoap_block_request_done (coap_block_request_t *ctx)
 Free block request context. More...
 
int nanocoap_sock_block_request (coap_block_request_t *ctx, const void *data, size_t len, bool more, coap_request_cb_t cb, void *arg)
 Do a block-wise request, send a single block. More...
 

Function Documentation

◆ nanocoap_block_request_done()

static void nanocoap_block_request_done ( coap_block_request_t ctx)
inlinestatic

Free block request context.

Parameters
[out]ctxThe block request context to finalize

Definition at line 439 of file nanocoap_sock.h.

◆ nanocoap_block_request_init()

static int nanocoap_block_request_init ( coap_block_request_t ctx,
const sock_udp_ep_t remote,
const char *  path,
uint8_t  method,
coap_blksize_t  blksize 
)
inlinestatic

Initialize block request context.

Parameters
[out]ctxThe block request context to initialize
[in]remoteServer endpoint
[in]pathServer path for request
[in]methodRequest method (COAP_METHOD_{GET|PUT|POST})
[in]blksizeRequest blocksize exponent
Return values
0Success
<0Error (see nanocoap_sock_connect for details)

Definition at line 398 of file nanocoap_sock.h.

◆ nanocoap_block_request_init_url()

static int nanocoap_block_request_init_url ( coap_block_request_t ctx,
const char *  url,
uint8_t  method,
coap_blksize_t  blksize 
)
inlinestatic

Initialize block request context by URL.

Parameters
[out]ctxThe block request context to initialize
[in]urlThe request URL
[in]methodRequest method (COAP_METHOD_{GET|PUT|POST})
[in]blksizeRequest blocksize exponent
Return values
0Success
<0Error (see nanocoap_sock_url_connect for details)

Definition at line 422 of file nanocoap_sock.h.

◆ nanocoap_get()

ssize_t nanocoap_get ( const sock_udp_ep_t remote,
const char *  path,
void *  buf,
size_t  len 
)

Simple synchronous CoAP (confirmable) get.

Parameters
[in]remoteremote UDP endpoint
[in]pathremote path
[out]bufbuffer to write response to
[in]lenlength of buffer
Returns
length of response payload on success
<0 on error

◆ nanocoap_get_blockwise_url()

int nanocoap_get_blockwise_url ( const char *  url,
coap_blksize_t  blksize,
coap_blockwise_cb_t  callback,
void *  arg 
)

Performs a blockwise coap get request to the specified url.

This function will fetch the content of the specified resource path via block-wise-transfer. A coap_blockwise_cb_t will be called on each received block.

Parameters
[in]urlAbsolute URL pointer to source path (i.e. not containing a fragment identifier)
[in]blksizesender suggested SZX for the COAP block request
[in]callbackcallback to be executed on each received block
[in]argoptional function arguments
Returns
-EINVAL if an invalid url is provided
-1 if failed to fetch the url content
0 on success

◆ nanocoap_get_blockwise_url_to_buf()

ssize_t nanocoap_get_blockwise_url_to_buf ( const char *  url,
coap_blksize_t  blksize,
void *  buf,
size_t  len 
)

Performs a blockwise coap get request to the specified url, store the response in a buffer.

This function will fetch the content of the specified resource path via block-wise-transfer. The blocks will be re-assembled into buf

Parameters
[in]urlAbsolute URL pointer to source path (i.e. not containing a fragment identifier)
[in]blksizesender suggested SZX for the COAP block request
[in]bufTarget buffer
[in]lenTarget buffer length
Returns
<0 on error
-EINVAL if an invalid url is provided
-ENOBUFS if the provided buffer was too small
size of the response payload on success

◆ nanocoap_request()

ssize_t nanocoap_request ( coap_pkt_t pkt,
const sock_udp_ep_t local,
const sock_udp_ep_t remote,
size_t  len 
)

Simple synchronous CoAP request.

Parameters
[in,out]pktPacket struct containing the request. Is reused for the response
[in]localLocal UDP endpoint, may be NULL
[in]remoteremote UDP endpoint
[in]lenTotal length of the buffer associated with the request
Returns
length of response on success
<0 on error

◆ nanocoap_server()

int nanocoap_server ( sock_udp_ep_t local,
uint8_t *  buf,
size_t  bufsize 
)

Start a nanocoap server instance.

This function only returns if there's an error binding to local, or if receiving of UDP packets fails.

Parameters
[in]locallocal UDP endpoint to bind to
[in]bufinput buffer to use
[in]bufsizesize of buf
Returns
-1 on error

◆ nanocoap_sock_block_request()

int nanocoap_sock_block_request ( coap_block_request_t ctx,
const void *  data,
size_t  len,
bool  more,
coap_request_cb_t  cb,
void *  arg 
)

Do a block-wise request, send a single block.

     This method is expected to be called in a loop until all
     payload blocks have been transferred.
Precondition
ctx was initialized with nanocoap_block_request_init or nanocoap_block_request_init_url
Parameters
[in]ctxblockwise request context
[in]datapayload to send
[in]lenpayload length
[in]moremore blocks after this one (will be set automatically if len > block size)
[in]cbcallback for response
[in]argcallback context
Returns
Number of payload bytes written on success Negative error on failure

◆ nanocoap_sock_close()

static void nanocoap_sock_close ( nanocoap_sock_t sock)
inlinestatic

Close a CoAP client socket.

Parameters
[in]sockCoAP UDP socket

Definition at line 207 of file nanocoap_sock.h.

◆ nanocoap_sock_connect()

static int nanocoap_sock_connect ( nanocoap_sock_t sock,
const sock_udp_ep_t local,
const sock_udp_ep_t remote 
)
inlinestatic

Create a CoAP client socket.

Parameters
[out]sockCoAP UDP socket
[in]localLocal UDP endpoint, may be NULL
[in]remoteremote UDP endpoint
Returns
0 on success
<0 on error

Definition at line 184 of file nanocoap_sock.h.

◆ nanocoap_sock_get()

ssize_t nanocoap_sock_get ( nanocoap_sock_t sock,
const char *  path,
void *  buf,
size_t  len 
)

Simple synchronous CoAP (confirmable) GET.

Parameters
[in]socksocket to use for the request
[in]pathremote path
[out]bufbuffer to write response to
[in]lenlength of buffer
Returns
length of response payload on success
<0 on error

◆ nanocoap_sock_get_blockwise()

int nanocoap_sock_get_blockwise ( nanocoap_sock_t sock,
const char *  path,
coap_blksize_t  blksize,
coap_blockwise_cb_t  callback,
void *  arg 
)

Performs a blockwise coap get request on a socket.

This function will fetch the content of the specified resource path via block-wise-transfer. A coap_blockwise_cb_t will be called on each received block.

Parameters
[in]socksocket to use for the request
[in]pathpointer to source path
[in]blksizesender suggested SZX for the COAP block request
[in]callbackcallback to be executed on each received block
[in]argoptional function arguments
Returns
-1 if failed to fetch the url content
0 on success

◆ nanocoap_sock_post()

ssize_t nanocoap_sock_post ( nanocoap_sock_t sock,
const char *  path,
const void *  request,
size_t  len,
void *  response,
size_t  len_max 
)

Simple synchronous CoAP (confirmable) POST.

Parameters
[in]socksocket to use for the request
[in]pathremote path
[in]requestbuffer containing the payload
[in]lenlength of the payload to send
[out]responsebuffer for the response, may be NULL
[in]len_maxlength of response
Returns
length of response payload on success
<0 on error

◆ nanocoap_sock_put()

ssize_t nanocoap_sock_put ( nanocoap_sock_t sock,
const char *  path,
const void *  request,
size_t  len,
void *  response,
size_t  len_max 
)

Simple synchronous CoAP (confirmable) PUT.

Parameters
[in]socksocket to use for the request
[in]pathremote path
[in]requestbuffer containing the payload
[in]lenlength of the payload to send
[out]responsebuffer for the response, may be NULL
[in]len_maxlength of response
Returns
length of response payload on success
<0 on error

◆ nanocoap_sock_request()

ssize_t nanocoap_sock_request ( nanocoap_sock_t sock,
coap_pkt_t pkt,
size_t  len 
)

Simple synchronous CoAP request.

Parameters
[in]socksocket to use for the request
[in,out]pktPacket struct containing the request. Is reused for the response
[in]lenTotal length of the buffer associated with the request
Returns
length of response on success
<0 on error

◆ nanocoap_sock_request_cb()

ssize_t nanocoap_sock_request_cb ( sock_udp_t sock,
coap_pkt_t pkt,
coap_request_cb_t  cb,
void *  arg 
)

Simple synchronous CoAP request with callback.

     The response will be handled by a callback, which avoids copying the
     response packet out of the network stack internal buffer.
Parameters
[in]socksocket to use for the request
[in,out]pktPacket struct containing the request. Is reused for the response
[in]cbCallback executed for response packet
[in]argOptional callback argumnent
Returns
length of response on success
<0 on error

◆ nanocoap_sock_url_connect()

int nanocoap_sock_url_connect ( const char *  url,
nanocoap_sock_t sock 
)

Create a CoAP client socket by URL.

Parameters
[in]urlURL with server information to connect to
[out]sockCoAP UDP socket
Returns
0 on success
<0 on error