Provided by: libcoap2_4.2.1-1build1_amd64 bug

NAME

       coap_pdu_setup, coap_pdu_init, coap_add_token, coap_new_optlist, coap_insert_optlist,
       coap_delete_optlist, coap_add_optlist_pdu, coap_add_option, coap_add_data - Work with CoAP
       PDUs

SYNOPSIS

       #include <coap2/coap.h>

       coap_pdu_t *coap_pdu_init(uint8_t type, uint8_t code, uint16_t message_id, size_t
       max_size);

       int coap_add_token(coap_pdu_t *pdu, size_t length, const uint8_t *data);

       coap_optlist_t *coap_new_optlist(uint16_t number, size_t length, const uint8_t *data);

       int coap_insert_optlist(coap_optlist_t **optlist_chain, coap_optlist_t *optlist);

       void coap_delete_optlist(coap_optlist_t *optlist_chain);

       int coap_add_optlist_pdu(coap_pdu_t *pdu, coap_optlist_t **optlist_chain);

       size_t coap_add_option(coap_pdu_t *pdu, uint16_t number, size_t length, const uint8_t
       *data);

       int coap_add_data(coap_pdu_t *pdu, size_t length, const uint8_t *data);

       void coap_add_data_blocked_response(coap_resource_t *resource, coap_session_t *session,
       coap_pdu_t *request, coap_pdu_t *response, const coap_binary_t *token, uint16_t
       media_type, int maxage, size_t length, const uint8_t data);

       unsigned int coap_encode_var_safe(uint8_t *buffer, size_t size, unsigned int value);

       int coap_split_path(const uint8_t *path, size_t length, uint8_t *buffer, size_t *buflen);

       int coap_split_query(const uint8_t *query, size_t length, uint8_t *buffer, size_t
       *buflen);

       Link with -lcoap-2, -lcoap-2-gnutls, -lcoap-2-openssl or -lcoap-2-tinydtls depending on
       your (D)TLS library type.

