Provided by: libcoap3t64_4.3.4-1.1build4_amd64 bug

NAME

       coap_pdu_setup, coap_new_pdu, coap_pdu_init, coap_new_message_id, coap_session_init_token,
       coap_session_new_token, coap_add_token, coap_new_optlist, coap_insert_optlist,
       coap_delete_optlist, coap_encode_var_safe, coap_encode_var_safe8, coap_add_optlist_pdu,
       coap_add_option, coap_add_data, coap_add_data_blocked_response, coap_send,
       coap_split_path, coap_split_query, coap_pdu_set_mid, coap_pdu_set_code, coap_pdu_set_type
       - Setting up CoAP PDUs

SYNOPSIS

       #include <coap3/coap.h>

       coap_pdu_t *coap_new_pdu(coap_pdu_type_t type, coap_pdu_code_t code, coap_session_t
       *session);

       coap_pdu_t *coap_pdu_init(coap_pdu_type_t type, coap_pdu_code_t code, coap_mid_t
       message_id, size_t max_size);

       uint16_t coap_new_message_id(coap_session_t *session);

       void coap_session_init_token(coap_session_t *session, size_t length, const uint8_t
       *token);

       void coap_session_new_token(coap_session_t *session, size_t *length, uint8_t *token);

       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);

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

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

       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(const coap_pdu_t *request, coap_pdu_t *response,
       uint16_t media_type, int maxage, size_t length, const uint8_t *data);

       coap_mid_t coap_send(coap_session_t *session, coap_pdu_t *pdu);

       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);

       void coap_pdu_set_mid(coap_pdu_t *pdu, coap_mid_t mid);

       void coap_pdu_set_code(coap_pdu_t *pdu, coap_pdu_code_t code);

       void coap_pdu_set_type(coap_pdu_t *pdu, coap_pdu_type_t type);

       For specific (D)TLS library support, link with -lcoap-3-notls, -lcoap-3-gnutls,
       -lcoap-3-openssl, -lcoap-3-mbedtls or -lcoap-3-tinydtls. Otherwise, link with -lcoap-3 to
       get the default (D)TLS library support.

DESCRIPTION

       The CoAP PDU is of the form


       --header--|--optional token--|--optional options--|--optional payload--
       The terminology used is taken mainly from "RFC7252 1.2. Terminology".

       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, and the PDU is of type CONFIRMABLE, then the response PDU is transmitted
       as an empty ACK packet. The response pdu is always freed off by the underlying library.

       For handling situations where the data to be transmitted does not fit into a single
       packet, see coap_block(3).

