samples: net: coap_server: Fix retransmission mechanism
The retransmission handler only increased the retransmission count, w/o sending the actual message again. Additionally, the next retransmission time calculation was broken - it did not take into consideration the time that has already passed since before retransmission, and re-applied the entire timeout value. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
parent
2e4eb781f9
commit
33677ef383
1 changed files with 35 additions and 8 deletions
|
@ -38,6 +38,10 @@ LOG_MODULE_REGISTER(net_coap_server_sample, LOG_LEVEL_DBG);
|
||||||
{ { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } }
|
{ { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ADDRLEN(sock) \
|
||||||
|
(((struct sockaddr *)sock)->sa_family == AF_INET ? \
|
||||||
|
sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
|
||||||
|
|
||||||
#define NUM_OBSERVERS 3
|
#define NUM_OBSERVERS 3
|
||||||
|
|
||||||
#define NUM_PENDINGS 3
|
#define NUM_PENDINGS 3
|
||||||
|
@ -951,9 +955,30 @@ static int send_notification_packet(const struct sockaddr *addr,
|
||||||
const uint8_t *token, uint8_t tkl,
|
const uint8_t *token, uint8_t tkl,
|
||||||
bool is_response);
|
bool is_response);
|
||||||
|
|
||||||
|
static void schedule_next_retransmission(void)
|
||||||
|
{
|
||||||
|
struct coap_pending *pending;
|
||||||
|
int32_t remaining;
|
||||||
|
uint32_t now = k_uptime_get_32();
|
||||||
|
|
||||||
|
/* Get the first pending retansmission to expire after cycling. */
|
||||||
|
pending = coap_pending_next_to_expire(pendings, NUM_PENDINGS);
|
||||||
|
if (!pending) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining = pending->t0 + pending->timeout - now;
|
||||||
|
if (remaining < 0) {
|
||||||
|
remaining = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_work_reschedule(&retransmit_work, K_MSEC(remaining));
|
||||||
|
}
|
||||||
|
|
||||||
static void retransmit_request(struct k_work *work)
|
static void retransmit_request(struct k_work *work)
|
||||||
{
|
{
|
||||||
struct coap_pending *pending;
|
struct coap_pending *pending;
|
||||||
|
int r;
|
||||||
|
|
||||||
pending = coap_pending_next_to_expire(pendings, NUM_PENDINGS);
|
pending = coap_pending_next_to_expire(pendings, NUM_PENDINGS);
|
||||||
if (!pending) {
|
if (!pending) {
|
||||||
|
@ -963,10 +988,17 @@ static void retransmit_request(struct k_work *work)
|
||||||
if (!coap_pending_cycle(pending)) {
|
if (!coap_pending_cycle(pending)) {
|
||||||
k_free(pending->data);
|
k_free(pending->data);
|
||||||
coap_pending_clear(pending);
|
coap_pending_clear(pending);
|
||||||
return;
|
} else {
|
||||||
|
net_hexdump("Retransmit", pending->data, pending->len);
|
||||||
|
|
||||||
|
r = sendto(sock, pending->data, pending->len, 0,
|
||||||
|
&pending->addr, ADDRLEN(&pending->addr));
|
||||||
|
if (r < 0) {
|
||||||
|
LOG_ERR("Failed to send %d", errno);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
k_work_reschedule(&retransmit_work, K_MSEC(pending->timeout));
|
schedule_next_retransmission();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_counter(struct k_work *work)
|
static void update_counter(struct k_work *work)
|
||||||
|
@ -999,12 +1031,7 @@ static int create_pending_request(struct coap_packet *response,
|
||||||
|
|
||||||
coap_pending_cycle(pending);
|
coap_pending_cycle(pending);
|
||||||
|
|
||||||
pending = coap_pending_next_to_expire(pendings, NUM_PENDINGS);
|
schedule_next_retransmission();
|
||||||
if (!pending) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
k_work_reschedule(&retransmit_work, K_MSEC(pending->timeout));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue