---
name: "coap_recovery"
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_recovery"
---

# coap\_recovery(3)

Work with CoAP packet transmissions

## NAME

coap\_recovery, coap\_session\_set\_ack\_random\_factor, coap\_session\_get\_ack\_random\_factor, coap\_session\_set\_ack\_timeout, coap\_session\_get\_ack\_timeout, coap\_session\_set\_default\_leisure, coap\_session\_get\_default\_leisure, coap\_session\_set\_max\_payloads, coap\_session\_get\_max\_payloads, coap\_session\_set\_max\_retransmit, coap\_session\_get\_max\_retransmit, coap\_session\_set\_non\_max\_retransmit, coap\_session\_get\_non\_max\_retransmit, coap\_session\_set\_non\_receive\_timeout, coap\_session\_get\_non\_receive\_timeout, coap\_session\_set\_non\_timeout, coap\_session\_get\_non\_timeout, coap\_session\_set\_nstart, coap\_session\_get\_nstart, coap\_session\_set\_probing\_rate, coap\_session\_get\_probing\_rate, coap\_debug\_set\_packet\_loss - Work with CoAP packet transmissions

## SYNOPSIS

**#include \<coap3/coap.h\>**

**void coap\_session\_set\_ack\_random\_factor(coap\_session\_t \****session***, coap\_fixed\_point\_t** *value***)**;

**coap\_fixed\_point\_t coap\_session\_get\_ack\_random\_factor( const coap\_session\_t \****session***)**;

**void coap\_session\_set\_ack\_timeout(coap\_session\_t \****session***, coap\_fixed\_point\_t** *value***)**;

**coap\_fixed\_point\_t coap\_session\_get\_ack\_timeout( const coap\_session\_t \****session***)**;

**void coap\_session\_set\_default\_leisure(coap\_session\_t \****session***, coap\_fixed\_point\_t** *value***)**;

**coap\_fixed\_point\_t coap\_session\_get\_default\_leisure( const coap\_session\_t \****session***)**;

**void coap\_session\_set\_max\_payloads(coap\_session\_t \****session***, uint16\_t** *value***)**;

**uint16\_t coap\_session\_get\_max\_payloads(const coap\_session\_t \****session***)**;

**void coap\_session\_set\_max\_retransmit(coap\_session\_t \****session***, uint16\_t** *value***)**;

**uint16\_t coap\_session\_get\_max\_retransmit(const coap\_session\_t \****session***)**;

**void coap\_session\_set\_non\_max\_retransmit(coap\_session\_t \****session***, uint16\_t** *value***)**;

**uint16\_t coap\_session\_get\_non\_max\_retransmit(const coap\_session\_t \****session***)**;

**void coap\_session\_set\_non\_receive\_timeout(coap\_session\_t \****session***, coap\_fixed\_point\_t** *value***)**;

**coap\_fixed\_point\_t coap\_session\_get\_non\_receive\_timeout( const coap\_session\_t \****session***)**;

**void coap\_session\_set\_non\_timeout(coap\_session\_t \****session***, coap\_fixed\_point\_t** *value***)**;

**coap\_fixed\_point\_t coap\_session\_get\_non\_timeout( const coap\_session\_t \****session***)**;

**void coap\_session\_set\_nstart(coap\_session\_t \****session***, uint16\_t** *value***)**;

**uint16\_t coap\_session\_get\_nstart(const coap\_session\_t \****session***)**;

**void coap\_session\_set\_probing\_rate(coap\_session\_t \****session***, uint32\_t** *value***)**;

**uint32\_t coap\_session\_get\_probing\_rate(const coap\_session\_t \****session***)**;

**int coap\_debug\_set\_packet\_loss(const char \****loss\_level***)**;

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

There is CoAP Confirmable message transmission recovery as defined in RFC7252, as well CoAP Non-Confirmable split into blocks message transmission recovery support as defined in RFC9177.

For CoAP Confirmable messages, it is possible to define the retry counts, repeat rate etc. for error recovery. Further information can be found in "RFC7272 4.2. Messages Transmitted Reliably", with the default values defined in "RFC7272 4.8. Transmission Parameters".

It is not recommended that the suggested default setting are changed, but there may be some special requirements that need different values and the consequences of changing these values is fully understood.

Some of the parameters or return values are in fixed point format as defined by the coap\_fixed\_point\_t structure as below

