net: coap: Add initial tx time to coap_pending structure
So far, coap_pending structure kept track only of the timeout interval between two consecutive retransmissions. Calculations inside `coap_pending_next_to_expire` relied only on this value. This approach gives incorrect results though, in case multiple messages are pending for retransmission. For instance, assuming initial retransmission timeout is set to 2 seconds. If some message had been retransmitted already, its timeout would be increased to 4 seconds. Any new message added to the pending list would have a retransmission timeout set to 2 seconds, and will be returned as a first message to expire, no matter how long the initial message was already on the list. To resolve this, add a `t0` field to the coap_pending structure. This field is initialized to the initial transmission time, and is increased on each retransmission by the retransmission timeout. `coap_pending_next_to_expire` uses this value to calculate absolute time, when the next retransmission should take place, and based on this information returns correctly first pending message to expire. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
parent
40ac0a7a7d
commit
df152ab59f
2 changed files with 13 additions and 2 deletions
|
@ -233,7 +233,8 @@ typedef int (*coap_reply_t)(const struct coap_packet *response,
|
||||||
*/
|
*/
|
||||||
struct coap_pending {
|
struct coap_pending {
|
||||||
struct sockaddr addr;
|
struct sockaddr addr;
|
||||||
s32_t timeout;
|
u32_t t0;
|
||||||
|
u32_t timeout;
|
||||||
u16_t id;
|
u16_t id;
|
||||||
u8_t *data;
|
u8_t *data;
|
||||||
u16_t len;
|
u16_t len;
|
||||||
|
|
|
@ -1075,6 +1075,7 @@ int coap_pending_init(struct coap_pending *pending,
|
||||||
|
|
||||||
pending->data = request->data;
|
pending->data = request->data;
|
||||||
pending->len = request->offset;
|
pending->len = request->offset;
|
||||||
|
pending->t0 = k_uptime_get_32();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1168,9 +1169,17 @@ struct coap_pending *coap_pending_next_to_expire(
|
||||||
{
|
{
|
||||||
struct coap_pending *p, *found = NULL;
|
struct coap_pending *p, *found = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
u32_t expiry, min_expiry;
|
||||||
|
|
||||||
for (i = 0, p = pendings; i < len; i++, p++) {
|
for (i = 0, p = pendings; i < len; i++, p++) {
|
||||||
if (p->timeout && (!found || found->timeout < p->timeout)) {
|
if (!p->timeout) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
expiry = p->t0 + p->timeout;
|
||||||
|
|
||||||
|
if (!found || (s32_t)(expiry - min_expiry) < 0) {
|
||||||
|
min_expiry = expiry;
|
||||||
found = p;
|
found = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1205,6 +1214,7 @@ bool coap_pending_cycle(struct coap_pending *pending)
|
||||||
{
|
{
|
||||||
s32_t old = pending->timeout;
|
s32_t old = pending->timeout;
|
||||||
|
|
||||||
|
pending->t0 += pending->timeout;
|
||||||
pending->timeout = next_timeout(pending->timeout);
|
pending->timeout = next_timeout(pending->timeout);
|
||||||
|
|
||||||
return (old != pending->timeout);
|
return (old != pending->timeout);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue