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.
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.