DESCRIPTION

       The CoAP PDU is of the form


       --header--|--optional token--|--optional options--|--optional payload--
       The PDU must be built in the correct order, from left to right. In particular, the options
       need to be added in the correct numerical option order as they are stored in the PDU using
       relative numeric offsets from the previous option number.

       There are option list functions available where options can be added to a chained list of
       options and then the chain list is sorted and then be added to the PDU.

       Typically for clients, when creating a request, the PDU needs to be created before filling
       it with the appropriate information.

       Typically with a server, the response PDU, with the optional token already added in, will
       already be created before the response handler is called, and the response PDU will need
       to be updated as appropriate starting with the optional options. Note that updating the
       response pdu’s code variable will cause the response pdu to get transmitted. If code does
       not get updated, then the response pdu is freed off by the underlying library.

       The coap_pdu_init() function returns a newly created PDU of type coap_pdu_t*. type is one
       of the following

       COAP_MESSAGE_CON   Set the PDU to be of type
                          confirmable.

       COAP_MESSAGE_NON   Set the PDU to be of type
                          non-confirmable.

       COAP_MESSAGE_ACK   Set the PDU to be of type
                          acknowledge (for internal use).

       COAP_MESSAGE_RST   Set the PDU to be of type reset.

       The code is one of the following

       COAP_REQUEST_GET      Set the PDU request to be of
                             type GET.

       COAP_REQUEST_POST     Set the PDU request to be of
                             type POST.

       COAP_REQUEST_PUT      Set the PDU request to be of
                             type PUT.

       COAP_REQUEST_DELETE   Set the PDU request to be of
                             type DELETE.

       COAP_REQUEST_FETCH    Set the PDU request to be of
                             type FETCH.

       COAP_REQUEST_PATCH    Set the PDU request to be of
                             type PATCH.

       COAP_REQUEST_IPATCH   Set the PDU request to be of
                             type IPATCH.

       The message_id must be unique per request (which is not the same as the token), and must
       not be reused within EXCHANGE_LIFETIME (usually 247 seconds). To automate this, the
       function coap_new_message_id(session) should be called.

       The max_size parameter defines the maximum size of a PDU and is usually determined by
       calling coap_session_max_pdu_size(session);

       The coap_add_token() function adds in the specified token’s data of length length to the
       PDU pdu. The maximum length of the token is 8 bytes. Adding the token must be done before
       any options or data are added. This function must only be called once per pdu, and must
       not be called in the appropriate response handler.

       The coap_new_optlist() function returns a newly created optlist entry of type
       coap_optlist_t*. The number specifies which CoAP option is to be used, and is one of the
       COAP_OPTION_* definitions. The length is the length of the data of the option, and data
       points to the content of the option.

       The following is the current list of options with their numeric value

           #define COAP_OPTION_IF_MATCH        1 /* opaque, 0-8 B */
           #define COAP_OPTION_URI_HOST        3 /* String, 1-255 B */
           #define COAP_OPTION_ETAG            4 /* opaque, 1-8 B */
           #define COAP_OPTION_IF_NONE_MATCH   5 /* empty,  0 B */
           #define COAP_OPTION_OBSERVE         6 /* empty/uint, 0 B/0-3 B */
           #define COAP_OPTION_URI_PORT        7 /* uint, 0-2 B */
           #define COAP_OPTION_LOCATION_PATH   8 /* String, 0-255 B */
           #define COAP_OPTION_URI_PATH       11 /* String, 0-255 B */
           #define COAP_OPTION_CONTENT_FORMAT 12 /* uint, 0-2 B */
           #define COAP_OPTION_MAXAGE         14 /* uint, 0-4 B, default 60 Seconds */
           #define COAP_OPTION_URI_QUERY      15 /* String, 1-255 B */
           #define COAP_OPTION_ACCEPT         17 /* uint, 0-2 B */
           #define COAP_OPTION_LOCATION_QUERY 20 /* String, 0-255 B */
           #define COAP_OPTION_BLOCK2         23 /* uint, 0-3 B */
           #define COAP_OPTION_BLOCK1         27 /* uint, 0-3 B */
           #define COAP_OPTION_SIZE2          28 /* uint, 0-4 B */
           #define COAP_OPTION_PROXY_URI      35 /* String, 1-1034 B */
           #define COAP_OPTION_PROXY_SCHEME   39 /* String, 1-255 B */
           #define COAP_OPTION_SIZE1          60 /* uint, 0-4 B */
           #define COAP_OPTION_NORESPONSE    258 /* uint, 0-1 B */

       See FURTHER INFORMATION as to how to get the latest list.

       The coap_insert_optlist() function adds the optlist entry onto the optlist_chain and then
       sorts the optlist_chain before returning. The initial optlist_chain entry needs to be set
       to NULL before this function is first called. The coap_delete_optlist() function has to be
       called to free off all the optlist_chain entries.

       The coap_delete_optlist() function deletes and frees off all the optlist entries in the
       optlist_chain.

       The coap_add_optlist_pdu() function sorts all of the entries in optlist_chain into
       ascending option numeric order and adds all the entries to the pdu. This function does not
       free off the entries in optlist_chain. This function must be called after adding any token
       and before adding in the payload data.

       The coap_add_option() function adds in the specified option of type number with data of
       length length to the PDU pdu. It is critical that options are added to the pdu with number
       either being the same or greater than the previous option number that was added.

       The coap_add_data() function adds in the specified payload data of length length to the
       PDU pdu. Adding the payload data must be done after any token or options are added. This
       function must only be called once per pdu.

       The coap_add_data_blocked_response() function adds in the appropriate part of the payload
       data of length length to the PDU pdu. It should be used as a direct replacement for
       coap_add_data() if it is possible that the data will not fit into a single pdu. It also
       adds in the appropriate CoAP options to handle Block-Wise transfer. This function is
       usually used for a server’s GET response. The resource, session, request, response and
       token are the same parameters for the registered GET resource handler. The media_type is
       for the format of the data and maxage defines the lifetime of the response. If set to -1,
       then the MAXAGE option does not get included. This function must only be called once per
       pdu. It is the responsibility of the client to recognize that it has only received a part
       of the data and request the next block (with the appropriate Block options) from the
       server. Returning the next requested block is handled by this function.

       The coap_encode_var_safe() function encodes value into buffer which has a size of size in
       bytes. Normally, the buffer size should be at least the sizeof(int) bytes unless you
       definitely know less space is required.

       The coap_split_path() function splits up path of length length and places the result in
       buffer which has a size of buflen. buflen needs to be preset with the size of buffer
       before the function call, and then buflen is updated with the actual size of buffer used.

       The coap_split_query() function splits up query of length length and places the result in
       buffer which has a size of buflen. buflen needs to be preset with the size of buffer
       before the function call, and then buflen is updated with the actual size of buffer used.

RETURN VALUES

       The coap_pdu_init() function returns a newly created PDU or NULL if there is a malloc or
       parameter failure.

       The coap_new_optlist() function returns a newly created optlist or NULL if there is a
       malloc failure.

       The coap_add_token(), coap_insert_optlist(), coap_delete_optlist(), coap_add_optlist_pdu()
       and coap_add_data() functions return 0 on failure, 1 on success.

       The coap_add_optlist() function returns either the length of the option or 0 on failure.

       The coap_encode_var_safe() function returns either the length of bytes encoded or 0 on
       failure.