```
typedef struct coap_fixed_point_t {
  uint16_t integer_part;    /* Integer part of fixed point variable */
  uint16_t fractional_part; /* Fractional part of fixed point variable
                               1/1000 (3 points) precision */
} coap_fixed_point_t;
```

The CoAP Confirmable message retry rules are (with the default values to compute the time)

```
1st retransmit after 1 * ack_timeout * ack_random factor (3 seconds)
2nd retransmit after 2 * ack_timeout * ack_random factor (6 seconds)
3rd retransmit after 3 * ack_timeout * ack_random factor (12 seconds)
4th retransmit after 4 * ack_timeout * ack_random factor (24 seconds)
5th retransmit after 5 * ack_timeout * ack_random factor (48 seconds)
As max_retransmit (by default) is 4, then the 5th retransmit does not get sent,
but at that point COAP_NACK_TOO_MANY_RETRIES gets raised in the nack_handler
(if defined). Note that the sum of the seconds is 93 matching
"https://rfc-editor.org/rfc/rfc7252#section-4.8.2[RFC7252 4.8.2.
MAX_TRANSMIT_WAIT]".
```

It should be noted that these retries are separate from the DTLS or TLS encrypted session setup retry timeouts. For DTLS, the initial requesting packet will get sent max\_retransmit times before reporting failure. For TLS the initial TCP connection will timeout before reporting failure.

For CoAP Non-Confirmable messages with RFC9177 enabled at both ends of a session, it is possible to define the retry counts etc. for data recovery. Further information can be found in "RFC9177 7.2. Non-confirmable (NON)".

It is also possible to set up packet losses, for both confirmable, and non-confirmable messages. This can be used for stress testing packet transmission recovery as well as application handling of lossy networks.

## FUNCTIONS

The following functions reflect the RFC7252 and RFC9177 uppercase names in lowercase following the coap\_session\_set\_ or coap\_session\_get\_ function prefix.

**Function: coap\_session\_set\_ack\_random\_factor()**

The **coap\_session\_set\_ack\_random\_factor**() function updates the *session* ack random wait factor, used to randomize re-transmissions, with the new *value*. The default value is 1.5 (RFC7252).

**Function: coap\_session\_get\_ack\_random\_factor()**

The **coap\_session\_get\_ack\_random\_factor**() function returns the current *session* ack random wait factor (RFC7252).

**Function: coap\_session\_set\_ack\_timeout()**

The **coap\_session\_set\_ack\_timeout**() function updates the *session* initial ack or response timeout with the new *value*. The default value is 2.0 (RFC7252).

**Function: coap\_session\_get\_ack\_timeout()**

The **coap\_session\_get\_ack\_timeout**() function returns the current *session* initial ack or response timeout (RFC7252).

**Function: coap\_session\_set\_default\_leisure()**

The **coap\_session\_set\_default\_leisure**() function updates the *session* default leisure time with the new *value*. The default value is 5.0 (RFC7252).

**Function: coap\_session\_get\_default\_leisure()**

The **coap\_session\_get\_default\_leisure**() function returns the current *session* default leisure time (RFC7252).

**Function: coap\_session\_set\_max\_payloads()**

The **coap\_session\_set\_max\_payloads**() function updates the *session* maximum payloads count with the new *value*. The default value is 10 (RFC9177).

**NOTE:** Both ends of the session must have the same maximum payloads value to minimize any recovery times.

**Function: coap\_session\_get\_max\_payloads()**

The **coap\_session\_get\_max\_payloads**() function returns the current *session* maximum payloads count (RFC9177).

**Function: coap\_session\_set\_max\_retransmit()**

The **coap\_session\_set\_max\_retransmit**() function updates the *session* maximum retransmit count with the new *value*. The default value is 4 (RFC7252).

**Function: coap\_session\_get\_max\_retransmit()**

The **coap\_session\_get\_max\_retransmit**() function returns the current *session* maximum retransmit count (RFC7252).

**Function: coap\_session\_set\_non\_max\_retransmit()**

The **coap\_session\_set\_non\_max\_retransmit**() function updates the *session* maximum non retransmit count with the new *value*. The default value is 4 (RFC9177).

**Function: coap\_session\_get\_non\_max\_retransmit()**

The **coap\_session\_get\_non\_max\_retransmit**() function returns the current *session* maximum non retransmit count (RFC9177).

**Function: coap\_session\_set\_non\_receive\_timeout()**

The **coap\_session\_set\_non\_receive\_timeout**() function updates the *session* non receive timeout with the new *value*. The default value is 4.0 (RFC9177).

