From 5a10ce4890ffa1e8197dd32d8f8d2b8bbb2d4e9c Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Fri, 13 Aug 2021 16:26:48 +0100 Subject: [PATCH] Congestion Control: add in RFC7252 configuration flexibility Create where appropriate default values for the Congestion control base values and update the derived CC values accordingly. Move derived value #define to coap_session_internal.h. Update coap_session_t to hold the new CC values. Update documentation for the new CC functions that update / get the appropriate values. NOTE: PROBING_WAIT is not currently checked in the code. --- examples/coap-client.c | 2 +- include/coap3/coap_session.h | 196 ++++++++++++++------------ include/coap3/coap_session_internal.h | 97 ++++++++++++- libcoap-3.map | 6 + libcoap-3.sym | 6 + man/Makefile.am | 5 + man/coap_recovery.txt.in | 99 +++++++++---- man/examples-code-check.c | 1 + src/coap_session.c | 97 +++++++++---- src/net.c | 5 +- src/resource.c | 2 +- 11 files changed, 364 insertions(+), 152 deletions(-) diff --git a/examples/coap-client.c b/examples/coap-client.c index b417878db8..a57366c017 100644 --- a/examples/coap-client.c +++ b/examples/coap-client.c @@ -1819,7 +1819,7 @@ main(int argc, char **argv) { if (is_mcast && wait_seconds == DEFAULT_WAIT_TIME) /* Allow for other servers to respond within DEFAULT_LEISURE RFC7252 8.2 */ - wait_seconds = COAP_DEFAULT_LEISURE; + wait_seconds = coap_session_get_default_leisure(session).integer_part; wait_ms = wait_seconds * 1000; coap_log(LOG_DEBUG, "timeout is set to %u seconds\n", wait_seconds); diff --git a/include/coap3/coap_session.h b/include/coap3/coap_session.h index 5dc03d4072..51092b04e5 100644 --- a/include/coap3/coap_session.h +++ b/include/coap3/coap_session.h @@ -424,130 +424,77 @@ coap_session_t *coap_session_get_by_peer(const coap_context_t *ctx, #define COAP_DEFAULT_ACK_RANDOM_FACTOR ((coap_fixed_point_t){1,500}) /** - * Number of message retransmissions before message sending is stopped + * Number of message retransmissions before message sending is stopped. * RFC 7252, Section 4.8 Default value of MAX_RETRANSMIT is 4 * * Configurable using coap_session_set_max_retransmit() */ -#define COAP_DEFAULT_MAX_RETRANSMIT 4 +#define COAP_DEFAULT_MAX_RETRANSMIT (4U) /** * The number of simultaneous outstanding interactions that a client * maintains to a given server. * RFC 7252, Section 4.8 Default value of NSTART is 1 + * + * Configurable using coap_session_set_nstart() */ -#define COAP_DEFAULT_NSTART 1 - - /** - * The maximum number of seconds before sending back a response to a - * multicast request. - * RFC 7252, Section 4.8 DEFAULT_LEISURE is 5. - */ -#ifndef COAP_DEFAULT_LEISURE -#define COAP_DEFAULT_LEISURE (5U) -#endif /* COAP_DEFAULT_LEISURE */ +#define COAP_DEFAULT_NSTART (1U) /** - * The MAX_TRANSMIT_SPAN definition for the session (s). + * The number of seconds to use as bounds for multicast traffic + * RFC 7252, Section 4.8 Default value of DEFAULT_LEISURE is 5.0 * - * RFC 7252, Section 4.8.2 Calculation of MAX_TRAMSMIT_SPAN - * ACK_TIMEOUT * ((2 ** (MAX_RETRANSMIT)) - 1) * ACK_RANDOM_FACTOR + * Configurable using coap_session_set_default_leisure() */ -#define COAP_MAX_TRANSMIT_SPAN(s) \ - ((s->ack_timeout.integer_part * 1000 + s->ack_timeout.fractional_part) * \ - ((1 << (s->max_retransmit)) -1) * \ - (s->ack_random_factor.integer_part * 1000 + \ - s->ack_random_factor.fractional_part) \ - / 1000000) +#define COAP_DEFAULT_DEFAULT_LEISURE ((coap_fixed_point_t){5,0}) /** - * The MAX_TRANSMIT_WAIT definition for the session (s). + * The number of bytes/second allowed when there is no response + * RFC 7252, Section 4.8 Default value of PROBING_RATE is 1 * - * RFC 7252, Section 4.8.2 Calculation of MAX_TRAMSMIT_WAIT - * ACK_TIMEOUT * ((2 ** (MAX_RETRANSMIT + 1)) - 1) * ACK_RANDOM_FACTOR + * Configurable using coap_session_set_probing_rate() */ -#define COAP_MAX_TRANSMIT_WAIT(s) \ - ((s->ack_timeout.integer_part * 1000 + s->ack_timeout.fractional_part) * \ - ((1 << (s->max_retransmit + 1)) -1) * \ - (s->ack_random_factor.integer_part * 1000 + \ - s->ack_random_factor.fractional_part) \ - / 1000000) +#define COAP_DEFAULT_PROBING_RATE (1U) /** * The MAX_LATENCY definition. * RFC 7252, Section 4.8.2 MAX_LATENCY is 100. */ -#define COAP_MAX_LATENCY 100 - - /** - * The PROCESSING_DELAY definition for the session (s). - * - * RFC 7252, Section 4.8.2 Calculation of PROCESSING_DELAY - * PROCESSING_DELAY set to ACK_TIMEOUT - */ -#define COAP_PROCESSING_DELAY(s) \ - ((s->ack_timeout.integer_part * 1000 + s->ack_timeout.fractional_part + 500) \ - / 1000) - - /** - * The MAX_RTT definition for the session (s). - * - * RFC 7252, Section 4.8.2 Calculation of MAX_RTT - * (2 * MAX_LATENCY) + PROCESSING_DELAY - */ -#define COAP_MAX_RTT(s) \ - ((2 * COAP_MAX_LATENCY) + COAP_PROCESSING_DELAY(s)) - - /** - * The EXCHANGE_LIFETIME definition for the session (s). - * - * RFC 7252, Section 4.8.2 Calculation of EXCHANGE_LIFETIME - * MAX_TRANSMIT_SPAN + (2 * MAX_LATENCY) + PROCESSING_DELAY - */ -#define COAP_EXCHANGE_LIFETIME(s) \ - (COAP_MAX_TRANSMIT_SPAN(s) + (2 * COAP_MAX_LATENCY) + COAP_PROCESSING_DELAY(s)) - - /** - * The NON_LIFETIME definition for the session (s). - * - * RFC 7252, Section 4.8.2 Calculation of NON_LIFETIME - * MAX_TRANSMIT_SPAN + MAX_LATENCY - */ -#define COAP_NON_LIFETIME(s) \ - (COAP_MAX_TRANSMIT_SPAN(s) + COAP_MAX_LATENCY) - - /** @} */ +#define COAP_DEFAULT_MAX_LATENCY (100U) /** -* Set the CoAP maximum retransmit count before failure +* Set the CoAP initial ack response timeout before the next re-transmit * -* Number of message retransmissions before message sending is stopped +* Number of seconds when to expect an ACK or a response to an +* outstanding CON message. +* RFC7252 ACK_TIMEOUT * * @param session The CoAP session. -* @param value The value to set to. The default is 4 and should not normally +* @param value The value to set to. The default is 2.0 and should not normally * get changed. */ -void coap_session_set_max_retransmit(coap_session_t *session, - unsigned int value); +void coap_session_set_ack_timeout(coap_session_t *session, + coap_fixed_point_t value); /** -* Set the CoAP initial ack response timeout before the next re-transmit +* Get the CoAP initial ack response timeout before the next re-transmit * * Number of seconds when to expect an ACK or a response to an * outstanding CON message. +* RFC7252 ACK_TIMEOUT * * @param session The CoAP session. -* @param value The value to set to. The default is 2 and should not normally -* get changed. +* +* @return Current ack response timeout value */ -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); /** * Set the CoAP ack randomize factor * * A factor that is used to randomize the wait time before a message * is retransmitted to prevent synchronization effects. +* RFC7252 ACK_RANDOM_FACTOR * * @param session The CoAP session. * @param value The value to set to. The default is 1.5 and should not normally @@ -556,42 +503,109 @@ void coap_session_set_ack_timeout(coap_session_t *session, void coap_session_set_ack_random_factor(coap_session_t *session, coap_fixed_point_t value); +/** +* Get the CoAP ack randomize factor +* +* A factor that is used to randomize the wait time before a message +* is retransmitted to prevent synchronization effects. +* RFC7252 ACK_RANDOM_FACTOR +* +* @param session The CoAP session. +* +* @return Current ack randomize value +*/ +coap_fixed_point_t coap_session_get_ack_random_factor( + const coap_session_t *session); + +/** +* Set the CoAP maximum retransmit count before failure +* +* Number of message retransmissions before message sending is stopped +* RFC7252 MAX_RETRANSMIT +* +* @param session The CoAP session. +* @param value The value to set to. The default is 4 and should not normally +* get changed. +*/ +void coap_session_set_max_retransmit(coap_session_t *session, + uint16_t value); + /** * Get the CoAP maximum retransmit before failure * * Number of message retransmissions before message sending is stopped +* RFC7252 MAX_RETRANSMIT * * @param session The CoAP session. * * @return Current maximum retransmit value */ -unsigned int coap_session_get_max_retransmit(const coap_session_t *session); +uint16_t coap_session_get_max_retransmit(const coap_session_t *session); /** -* Get the CoAP initial ack response timeout before the next re-transmit +* Set the CoAP maximum concurrent transmission count of Confirmable messages +* RFC7252 NSTART * -* Number of seconds when to expect an ACK or a response to an -* outstanding CON message. +* @param session The CoAP session. +* @param value The value to set to. The default is 1 and should not normally +* get changed. +*/ +void coap_session_set_nstart(coap_session_t *session, + uint16_t value); + +/** +* Get the CoAP maximum concurrent transmission count of Confirmable messages +* RFC7252 NSTART * * @param session The CoAP session. * -* @return Current ack response timeout value +* @return Current nstart value */ -coap_fixed_point_t coap_session_get_ack_timeout(const coap_session_t *session); +uint16_t coap_session_get_nstart(const coap_session_t *session); /** -* Get the CoAP ack randomize factor +* Set the CoAP default leisure time (for multicast) +* RFC7252 DEFAULT_LEISURE * -* A factor that is used to randomize the wait time before a message -* is retransmitted to prevent synchronization effects. +* @param session The CoAP session. +* @param value The value to set to. The default is 5.0 and should not normally +* get changed. +*/ +void coap_session_set_default_leisure(coap_session_t *session, + coap_fixed_point_t value); + +/** +* Get the CoAP default leisure time +* RFC7252 DEFAULT_LEISURE * * @param session The CoAP session. * -* @return Current ack randomize value +* @return Current default_leisure value */ -coap_fixed_point_t coap_session_get_ack_random_factor( +coap_fixed_point_t coap_session_get_default_leisure( const coap_session_t *session); +/** +* Set the CoAP probing rate when there is no response +* RFC7252 PROBING_RATE +* +* @param session The CoAP session. +* @param value The value to set to. The default is 1 and should not normally +* get changed. +*/ +void coap_session_set_probing_rate(coap_session_t *session, uint32_t value); + +/** +* Get the CoAP probing rate when there is no response +* RFC7252 PROBING_RATE +* +* @param session The CoAP session. +* +* @return Current probing_rate value +*/ +uint32_t coap_session_get_probing_rate(const coap_session_t *session); + + /** @} */ /** * Send a ping message for the session. * @param session The CoAP session. diff --git a/include/coap3/coap_session_internal.h b/include/coap3/coap_session_internal.h index 7770c7f6d5..d25fbe8814 100644 --- a/include/coap3/coap_session_internal.h +++ b/include/coap3/coap_session_internal.h @@ -124,12 +124,18 @@ struct coap_session_t { Value maintained internally */ void *app; /**< application-specific data */ - unsigned int max_retransmit; /**< maximum re-transmit count (default - 4) */ - coap_fixed_point_t ack_timeout; /**< timeout waiting for ack (default 2 - secs) */ + coap_fixed_point_t ack_timeout; /**< timeout waiting for ack + (default 2.0 secs) */ coap_fixed_point_t ack_random_factor; /**< ack random factor backoff (default 1.5) */ + uint16_t max_retransmit; /**< maximum re-transmit count + (default 4) */ + uint16_t nstart; /**< maximum concurrent confirmable xmits + (default 1) */ + coap_fixed_point_t default_leisure; /**< Mcast leisure time + (default 5.0 secs) */ + uint32_t probing_rate; /**< Max transfer wait when remote is not + respoding (default 1 byte/sec) */ unsigned int dtls_timeout_count; /**< dtls setup retry counter */ int dtls_event; /**< Tracking any (D)TLS events on this sesison */ @@ -314,6 +320,89 @@ coap_session_t *coap_session_new_dtls_session(coap_session_t *session, void coap_session_free(coap_session_t *session); void coap_session_mfree(coap_session_t *session); +#define COAP_SESSION_REF(s) ((s)->ref + +/* RFC7252 */ +#define COAP_ACK_TIMEOUT(s) ((s)->ack_timeout) +#define COAP_ACK_RANDOM_FACTOR(s) ((s)->ack_random_factor) +#define COAP_MAX_RETRANSMIT(s) ((s)->max_retransmit) +#define COAP_NSTART(s) ((s)->nstart) +#define COAP_DEFAULT_LEISURE(s) ((s)->default_leisure) +#define COAP_PROBING_RATE(s) ((s)->probing_rate) + + /** + * The DEFAULT_LEISURE definition for the session (s). + * + * RFC 7252, Section 4.8 + * Initial value 5.0 seconds + */ +#define COAP_DEFAULT_LEISURE_TICKS(s) \ + (COAP_DEFAULT_LEISURE(s).integer_part * COAP_TICKS_PER_SECOND + \ + COAP_DEFAULT_LEISURE(s).fractional_part * COAP_TICKS_PER_SECOND / 1000) + /** + * The MAX_TRANSMIT_SPAN definition for the session (s). + * + * RFC 7252, Section 4.8.2 Calculation of MAX_TRAMSMIT_SPAN + * ACK_TIMEOUT * ((2 ** (MAX_RETRANSMIT)) - 1) * ACK_RANDOM_FACTOR + */ +#define COAP_MAX_TRANSMIT_SPAN(s) \ + (((s)->ack_timeout.integer_part * 1000 + (s)->ack_timeout.fractional_part) * \ + ((1 << ((s)->max_retransmit)) -1) * \ + ((s)->ack_random_factor.integer_part * 1000 + \ + (s)->ack_random_factor.fractional_part) \ + / 1000000) + + /** + * The MAX_TRANSMIT_WAIT definition for the session (s). + * + * RFC 7252, Section 4.8.2 Calculation of MAX_TRAMSMIT_WAIT + * ACK_TIMEOUT * ((2 ** (MAX_RETRANSMIT + 1)) - 1) * ACK_RANDOM_FACTOR + */ +#define COAP_MAX_TRANSMIT_WAIT(s) \ + (((s)->ack_timeout.integer_part * 1000 + (s)->ack_timeout.fractional_part) * \ + ((1 << ((s)->max_retransmit + 1)) -1) * \ + ((s)->ack_random_factor.integer_part * 1000 + \ + (s)->ack_random_factor.fractional_part) \ + / 1000000) + + /** + * The PROCESSING_DELAY definition for the session (s). + * + * RFC 7252, Section 4.8.2 Calculation of PROCESSING_DELAY + * PROCESSING_DELAY set to ACK_TIMEOUT + */ +#define COAP_PROCESSING_DELAY(s) \ + (((s)->ack_timeout.integer_part * 1000 + (s)->ack_timeout.fractional_part + \ + 500) / 1000) + + /** + * The MAX_RTT definition for the session (s). + * + * RFC 7252, Section 4.8.2 Calculation of MAX_RTT + * (2 * MAX_LATENCY) + PROCESSING_DELAY + */ +#define COAP_MAX_RTT(s) \ + ((2 * COAP_DEFAULT_MAX_LATENCY) + COAP_PROCESSING_DELAY(s)) + + /** + * The EXCHANGE_LIFETIME definition for the session (s). + * + * RFC 7252, Section 4.8.2 Calculation of EXCHANGE_LIFETIME + * MAX_TRANSMIT_SPAN + (2 * MAX_LATENCY) + PROCESSING_DELAY + */ +#define COAP_EXCHANGE_LIFETIME(s) \ + (COAP_MAX_TRANSMIT_SPAN(s) + (2 * COAP_DEFAULT_MAX_LATENCY) + \ + COAP_PROCESSING_DELAY(s)) + + /** + * The NON_LIFETIME definition for the session (s). + * + * RFC 7252, Section 4.8.2 Calculation of NON_LIFETIME + * MAX_TRANSMIT_SPAN + MAX_LATENCY + */ +#define COAP_NON_LIFETIME(s) \ + (COAP_MAX_TRANSMIT_SPAN(s) + COAP_DEFAULT_MAX_LATENCY) + /** @} */ #define SESSIONS_ADD(e, obj) \ diff --git a/libcoap-3.map b/libcoap-3.map index 91b0659843..ff92dda387 100644 --- a/libcoap-3.map +++ b/libcoap-3.map @@ -191,8 +191,11 @@ global: coap_session_get_app_data; coap_session_get_by_peer; coap_session_get_context; + coap_session_get_default_leisure; coap_session_get_ifindex; coap_session_get_max_retransmit; + coap_session_get_nstart; + coap_session_get_probing_rate; coap_session_get_proto; coap_session_get_psk_hint; coap_session_get_psk_identity; @@ -209,8 +212,11 @@ global: coap_session_set_ack_random_factor; coap_session_set_ack_timeout; coap_session_set_app_data; + coap_session_set_default_leisure; coap_session_set_max_retransmit; coap_session_set_mtu; + coap_session_set_nstart; + coap_session_set_probing_rate; coap_session_set_type_client; coap_session_str; coap_set_app_data; diff --git a/libcoap-3.sym b/libcoap-3.sym index cfbb18d109..0a9aad5751 100644 --- a/libcoap-3.sym +++ b/libcoap-3.sym @@ -189,8 +189,11 @@ coap_session_get_addr_remote coap_session_get_app_data coap_session_get_by_peer coap_session_get_context +coap_session_get_default_leisure coap_session_get_ifindex coap_session_get_max_retransmit +coap_session_get_nstart +coap_session_get_probing_rate coap_session_get_proto coap_session_get_psk_hint coap_session_get_psk_identity @@ -207,8 +210,11 @@ coap_session_send_ping coap_session_set_ack_random_factor coap_session_set_ack_timeout coap_session_set_app_data +coap_session_set_default_leisure coap_session_set_max_retransmit coap_session_set_mtu +coap_session_set_nstart +coap_session_set_probing_rate coap_session_set_type_client coap_session_str coap_set_app_data diff --git a/man/Makefile.am b/man/Makefile.am index 12fb5b40c2..853178b80f 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -117,6 +117,11 @@ install-man: install-man3 install-man5 install-man7 @echo ".so man3/coap_pdu_setup.3" > coap_pdu_set_mid.3 @echo ".so man3/coap_pdu_setup.3" > coap_pdu_set_code.3 @echo ".so man3/coap_pdu_setup.3" > coap_pdu_set_type.3 + @echo ".so man3/coap_recovery.3" > coap_session_set_nstart.3 + @echo ".so man3/coap_recovery.3" > coap_session_get_nstart.3 + @echo ".so man3/coap_recovery.3" > coap_session_set_probing_wait.3 + @echo ".so man3/coap_recovery.3" > coap_session_get_probing_wait.3 + @echo ".so man3/coap_recovery.3" > coap_debug_set_packet_loss.3 @echo ".so man3/coap_resource.3" > coap_resource_get_userdata.3 @echo ".so man3/coap_resource.3" > coap_resource_release_userdata_handler.3 @echo ".so man3/coap_resource.3" > coap_resource_get_uri_path.3 diff --git a/man/coap_recovery.txt.in b/man/coap_recovery.txt.in index 74c07851bb..9548b7094a 100644 --- a/man/coap_recovery.txt.in +++ b/man/coap_recovery.txt.in @@ -11,12 +11,18 @@ coap_recovery(3) NAME ---- coap_recovery, -coap_session_set_max_retransmit, -coap_session_set_ack_timeout, coap_session_set_ack_random_factor, -coap_session_get_max_retransmit, -coap_session_get_ack_timeout, 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_retransmit, +coap_session_get_max_retransmit, +coap_session_set_nstart, +coap_session_get_nstart, +coap_session_set_probing_wait, +coap_session_get_probing_wait, coap_debug_set_packet_loss - Work with CoAP packet transmissions @@ -24,23 +30,38 @@ SYNOPSIS -------- *#include * -*void coap_session_set_max_retransmit(coap_session_t *_session_, -unsigned int _value_)*; - -*void coap_session_set_ack_timeout(coap_session_t *_session_, -coap_fixed_point_t _value_)*; - *void coap_session_set_ack_random_factor(coap_session_t *_session_, coap_fixed_point_t _value_)*; -*unsigned int coap_session_get_max_retransmit(const coap_session_t *_session_)*; +*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_)*; -*coap_fixed_point_t coap_session_get_ack_random_factor( +*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_retransmit(coap_session_t *_session_, +uint16_t _value_)*; + +*uint16_t coap_session_get_max_retransmit(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 @@ -53,14 +74,13 @@ DESCRIPTION ----------- 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". +"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. -Changing the default values for multicast packets is not supported. - Some of the parameters or return values are in fixed point format as defined by the coap_fixed_point_t structure as below ---- @@ -93,24 +113,45 @@ 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. -The *coap_session_set_max_retransmit*() function updates the _session_ maximum -retransmit count with the new _value_. The default value is 4. - -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. +The following functions reflect the RFC7252 uppercase names in lowercase +following the coap_session[sg]_ function prefix. 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. -The *coap_session_get_max_retransmit*() function returns the current _session_ -maximum retransmit count. +The *coap_session_get_ack_random_factor*() function returns the current +_session_ ack random wait factor. + +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. The *coap_session_get_ack_timeout*() function returns the current _session_ initial ack or response timeout. -The *coap_session_get_ack_random_factor*() function returns the current -_session_ ack random wait factor. +The *coap_session_set_default_leisure*() function updates the _session_ +default leisure time with the new _value_. The initial default value is 5.0. + +The *coap_session_get_default_leisure*() function returns the current _session_ +default leisure time. + +The *coap_session_set_max_retransmit*() function updates the _session_ maximum +retransmit count with the new _value_. The default value is 4. + +The *coap_session_get_max_retransmit*() function returns the current _session_ +maximum retransmit count. + +The *coap_session_set_nstart*() function updates the _session_ nstart +with the new _value_. The default value is 1. + +The *coap_session_get_nstart*() function returns the current _session_ +nstart value. + +The *coap_session_set_probing_rate*() function updates the _session_ probing +rate with the new _value_. The default value is 1 byte per second. + +The *coap_session_get_probing_rate*() function returns the current _session_ +probing rate value. 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 @@ -124,8 +165,10 @@ To remove any packet losses, set the _loss_level_ to "0%". RETURN VALUES ------------- -*coap_session_get_max_retransmit*(), *coap_session_get_ack_timeout*() and -*coap_session_get_ack_random_factor*() return their respective current values. +*coap_session_get_ack_random_factor*(), *coap_session_get_ack_timeout*(), +*coap_session_get_default_leisure*(), *coap_session_get_max_retransmit*(), +*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. @@ -144,8 +187,8 @@ The client needs to be sending confirmable requests during the test. 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 +*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 diff --git a/man/examples-code-check.c b/man/examples-code-check.c index 6fc21748a5..6a55d58905 100644 --- a/man/examples-code-check.c +++ b/man/examples-code-check.c @@ -80,6 +80,7 @@ const char *number_list[] = { "coap_session_state_t ", "coap_session_type_t ", "int ", + "uint16_t ", "uint32_t ", "uint64_t ", "unsigned int ", diff --git a/src/coap_session.c b/src/coap_session.c index a500cdfea8..3f93317871 100644 --- a/src/coap_session.c +++ b/src/coap_session.c @@ -27,50 +27,94 @@ #include void -coap_session_set_max_retransmit (coap_session_t *session, unsigned int value) { - if (value > 0) - session->max_retransmit = value; - coap_log(LOG_DEBUG, "***%s: session max_retransmit set to %d\n", - coap_session_str(session), session->max_retransmit); - return; -} - -void -coap_session_set_ack_timeout (coap_session_t *session, coap_fixed_point_t value) { - if (value.integer_part > 0 && value.fractional_part < 1000) +coap_session_set_ack_timeout(coap_session_t *session, coap_fixed_point_t value) { + if (value.integer_part > 0 && value.fractional_part < 1000) { session->ack_timeout = value; - coap_log(LOG_DEBUG, "***%s: session ack_timeout set to %d.%03d\n", + coap_log(LOG_DEBUG, "***%s: session ack_timeout set to %u.%03u\n", coap_session_str(session), session->ack_timeout.integer_part, session->ack_timeout.fractional_part); - return; + } } void -coap_session_set_ack_random_factor (coap_session_t *session, - coap_fixed_point_t value) { - if (value.integer_part > 0 && value.fractional_part < 1000) +coap_session_set_ack_random_factor(coap_session_t *session, + coap_fixed_point_t value) { + if (value.integer_part > 0 && value.fractional_part < 1000) { session->ack_random_factor = value; - coap_log(LOG_DEBUG, "***%s: session ack_random_factor set to %d.%03d\n", + coap_log(LOG_DEBUG, "***%s: session ack_random_factor set to %u.%03u\n", coap_session_str(session), session->ack_random_factor.integer_part, session->ack_random_factor.fractional_part); - return; + } } -unsigned int -coap_session_get_max_retransmit (const coap_session_t *session) { - return session->max_retransmit; +void +coap_session_set_max_retransmit(coap_session_t *session, uint16_t value) { + if (value > 0) { + session->max_retransmit = value; + coap_log(LOG_DEBUG, "***%s: session max_retransmit set to %u\n", + coap_session_str(session), session->max_retransmit); + } +} + +void +coap_session_set_nstart(coap_session_t *session, uint16_t value) { + if (value > 0) { + session->nstart = value; + coap_log(LOG_DEBUG, "***%s: session nstart set to %u\n", + coap_session_str(session), session->nstart); + } +} + +void +coap_session_set_default_leisure(coap_session_t *session, + coap_fixed_point_t value) { + if (value.integer_part > 0 && value.fractional_part < 1000) { + session->default_leisure = value; + coap_log(LOG_DEBUG, "***%s: session default_leisure set to %u.%03u\n", + coap_session_str(session), session->default_leisure.integer_part, + session->default_leisure.fractional_part); + } +} + +void +coap_session_set_probing_rate(coap_session_t *session, uint32_t value) { + if (value > 0) { + session->probing_rate = value; + coap_log(LOG_DEBUG, "***%s: session probing_rate set to %u\n", + coap_session_str(session), session->probing_rate); + } } coap_fixed_point_t -coap_session_get_ack_timeout (const coap_session_t *session) { +coap_session_get_ack_timeout(const coap_session_t *session) { return session->ack_timeout; } coap_fixed_point_t -coap_session_get_ack_random_factor (const coap_session_t *session) { +coap_session_get_ack_random_factor(const coap_session_t *session) { return session->ack_random_factor; } +uint16_t +coap_session_get_max_retransmit(const coap_session_t *session) { + return session->max_retransmit; +} + +uint16_t +coap_session_get_nstart(const coap_session_t *session) { + return session->nstart; +} + +coap_fixed_point_t +coap_session_get_default_leisure(const coap_session_t *session) { + return session->default_leisure; +} + +uint32_t +coap_session_get_probing_rate(const coap_session_t *session) { + return session->probing_rate; +} + coap_session_t * coap_session_reference(coap_session_t *session) { ++session->ref; @@ -156,9 +200,12 @@ coap_make_session(coap_proto_t proto, coap_session_type_t type, coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n"); } } - session->max_retransmit = COAP_DEFAULT_MAX_RETRANSMIT; session->ack_timeout = COAP_DEFAULT_ACK_TIMEOUT; session->ack_random_factor = COAP_DEFAULT_ACK_RANDOM_FACTOR; + session->max_retransmit = COAP_DEFAULT_MAX_RETRANSMIT; + session->nstart = COAP_DEFAULT_NSTART; + session->default_leisure = COAP_DEFAULT_DEFAULT_LEISURE; + session->probing_rate = COAP_DEFAULT_PROBING_RATE; session->dtls_event = -1; session->last_ping_mid = COAP_INVALID_MID; @@ -498,7 +545,7 @@ void coap_session_connected(coap_session_t *session) { ssize_t bytes_written; coap_queue_t *q = session->delayqueue; if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) { - if (session->con_active >= COAP_DEFAULT_NSTART) + if (session->con_active >= COAP_NSTART(session)) break; session->con_active++; } diff --git a/src/net.c b/src/net.c index a39c1f9c81..c52bec3588 100644 --- a/src/net.c +++ b/src/net.c @@ -888,7 +888,8 @@ coap_send_pdu(coap_session_t *session, coap_pdu_t *pdu, coap_queue_t *node) { } if (session->state != COAP_SESSION_STATE_ESTABLISHED || - (pdu->type == COAP_MESSAGE_CON && session->con_active >= COAP_DEFAULT_NSTART)) { + (pdu->type == COAP_MESSAGE_CON && + session->con_active >= COAP_NSTART(session))) { return coap_session_delay_pdu(session, pdu, node); } @@ -2563,7 +2564,7 @@ handle_request(coap_context_t *context, coap_session_t *session, coap_pdu_t *pdu /* Need to delay sending mcast request to application layer, so response is not immediate. */ coap_prng(&r, sizeof(r)); - delay = (COAP_DEFAULT_LEISURE * COAP_TICKS_PER_SECOND * r) / 256; + delay = (COAP_DEFAULT_LEISURE_TICKS(session) * r) / 256; /* Register request to be internally re-transmitted after delay */ if ((async = coap_register_async(session, pdu, delay))) { /* Need to restore MID so delayed response can be matched up */ diff --git a/src/resource.c b/src/resource.c index 03f13ba3de..7289102a3b 100644 --- a/src/resource.c +++ b/src/resource.c @@ -903,7 +903,7 @@ coap_notify_observers(coap_context_t *context, coap_resource_t *r, context->observe_pending = 1; continue; } - if (obs->session->con_active >= COAP_DEFAULT_NSTART && + if (obs->session->con_active >= COAP_NSTART(obs->session) && ((r->flags & COAP_RESOURCE_FLAGS_NOTIFY_CON) || (obs->non_cnt >= COAP_OBS_MAX_NON))) { r->partiallydirty = 1;