EXAMPLES

       Setup PDU and Transmit

           #include <coap2/coap.h>

           static int token = 0;

           int
           build_send_pdu(coap_context_t *context, coap_session_t *session,
           uint8_t msgtype, uint8_t request_code, const char *uri, const char *query,
           unsigned char *data, size_t length, int observe) {

             coap_pdu_t *pdu;
             (void)context;
             char buf[1024];
             size_t buflen;
             char *sbuf = buf;
             int res;
             coap_optlist_t *optlist_chain = NULL;

             /* Create the pdu with the appropriate options */
             pdu = coap_pdu_init(msgtype, request_code, coap_new_message_id(session),
                                 coap_session_max_pdu_size(session));
             if (!pdu)
               return 0;

             /*
              * Create uniqueness token for this request for handling unsolicited /
              * delayed responses
              */
             token++;
             if (!coap_add_token(pdu, sizeof(token), (unsigned char*)&token)) {
               coap_log(LOG_DEBUG, "cannot add token to request\n");
               goto error;
             }

             if (uri) {
               /* Add in the URI options */
               buflen = sizeof(buf);
               res = coap_split_path((const uint8_t*)uri, strlen(uri), sbuf, &buflen);
               while (res--) {
                 if (!coap_insert_optlist(&optlist_chain,
                                          coap_new_optlist(COAP_OPTION_URI_PATH,
                                   coap_opt_length(sbuf), coap_opt_value(sbuf))))
                   goto error;
                 sbuf += coap_opt_size(sbuf);
               }
             }

             if (query) {
               /* Add in the QUERY options */
               buflen = sizeof(buf);
               res = coap_split_query((const uint8_t*)query, strlen(query), sbuf, &buflen);
               while (res--) {
                 if (!coap_insert_optlist(&optlist_chain,
                                          coap_new_optlist(COAP_OPTION_URI_QUERY,
                                   coap_opt_length(sbuf), coap_opt_value(sbuf))))
                   goto error;
                 sbuf += coap_opt_size(sbuf);
               }
             }

             if (request_code == COAP_REQUEST_GET && observe) {
               /* Indicate that we want to observe this resource */
               if (!coap_insert_optlist(&optlist_chain,
                                        coap_new_optlist(COAP_OPTION_OBSERVE,
                                                    COAP_OBSERVE_ESTABLISH, NULL)))
                 goto error;
             }

             /* ... Other code / options etc. ... */

             /* Add in all the options (after internal sorting) to the pdu */
             if (!coap_add_optlist_pdu(pdu, &optlist_chain))
               goto error;

             if (data && length) {
               /* Add in the specified data */
               if (!coap_add_data(pdu, length, data))
                 goto error;
             }

             if (coap_send(session, pdu) == COAP_INVALID_TID)
               goto error;
             return 1;

           error:

             if (pdu)
               coap_pdu_delete(pdu);
             return 0;

           }

       Resource Handler Response PDU Update

           #include <coap2/coap.h>

           static void
           hnd_get_time(coap_context_t *context, coap_resource_t *resource,
           coap_session_t *session, coap_pdu_t *request, coap_string_t *token,
           coap_string_t *query, coap_pdu_t *response) {

             unsigned char buf[40];
             size_t len;
             time_t now;

             /* ... Additional analysis code for resource, request pdu etc.  ... */

             /* After analysis, generate a suitable response */

             /* Note that token, if set, is already in the response pdu */

             now = time(NULL);

             if (query != NULL && coap_string_equal(query, coap_make_str_const("secs"))) {
               /* Output secs since Jan 1 1970 */
               len = snprintf((char *)buf, sizeof(buf), "%lu", now);
             }
             else {
               /* Output human-readable time */
               struct tm *tmp;
               tmp = gmtime(&now);
               if (!tmp) {
                 /* If 'now' is not valid */
                 response->code = COAP_RESPONSE_CODE(404);
                 return;
               }
               len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp);
             }
             /*
              * Invoke coap_add_data_blocked_response() to do all the hard work.
              *
              * Define the format - COAP_MEDIATYPE_TEXT_PLAIN - to add in
              * Define how long this response is valid for (secs) - 1 - to add in.
              *
              * OBSERVE Option added internally if needed within the function
              * BLOCK2 Option added internally if output too large
              * ETAG Option added internally
              */
             coap_add_data_blocked_response(resource, session, request, response, token,
                                            COAP_MEDIATYPE_TEXT_PLAIN, 1,
                                            len,
                                            buf);

             /*
              * As resource->code has been updated in coap_add_data_blocked_response(),
              * the response pdu will be transmitted by the underlying library.
              */

           }

SEE ALSO

       coap_observe(3), coap_resource(3)

FURTHER INFORMATION

       See "RFC7252: The Constrained Application Protocol (CoAP)" for further information.

       See https://www.iana.org/assignments/core-parameters/core-parameters.xhtml#option-numbers
       for the current set of defined CoAP Options.

BUGS

       Please report bugs on the mailing list for libcoap:
       libcoap-developers@lists.sourceforge.net

AUTHORS

       The libcoap project <libcoap-developers@lists.sourceforge.net>