**Function: coap\_session\_get\_non\_receive\_timeout()**

The **coap\_session\_get\_non\_receive\_timeout**() function returns the current *session* non receive timeout (RFC9177).

**Function: coap\_session\_set\_non\_timeout()**

The **coap\_session\_set\_non\_timeout**() function updates the *session* non timeout with the new *value*. The default value is 2.0 (RFC9177).

**Function: coap\_session\_get\_non\_timeout()**

The **coap\_session\_get\_non\_timeout**() function returns the current *session* non timeout (RFC9177).

**Function: coap\_session\_set\_nstart()**

The **coap\_session\_set\_nstart**() function updates the *session* nstart with the new *value*. The default value is 1 (RFC7252).

**Function: coap\_session\_set\_probing\_rate()**

The **coap\_session\_get\_nstart**() function returns the current *session* nstart value (RFC7252).

**Function: coap\_session\_set\_probing\_rate()**

The **coap\_session\_set\_probing\_rate**() function updates the *session* probing rate with the new *value*. The default value is 1 byte per second (RFC7252).

**Function: coap\_session\_get\_probing\_rate()**

The **coap\_session\_get\_probing\_rate**() function returns the current *session* probing rate value (RFC7252).

**Function: coap\_debug\_set\_packet\_loss()**

The **coap\_debug\_set\_packet\_loss**() function is uses to set the packet loss levels as defined in *loss\_level*. *loss\_level* can be set as a percentage from "0%" to "100%". Alternatively, it is possible to specify which packets of a packet sequence are dropped. A definition of "1,5-9,11-20,101" means that packets 1, 5 through 9, 11 through 20 and 101 will get dropped. A maximum of 10 different packet sets is supported. The packet count is reset to 0 when **coap\_debug\_set\_packet\_loss**() is called. To remove any packet losses, set the *loss\_level* to "0%".

## RETURN VALUES

**coap\_session\_get\_ack\_random\_factor**(), **coap\_session\_get\_ack\_timeout**(), **coap\_session\_get\_default\_leisure**(), **coap\_session\_get\_max\_payloads**(), **coap\_session\_get\_max\_retransmit**(), **coap\_session\_get\_non\_max\_retransmit**(), **coap\_session\_get\_non\_receive\_timeout**(), **coap\_session\_get\_non\_timeout**(), **coap\_session\_get\_nstart**() and **coap\_session\_get\_probing\_rate**() return their respective current values.

**coap\_debug\_set\_packet\_loss**() returns 0 if *loss\_level* does not parse correctly, otherwise 1 if successful.

## TESTING

The libcoap RFC7252 recovery/re-transmit logic will only work for confirmable requests or if RFC9177 support is enabled for non-confirmable large body transmissions that need to span multiple packets.

To see what is happening (other than by sniffing the network traffic), the logging level needs to be set to COAP\_LOG\_DEBUG in the client by using **coap\_set\_log\_level**(COAP\_LOG\_DEBUG) and **coap\_dtls\_set\_log\_level**(COAP\_LOG\_DEBUG).

The server can either be stopped, or if packet loss levels are set to 100% by using **coap\_debug\_set\_packet\_loss**("100%") when receiving the client requests.

**NOTE:** If the server end of the connection is returning ICMP unreachable packets after being turned off, you will get a debug message of the form "coap\_network\_read: unreachable", so libcoap will stop doing the retries. If this is the case, then you need to make use of (on the server) **coap\_debug\_set\_packet\_loss**("100%") or put in some packet filtering to drop the packets.

For confirmable transmissions, the client should then restart transmitting the requests based on the ack\_timeout, ack\_random\_factor and max\_retransmit values. The client’s nack\_handler will get called with COAP\_NACK\_TOO\_MANY\_RETRIES when the confirmable request cannot be successfully transmitted.

For non-confirmable block transmissions (RFC9177 enabled), the client should then restart transmitting the missing requests based on the max\_payloads, non\_timeout, non\_receive\_timeout, and non\_max\_retransmit values. The client’s nack\_handler will get called with COAP\_NACK\_TOO\_MANY\_RETRIES when the non-confirmable large body request cannot be successfully transmitted.

## FURTHER INFORMATION

See

"RFC7252: The Constrained Application Protocol (CoAP)"

"RFC9177: Constrained Application Protocol (CoAP) Block-Wise Transfer Options Supporting Robust Transmission"

for further information.

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