COAP_PDU_ACCESS(3)

NAME
coap_pdu_access, coap_check_option, coap_decode_var_bytes, coap_decode_var_bytes8, coap_get_data, coap_opt_length, coap_opt_value, coap_option_filter_clear, coap_option_filter_get, coap_option_filter_set, coap_option_filter_unset, coap_option_iterator_init, coap_option_next, coap_pdu_get_code, coap_pdu_get_mid, coap_pdu_get_token, coap_pdu_get_type, coap_get_uri_path - Accessing CoAP PDUs

SYNOPSIS

#include <coap3/coap.h>

coap_opt_t *coap_check_option(const coap_pdu_t *pdu, coap_option_num_t number, coap_opt_iterator_t *oi);

unsigned int coap_decode_var_bytes(const uint8_t *buf, size_t length);

uint64_t coap_decode_var_bytes8(const uint8_t *buf, size_t length);

int coap_get_data(const coap_pdu_t *pdu, size_t *length, const uint8_t **_data);

uint32_t coap_opt_length(const coap_opt_t *opt);

const uint8_t *coap_opt_value(const coap_opt_t *opt);

void coap_option_filter_clear(coap_opt_filter_t *filter);

int coap_option_filter_get(coap_opt_filter_t *filter, coap_option_num_t number);

int coap_option_filter_set(coap_opt_filter_t *filter, coap_option_num_t number);

int coap_option_filter_unset(coap_opt_filter_t *filter, coap_option_num_t number);

coap_opt_iterator_t *coap_option_iterator_init(const coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_opt_filter_t *filter);

coap_opt_t *coap_option_next(coap_opt_iterator_t *oi);

coap_pdu_code_t coap_pdu_get_code(const coap_pdu_t *pdu);

coap_mid_t coap_pdu_get_mid(const coap_pdu_t *pdu);

coap_bin_const_t coap_pdu_get_token(const coap_pdu_t *pdu);

coap_pdu_type_t coap_pdu_get_type(const coap_pdu_t *pdu);

coap_string_t *coap_get_uri_path(const coap_pdu_t *pdu);

For specific (D)TLS library support, link with -lcoap-3-notls, -lcoap-3-gnutls, -lcoap-3-openssl, -lcoap-3-mbedtls, -lcoap-3-wolfssl 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 following functions provide access to the information held within different parts of a PDU.

PDU HEADER FUNCTIONS

Function: coap_pdu_get_type()

The coap_pdu_get_type() function returns one of the messages types below from the PDU pdu header.

    COAP_MESSAGE_CON  Type confirmable.
    COAP_MESSAGE_NON  Type non-confirmable.
    COAP_MESSAGE_ACK  Type acknowledge
    COAP_MESSAGE_RST  Type reset.

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

Function: coap_pdu_get_code()

The coap_pdu_get_code() function returns one of the codes below from the PDU pdu header. It is possible that new codes are added in over time.

    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

NOTE: For reliable messages "ttps://rfc-editor.org/rfc/rfc8323[RFC8323], this will always return COAP_EMPTY_CODE.

Function: coap_pdu_get_mid()

The coap_pdu_get_mid() returns the message id from the PDU pdu header.

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

PDU TOKEN FUNCTIONS

Function: coap_pdu_get_token()

The coap_pdu_get_token() returns the token information held in the PDU pdu token which may be zero length.

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_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_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_NORESPONSE    258 /* _U-_E_U, uint,      0-1 B, RFC7967 */

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

Function: coap_check_option()

The coap_check_option() function is used to check whether the specified option number is in the PDU pdu options. The option iterator oi is used as a scratch (does not need to be initialized) internal storage location while iterating through the options looking for the specific number. If the number is repeated in the pdu, only the first occurrence will be returned. If the option is not found, NULL is returned.

Function: coap_option_iterator_init()

The coap_option_iterator_init() function can be used to initialize option iterator oi, applying a filter filter to indicate which options are to be ignored when iterating through the options. The filter can be NULL (or COAP_OPT_ALL) if all of the options are required. To set up the filter otherwise, the following 4 functions are available.

Function: coap_option_filter_clear()

The coap_option_filter_clear() function initializes filter to have no options set.

Function: coap_option_filter_get()

The coap_option_filter_get() function is used to check whether option number is set in filter.

Function: coap_option_filter_set()

The coap_option_filter_set() function is used to set option number in filter.

Function: coap_option_filter_unset()

The coap_option_filter_unset() function is used to remove option number in filter.

Function: coap_option_next()

The coap_option_next() function is then used following coap_option_iterator_init() in a loop to return all the appropriate options until NULL is returned - indicating the end of the available options. See EXAMPLES below for further information.