PDU CREATE AND HEADER FUNCTIONS

       Function: coap_new_pdu()

       The coap_new_pdu() function returns a newly created PDU of type coap_pdu_t.

       The 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_EMPTY_CODE                               0.00
           COAP_REQUEST_CODE_GET                         0.01
           COAP_REQUEST_CODE_POST                        0.02
           COAP_REQUEST_CODE_PUT                         0.03
           COAP_REQUEST_CODE_DELETE                      0.04
           COAP_REQUEST_CODE_FETCH                       0.05
           COAP_REQUEST_CODE_PATCH                       0.06
           COAP_REQUEST_CODE_IPATCH                      0.07
           COAP_RESPONSE_CODE_OK                         2.00
           COAP_RESPONSE_CODE_CREATED                    2.01
           COAP_RESPONSE_CODE_DELETED                    2.02
           COAP_RESPONSE_CODE_VALID                      2.03
           COAP_RESPONSE_CODE_CHANGED                    2.04
           COAP_RESPONSE_CODE_CONTENT                    2.05
           COAP_RESPONSE_CODE_CONTINUE                   2.31
           COAP_RESPONSE_CODE_BAD_REQUEST                4.00
           COAP_RESPONSE_CODE_UNAUTHORIZED               4.01
           COAP_RESPONSE_CODE_BAD_OPTION                 4.02
           COAP_RESPONSE_CODE_FORBIDDEN                  4.03
           COAP_RESPONSE_CODE_NOT_FOUND                  4.04
           COAP_RESPONSE_CODE_NOT_ALLOWED                4.05
           COAP_RESPONSE_CODE_NOT_ACCEPTABLE             4.06
           COAP_RESPONSE_CODE_INCOMPLETE                 4.08
           COAP_RESPONSE_CODE_CONFLICT                   4.09
           COAP_RESPONSE_CODE_PRECONDITION_FAILED        4.12
           COAP_RESPONSE_CODE_REQUEST_TOO_LARGE          4.13
           COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT 4.15
           COAP_RESPONSE_CODE_UNPROCESSABLE              4.22
           COAP_RESPONSE_CODE_TOO_MANY_REQUESTS          4.29
           COAP_RESPONSE_CODE_INTERNAL_ERROR             5.00
           COAP_RESPONSE_CODE_NOT_IMPLEMENTED            5.01
           COAP_RESPONSE_CODE_BAD_GATEWAY                5.02
           COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE        5.03
           COAP_RESPONSE_CODE_GATEWAY_TIMEOUT            5.04
           COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED     5.05
           COAP_RESPONSE_CODE_HOP_LIMIT_REACHED          5.08
           COAP_SIGNALING_CODE_CSM                       7.01
           COAP_SIGNALING_CODE_PING                      7.02
           COAP_SIGNALING_CODE_PONG                      7.03
           COAP_SIGNALING_CODE_RELEASE                   7.04
           COAP_SIGNALING_CODE_ABORT                     7.05

       and session is used to set up other default values.

       Function: coap_pdu_init()

       The coap_pdu_init() function does the same work as coap_new_pdu() but gives the additional
       ability to define the default values for message_id and max_size that coap_new_pdu()
       creates.

       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.

       At the CoAP protocol level, requests and responses are matched by message_id which is why
       it needs to be unique. At the application level, for "separate" responses, the initial
       empty ACK response matches the message_id of the request (handled by libcoap) but the
       actual response has the same token as the request and this must be used for the match. For
       "piggybacked" responses the token must still be used as the valid match for request and
       response. and the message_id just happens to match (but unsafe in case the server is
       sending back a "separate" response).

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

       Function: coap_new_message_id()

       The coap_new_message_id() function returns the next message id to use for sending a new
       request message.

       NOTE: For reliable messages RFC8323, this will always return 0.

       Function: coap_pdu_set_mid()

       The coap_pdu_set_mid() function is used to set the message id mid in the PDU pdu.

       Function: coap_pdu_set_code()

       The coap_pdu_set_code() function is used to set the code code in the PDU pdu.

       Function: coap_pdu_set_type()

       The coap_pdu_set_type() function is used to set the type of the PDU pdu.

       NOTE: A PDU does not need to be created by the server application to send back a response.
       The libcoap server logic creates the initial PDU with COAP_EMPTY_CODE, appropriate
       message_id, matching token and potentially some other options before calling the
       appropriate request handler (See coap_register_request_handler(3)).

PDU TOKEN FUNCTIONS

       Function: coap_session_init_token()

       The coap_session_init_token() function is used to initialize the starting token of length
       for the session.

       NOTE: this only takes the first 8 bytes of the token if extended tokens are being used
       (RFC8974).

       Function: coap_session_new_token()

       The coap_session_new_token() function is used to obtain the next available token of length
       for the session. Note that the same token must be used for doing an observe cancellation
       that was used for doing the observe registration. Otherwise tokens should be unique for
       each request/response so that they can be correctly matched.

       NOTE: Only a token of up to 8 bytes is returned.

       Function: coap_add_token()

       The coap_add_token() function adds in the specified token’s data of length length to the
       PDU pdu. The maximum (but impractical due to PDU sizes) length of the token is 65804
       bytes. If anything more than 8, the remote peer needs to support extended tokens for this
       to work. 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 request
       handler as the token has already been added into the skeletal response PDU.

       If a token is not added, then the token in the PDU is zero length, but still a valid token
       which is used for matching. The exception is an empty ACK packet.

       NOTE: The token provided by the client application may not be the same as used internally
       by libcoap - for example when doing data transmission where the body of data is spread
       over multiple payloads (see coap_block(3)). However, when the data transfers complete, the
       application will receive the corrected token in the response PDU.

