Coap retransmission
include coap_time
function nstart : stream_pos
function exchange_lifetime(I:id) : milliseconds
function probing_rate : stream_pos
function ack_timeout(I:id) : milliseconds
function ack_random_factor : stream_pos
function default_leisure = milliseconds
function max_transmit_span : milliseconds
function max_transmit_wait : milliseconds
function max_latency : milliseconds
function processing_delay : milliseconds
function non_lifetime : milliseconds
relation rtt_enabled
function current_rtt(E:ip.endpoint) : milliseconds
function lastest_rtt(E:ip.endpoint) : milliseconds
function max_rtt : milliseconds
Table 3 lists the derived parameters introduced in this subsection with their default values.
+-------------------+---------------+
| name | default value |
+-------------------+---------------+
| MAX_TRANSMIT_SPAN | 45 s |
| MAX_TRANSMIT_WAIT | 93 s |
| MAX_LATENCY | 100 s |
| PROCESSING_DELAY | 2 s |
| MAX_RTT | 202 s |
| EXCHANGE_LIFETIME | 247 s |
| NON_LIFETIME | 145 s |
+-------------------+---------------+
Table 3: Derived Protocol Parameters
after init {
nstart := 1;
exchange_lifetime (I) := 0;
ack_timeout := 2000;
ack_random_factor := 1.5;
default_leisure := 5000;
max_transmit_span := 45000;
max_transmit_wait := 93000;
Note that this is not
necessarily smaller than MAX_TRANSMIT_WAIT, as MAX_LATENCY is not
intended to describe a situation when the protocol works well, but
the worst-case situation against which the protocol has to guard.
We, also arbitrarily, define MAX_LATENCY to be 100 seconds. Apart
from being reasonably realistic for the bulk of configurations as
well as close to the historic choice for TCP, this value also
allows Message ID lifetime timers to be represented in 8 bits
(when measured in seconds). In these calculations, there is no
assumption that the direction of the transmission is irrelevant
(i.e., that the network is symmetric); there is just the
assumption that the same value can reasonably be used as a maximum
value for both directions. If that is not the case, the following
calculations become only slightly more complex.
max_latency := 100000;
o PROCESSING_DELAY is the time a node takes to turn around a
Confirmable message into an acknowledgement. We assume the node
will attempt to send an ACK before having the sender time out, so
as a conservative assumption we set it equal to ACK_TIMEOUT.
processing_delay := ack_timeout;
o MAX_RTT is the maximum round-trip time, or:
(2 * MAX_LATENCY) + PROCESSING_DELAY
max_rtt := (2 * max_latency) + processing_delay;
o NON_LIFETIME is the time from sending a Non-confirmable message to
the time its Message ID can be safely reused. If multiple
transmission of a NON message is not used, its value is
MAX_LATENCY, or 100 seconds. However, a CoAP sender might send a
NON message multiple times, in particular for multicast
applications. While the period of reuse is not bounded by the
specification, an expectation of reliable detection of duplication
at the receiver is on the timescales of MAX_TRANSMIT_SPAN.
Therefore, for this purpose, it is safer to use the value:
MAX_TRANSMIT_SPAN + MAX_LATENCY
or 145 seconds with the default transmission parameters; however,
an implementation that just wants to use a single timeout value
for retiring Message IDs can safely use the larger value for
EXCHANGE_LIFETIME.
non_lifetime := max_transmit_span + max_latency;rtt_enabled := true;current_rtt(E) := 0;lastest_rtt(E) := 0;}action on_message_received(src:ip.endpoint,dst:ip.endpoint, msg:message, sent_bytes:stream_pos) = {if (rtt_enabled) {current_rtt(src) := time_api.c_timer.now_micros;}}action on_message_sent(src:ip.endpoint,dst:ip.endpoint, msg:message, sent_bytes:stream_pos) = {if (rtt_enabled) {lastest_rtt(src) := time_api.c_timer.now_micros;}}action on_ack_received(src:ip.endpoint,dst:ip.endpoint, msg:message, sent_bytes:stream_pos) = {if (rtt_enabled) {current_rtt(src) := time_api.c_timer.now_micros;}}action on_ack_sent(src:ip.endpoint,dst:ip.endpoint, msg:message, sent_bytes:stream_pos) = {if (rtt_enabled) {lastest_rtt(src) := time_api.c_timer.now_micros;}
In particular, a decrease of ACK_TIMEOUT below 1 second
would violate the guidelines of [RFC5405]. ([RTO-CONSIDER] provides
some additional background.)
require ack_timeout >= 1000;
Configurations MUST NOT decrease ACK_TIMEOUT or increase NSTART without using mechanisms that
ensure congestion control safety, either defined in the configuration
or in future standards documents.
ACK_RANDOM_FACTOR MUST NOT be decreased below 1.0, and it SHOULD have a value that is sufficiently different from 1.0 to provide some protection from synchronization effects.
require ack_random_factor >= 1.0;
ACK_TIMEOUT * ((2 ** MAX_RETRANSMIT) - 1) * ACK_RANDOM_FACTOR
max_transmit_span := ack_timeout * ((2 ** 4) - 1) * ack_random_factor;
ACK_TIMEOUT * ((2 ** (MAX_RETRANSMIT + 1)) - 1) * ACK_RANDOM_FACTOR
max_transmit_wait := ack_timeout * ((2 ** (4 + 1)) - 1) * ack_random_factor;
o EXCHANGE_LIFETIME is the time from starting to send a Confirmable
message to the time when an acknowledgement is no longer expected,
i.e., message-layer information about the message exchange can be
purged. EXCHANGE_LIFETIME includes a MAX_TRANSMIT_SPAN, a
MAX_LATENCY forward, PROCESSING_DELAY, and a MAX_LATENCY for the
way back. Note that there is no need to consider
MAX_TRANSMIT_WAIT if the configuration is chosen such that the
last waiting period (ACK_TIMEOUT * (2 ** MAX_RETRANSMIT) or the
difference between MAX_TRANSMIT_SPAN and MAX_TRANSMIT_WAIT) is
less than MAX_LATENCY -- which is a likely choice, as MAX_LATENCY
is a worst-case value unlikely to be met in the real world. In
this case, EXCHANGE_LIFETIME simplifies to:
MAX_TRANSMIT_SPAN + (2 * MAX_LATENCY) + PROCESSING_DELAY
or 247 seconds with the default transmission parameters.
exchange_lifetime(src) := max_transmit_span + (2 * max_latency) + processing_delay;
}