Function: coap_opt_length()

The coap_opt_length() function returns the length of the option opt (as returned by coap_check_option() or coap_option_next()).

Function: coap_opt_value()

The coap_opt_value() function returns a pointer to the start of the data for the option opt (as returned by coap_check_option() or coap_option_next()).

Function: coap_decode_var_bytes()

The coap_decode_var_bytes() function will decode an option value up to 4 bytes long from buf and length into an unsigned 32bit number.

Function: coap_decode_var_bytes8()

The coap_decode_var_bytes8() function will decode an option value up to 8 bytes long from buf and length into an unsigned 64bit number.

Function: coap_get_uri_path()

The coap_get_uri_path() function will abstract the uri path from the specified pdu options. The returned uri path will need to be freed off when no longer required.

PDU PAYLOAD FUNCTIONS

Function: coap_get_data()

The coap_get_data() function is used abstract from the pdu payload information about the received data by updating length with the length of data available, and data with a pointer to where the data is located.

NOTE: This function has been updated by coap_get_data_large() when large transfers may take place. See coap_block(3).

RETURN VALUES

coap_check_option() and coap_option_next() returns a coap_opt_t* or NULL if not found.

coap_decode_var_bytes() and coap_decode_var_bytes8() return the decoded value.

coap_pdu_get_code(), coap_pdu_get_mid(), coap_pdu_get_type() return the appropriate value.

coap_option_filter_get(), coap_option_filter_set() and coap_option_filter_unset() return 1 on success or 0 on failure.

coap_get_data() returns 1 if data, else 0.

coap_opt_length() returns the option length.

coap_opt_value() returns a pointer to the start of the option value or NULL if error.

coap_option_iterator_init() returns ap pointer to the provided iterator or NULL on error.

coap_pdu_get_token() returns a pointer to the token in the pdu.

coap_get_uri_path() returns an allocated pointer to the uri path in the pdu or NULL on error. This pointer will need to be freed off.

EXAMPLES

Abstract information from PDU

    #include <coap3/coap.h>
    static void
    get_pdu_information(coap_pdu_t *pdu) {
      int ret;
      /* Header variables */
      coap_pdu_type_t pdu_type;
      coap_pdu_code_t pdu_code;
      coap_mid_t pdu_mid;
      /* Token variables */
      coap_bin_const_t pdu_token;
      /* Option variables */
      coap_opt_iterator_t opt_iter;
      coap_opt_t *option;
      coap_opt_filter_t ignore_options;
      /* Data payload variables */
      size_t pdu_data_length;
      const uint8_t *pdu_data;
      size_t pdu_data_offset;
      size_t pdu_data_total_length;
      /* Pull in the header information */
      pdu_type = coap_pdu_get_type(pdu);
      pdu_code = coap_pdu_get_code(pdu);
      pdu_mid = coap_pdu_get_mid(pdu);
      /* Pull in the token information */
      pdu_token = coap_pdu_get_token(pdu);
      /* Pull in the option information */
      /* Specific option check */
      option = coap_check_option(pdu, COAP_OPTION_OBSERVE, &opt_iter);
      if (option) {
        uint32_t value = coap_decode_var_bytes(coap_opt_value(option),
                                               coap_opt_length(option));
        coap_log_info("Option OBSERVE, value %u\n", value);
      }
      /* Iterate through all options */
      coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL);
      while ((option = coap_option_next(&opt_iter))) {
        coap_log_info("A: Option %d, Length %u\n",
                      opt_iter.number, coap_opt_length(option));
      }
      /* Iterate through options, some ignored */
      coap_option_filter_clear(&ignore_options);
      coap_option_filter_set(&ignore_options, COAP_OPTION_OBSERVE);
      coap_option_iterator_init(pdu, &opt_iter, &ignore_options);
      while ((option = coap_option_next(&opt_iter))) {
        coap_log_info("I: Option %d, Length %u\n",
                      opt_iter.number, coap_opt_length(option));
      }
      /* Pull in the payload information */
      ret = coap_get_data_large(pdu, &pdu_data_length, &pdu_data,
                                &pdu_data_offset, &pdu_data_total_length);
    }

SEE ALSO

coap_block(3) and coap_pdu_setup(3)

FURTHER INFORMATION

See

"RFC7252: The Constrained Application Protocol (CoAP)"

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

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 raise an issue on GitHub at https://github.com/obgm/libcoap/issues to report any bugs.

Please raise a Pull Request at https://github.com/obgm/libcoap/pulls for any fixes.

AUTHORS

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