PDU OPTIONS FUNCTIONS

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

           /*
            * The C, U, and N flags indicate the properties
            * Critical, Unsafe, and NoCacheKey, respectively.
            * If U is set, then N has no meaning as per
            * https://rfc-editor.org/rfc/rfc7252#section-5.10
            * and is set to a -.
            * Separately, R is for the options that can be repeated
            *
            * The least significant byte of the option is set as followed
            * as per https://rfc-editor.org/rfc/rfc7252#section-5.4.6
            *
            *   0   1   2   3   4   5   6   7
            * --+---+---+---+---+---+---+---+
            *           | NoCacheKey| U | C |
            * --+---+---+---+---+---+---+---+
            *
            * https://rfc-editor.org/rfc/rfc8613#section-4 goes on to define E, I and U
            * properties Encrypted and Integrity Protected, Integrity Protected Only and
            * Unprotected respectively.  Integrity Protected Only is not currently used.
            *
            * An Option is tagged with CUNREIU with any of the letters replaced with _ if
            * not set, or - for N if U is set (see above) for aiding understanding of the
            * Option.
            */

           COAP_OPTION_IF_MATCH        1 /* C__RE__, opaque,    0-8 B, RFC7252 */
           COAP_OPTION_URI_HOST        3 /* CU-___U, String,  1-255 B, RFC7252 */
           COAP_OPTION_ETAG            4 /* ___RE__, opaque,    1-8 B, RFC7252 */
           COAP_OPTION_IF_NONE_MATCH   5 /* C___E__, empty,       0 B, RFC7252 */
           COAP_OPTION_OBSERVE         6 /* _U-_E_U, empty/uint,  0 B/0-3 B, RFC7641 */
           COAP_OPTION_URI_PORT        7 /* CU-___U, uint,      0-2 B, RFC7252 */
           COAP_OPTION_LOCATION_PATH   8 /* ___RE__, String,  0-255 B, RFC7252 */
           COAP_OPTION_OSCORE          9 /* C_____U, *,       0-255 B, RFC8613 */
           COAP_OPTION_URI_PATH       11 /* CU-RE__, String,  0-255 B, RFC7252 */
           COAP_OPTION_CONTENT_FORMAT 12 /* ____E__, uint,      0-2 B, RFC7252 */
           /* COAP_OPTION_MAXAGE default 60 seconds if not set */
           COAP_OPTION_MAXAGE         14 /* _U-_E_U, uint,      0-4 B, RFC7252 */
           COAP_OPTION_URI_QUERY      15 /* CU-RE__, String,  1-255 B, RFC7252 */
           COAP_OPTION_HOP_LIMIT      16 /* ______U, uint,        1 B, RFC8768 */
           COAP_OPTION_ACCEPT         17 /* C___E__, uint,      0-2 B, RFC7252 */
           COAP_OPTION_Q_BLOCK1       19 /* CU__E_U, uint,      0-3 B, RFC8177 */
           COAP_OPTION_LOCATION_QUERY 20 /* ___RE__, String,  0-255 B, RFC7252 */
           COAP_OPTION_BLOCK2         23 /* CU-_E_U, uint,      0-3 B, RFC7959 */
           COAP_OPTION_BLOCK1         27 /* CU-_E_U, uint,      0-3 B, RFC7959 */
           COAP_OPTION_SIZE2          28 /* __N_E_U, uint,      0-4 B, RFC7959 */
           COAP_OPTION_Q_BLOCK2       31 /* CU_RE_U, uint,      0-3 B, RFC9177 */
           COAP_OPTION_PROXY_URI      35 /* CU-___U, String, 1-1034 B, RFC7252 */
           COAP_OPTION_PROXY_SCHEME   39 /* CU-___U, String,  1-255 B, RFC7252 */
           COAP_OPTION_SIZE1          60 /* __N_E_U, uint,      0-4 B, RFC7252 */
           COAP_OPTION_ECHO          252 /* _N__E_U, opaque,   0-40 B, RFC9175 */
           COAP_OPTION_NORESPONSE    258 /* _U-_E_U, uint,      0-1 B, RFC7967 */
           COAP_OPTION_RTAG          292 /* ___RE_U, opaque,    0-8 B, RFC9175 */

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

       Function: coap_new_optlist()

       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.

       NOTE: Where possible, the option data needs to be stripped of leading zeros (big endian)
       to reduce the amount of data needed in the PDU, as well as in some cases the maximum data
       size of an option can be exceeded if not stripped and hence be illegal. This is done by
       using coap_encode_var_safe() or coap_encode_var_safe8().

       Function: coap_insert_optlist()

       The coap_insert_optlist() function adds the optlist entry onto the end of the
       optlist_chain. 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.

       Function: coap_delete_optlist()

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

       Function: coap_add_optlist_pdu()

       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.

       Function: coap_add_option()

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

       NOTE: Where possible, the option data needs to be stripped of leading zeros (big endian)
       to reduce the amount of data needed in the PDU, as well as in some cases the maximum data
       size of an option can be exceeded if not stripped and hence be illegal. This is done by
       using coap_encode_var_safe() or coap_encode_var_safe8().

       Function: coap_encode_var_safe()

       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.

       Function: coap_encode_var_safe8()

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

       Function: coap_split_path()

       The coap_split_path() function splits up path of length length and places the result in
       buffer which has a size of buflen with the nul character separating each path component.
       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 return value indicates the
       number of components that individual COAP_OPTION_URI_PATH options need to be created for.

       Function: coap_split_query()

       The coap_split_query() function splits up query of length length and places the result in
       buffer which has a size of buflen with the nul character separating each path component.
       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 return value indicates the
       number of components that individual COAP_OPTION_URI_QUERY options need to be created for.

PDU OPTIONS - LIBCOAP HANDLING

       Most of the options are under the control of the applications, but the following are
       primarily used internally by libcoap.

       COAP_OPTION_BLOCK1 and COAP_OPTION_BLOCK2

       These Block options are used when a large body needs to be split up into multiple
       payloads. Following the introduction of coap_context_set_block_mode(3), libcoap can
       internally handle the setting of these options (see coap_block(3)). Applications can
       continue to include these options to set hint block size values.

       It is recommended that coap_context_set_block_mode(context,
       COAP_BLOCK_USE_LIBCOAP|COAP_BLOCK_SINGLE_BODY) is used to reduce the programming
       requirements for block handling within the applications.

       COAP_OPTION_ECHO

       This option can be set by the server application to indicate that the state of the
       client’s freshness is confirmed. The libcoap client logic will detect the use of the Echo
       option by the server and reflect back the Echo value in the next request without involving
       the client application. The opaque option Echo may be seen by the client application.

       COAP_OPTION_ETAG

       This option is normally set by the server libcoap logic when sending back multiple
       payloads so that the (libcoap logic) client can re-assemble the correct body.

       COAP_OPTION_HOP_LIMIT

       When using proxy logic, the value of the Hop-Limit option is decremented by one for each
       proxy hop. If the count decrements to zero, then a 5.08 (Hop Limit Reached) error code is
       returned to the sender. The initial count is 16, unless the client application sets its
       own limit using the Hop-Limit option.

       COAP_OPTION_RTAG

       This option is set by the libcoap client logic when transmitting multiple bodies with
       multiple payloads so that the (libcoap logic) server can differentiate and re-assemble the
       correct body.

       COAP_OPTION_SIZE1 and COAP_OPTION_SIZE2

       These options are added by the libcoap logic to provide a size (Size1 by libcoap client
       logic, Size2 by libcoap server logic) indication to the recipient of the size of the large
       body that is to be transferred. See coap_block(3).

       COAP_OPTION_OSCORE

       This option is used during OSCORE enabled communications. It should not be set by any
       application, but is used internally. See coap_oscore(3) for further information on how to
       set up OSCORE.

PDU PAYLOAD FUNCTIONS

       Function: coap_add_data()

       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.

       Function: coap_add_data_blocked_response()

       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 / FETCH response. The request and response are the same
       parameters for the registered GET / FETCH 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
       Max-Age 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.

       NOTE: This function has been superseded by coap_add_data_large_response(). See
       coap_block(3).

PDU TRANSMIT FUNCTIONS

       Function: coap_send()

       The coap_send() function is used to initiate the transmission of the pdu associated with
       the session. The caller must not access or delete pdu after calling coap_send() - even if
       there is a return error.

       NOTE: For request handlers, returning from the request handler will cause the response PDU
       to be transmitted as appropriate and there is no need to call coap_send() to do this.

RETURN VALUES

       coap_new_pdu() and coap_pdu_init() return a newly created PDU or NULL if there is a malloc
       or parameter failure.

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

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

       coap_encode_var_safe() returns either the length of bytes encoded (which can be 0 when
       encoding 0) or 0 on failure.

       coap_encode_var_safe8() returns either the length of bytes encoded (which can be 0 when
       encoding 0) or 0 on failure.

       coap_add_option() returns the size of option added, or 0 on failure.

       coap_send() returns the CoAP message ID on success or COAP_INVALID_MID on failure.

       coap_split_path() and coap_split_query() return the number of components found.

       coap_new_message_id() returns the next CoAP message ID to use.

EXAMPLES

       Setup PDU and Transmit

           #include <coap3/coap.h>

           static 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;
             uint8_t buf[1024];
             size_t buflen;
             uint8_t *sbuf = buf;
             int res;
             coap_optlist_t *optlist_chain = NULL;
             /* Remove (void) definition if variable is used */
             (void)context;

             /* 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 unique token for this request for handling unsolicited /
              * delayed responses
              */
             coap_session_new_token(session, &buflen, buf);
             if (!coap_add_token(pdu, buflen, buf)) {
               coap_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_encode_var_safe(buf, sizeof(buf),
                                          COAP_OBSERVE_ESTABLISH), buf)
                                        ))
                 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_MID)
               goto error;
             return 1;

           error:

             if (pdu)
               coap_delete_pdu(pdu);
             return 0;

           }

       Resource Request Handler Response PDU Update

           #include <coap3/coap.h>

           #include <stdio.h>

           static void
           hnd_get_time(coap_resource_t *resource, coap_session_t *session,
           const coap_pdu_t *request, const 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 */

             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 */
                 coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
                 return;
               }
               len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp);
             }
             coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
             /*
              * Invoke coap_add_data_large_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.
              * Etag Option added internally with unique value as param set to 0
              *
              * Observe Option added internally if needed within the function
              * Block2 Option added internally if output too large
              * Size2 Option added internally
              */
             coap_add_data_large_response(resource, session, request, response,
                                          query, COAP_MEDIATYPE_TEXT_PLAIN, 1, 0,
                                          len,
                                          buf, NULL, NULL);

             /*
              * Returning from the request handler will cause the response to be
              * sent off (assuming coap_pdu_set_code() has been called), unless
              * the response is confirmable and the code is COAP_EMPTY_CODE which
              * will cause an empty ACK packet to be returned).
              */

           }

SEE ALSO

       coap_block(3), coap_observe(3), coap_oscore(3), coap_pdu_access(3) and coap_resource(3)

FURTHER INFORMATION

       See

       "RFC7252: The Constrained Application Protocol (CoAP)"

       "RFC7959: Block-Wise Transfers in the Constrained Application Protocol (CoAP)"

       "RFC8613: Object Security for Constrained RESTful Environments (OSCORE)"

       "RFC8974: Extended Tokens and Stateless Clients in 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 or raise an issue on GitHub at
       https://github.com/obgm/libcoap/issues

AUTHORS

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