diff --git a/sys/include/net/nanocoap.h b/sys/include/net/nanocoap.h index 5fadbaed9867aabe1f384b2a5baa8a09df7bc585..fa1de6c7c94e487330171fb1ae01a2d48bc4dbb0 100644 --- a/sys/include/net/nanocoap.h +++ b/sys/include/net/nanocoap.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2016-17 Kaspar Schleiser <kaspar@schleiser.de> * 2018 Freie Universität Berlin + * 2018 Ken Bannister <kb2ma@runbox.com> * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -8,9 +9,102 @@ */ /** - * @defgroup net_nanocoap nanocoap small CoAP library + * @defgroup net_nanocoap Nanocoap small CoAP library * @ingroup net - * @brief Provides CoAP functionality optimized for minimal resource usage + * @brief CoAP library optimized for minimal resource usage + * + * nanocoap provides a granular, low-level interface for writing CoAP messages + * via RIOT's sock networking API. + * + * ## 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). nanocoap 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 coap_get_xxx() functions to read the header and + * options. Use the coap_opt_get_xxx() functions to read an option generically + * by data type. 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 choose either the minimal API or the struct-based + * API to write the rest of the response. See the instructions in the section + * _Write Options and Payload_ below. + * + * ## Client Operation ## + * + * Choose either the minimal API or the struct-based API to write a request. + * 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 provides two APIs for writing CoAP options: + * + * - **minimal API** requires only a reference to the buffer for the message. + * However, the caller must provide the last option number written as well as + * the buffer position. + * + * - **struct-based API** uses a coap_pkt_t struct to conveniently track each + * option as it is written and prepare for any payload. + * + * You must use one API exclusively for a given message. For either API, the + * caller must write options in order by option number (see "CoAP option + * numbers" in [CoAP defines](group__net__coap.html)). + * + * ### Minimal API ### + * + * 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 coap_opt_put_xxx() and coap_put_xxx() functions to write each + * option. These functions require the position in the buffer to start writing, + * and return the number of bytes written. + * + * If there is a payload, append a payload marker (0xFF). Then write the + * payload to within the maximum length remaining in the buffer. + * + * ### Struct-based API ### + * + * As with the minimal API, first ensure the CoAP header has been initialized + * with coap_build_hdr(). Then use coap_pkt_init() to initialize the coap_pkt_t + * struct. + * + * Next, use the coap_opt_add_xxx() functions to write each option, like + * coap_opt_add_uint(). When all options have been added, call + * coap_opt_finish(). + * + * Finally, write any message payload at the coap_pkt_t _payload_ pointer + * attribute. The _payload_len_ attribute provides the available length in the + * buffer. The option functions keep these values current as they are used. * * @{ *