---
name: "coap_pdu_access"
section: "3"
platform: "linux"
package: "libcoap3t64"
version: "4.3.4-1.1+deb13u3"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/coap_pdu_access"
---

# coap\_pdu\_access(3)

Accessing CoAP PDUs

## 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** 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)](/coap_block/3.md).

## 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(pdu, &pdu_data_length, &pdu_data);
    /* or */
  ret = coap_get_data_large(pdu, &pdu_data_length, &pdu_data,
                            &pdu_data_offset, &pdu_data_total_length);
}
```

## SEE ALSO

[**coap\_block**(3)](/coap_block/3.md) and [**coap\_pdu\_setup**(3)](/coap_pdu_setup/3.md)

## 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 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\>
