From 90ca43d5b0ed1d1a844929e4c4fa46a2c4747cb9 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 20 Apr 2022 11:45:39 +0200 Subject: [PATCH] nanocoap_sock: ensure ctx is reset before receiving new frame --- sys/net/application_layer/nanocoap/sock.c | 27 +++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/sys/net/application_layer/nanocoap/sock.c b/sys/net/application_layer/nanocoap/sock.c index b9c59856d911..53cd217653bd 100644 --- a/sys/net/application_layer/nanocoap/sock.c +++ b/sys/net/application_layer/nanocoap/sock.c @@ -47,7 +47,6 @@ typedef struct { bool more; } _block_ctx_t; - static uint16_t _get_id(void) { __attribute__((section(".noinit"))) @@ -93,7 +92,7 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt, ssize_t tmp, res = 0; size_t pdu_len = (pkt->payload - (uint8_t *)pkt->hdr) + pkt->payload_len; uint8_t *buf = (uint8_t*)pkt->hdr; - uint32_t id = coap_get_id(pkt); + unsigned id = coap_get_id(pkt); void *payload, *ctx = NULL; unsigned state = STATE_SEND_REQUEST; @@ -106,9 +105,13 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt, /* check if we expect a reply */ const bool confirmable = coap_get_type(pkt) == COAP_TYPE_CON; + /* try receiving another packet without re-request */ + bool retry_rx = false; + while (1) { switch (state) { case STATE_SEND_REQUEST: + DEBUG("nanocoap: send %u bytes (%u tries left)\n", pdu_len, tries_left); if (--tries_left == 0) { DEBUG("nanocoap: maximum retries reached\n"); return -ETIMEDOUT; @@ -120,16 +123,24 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt, return res; } - if (confirmable || cb) { - state = STATE_AWAIT_RESPONSE; - } else { + /* no response needed and no response handler given */ + if (!confirmable && !cb) { return 0; } + + /* ctx must have been released at this point */ + assert(ctx == NULL); + state = STATE_AWAIT_RESPONSE; /* fall-through */ case STATE_AWAIT_RESPONSE: + DEBUG("nanocoap: waiting for response (timeout: %lu µs)\n", timeout); tmp = sock_udp_recv_buf(sock, &payload, &ctx, timeout, NULL); if (tmp == 0) { /* no more data */ + if (retry_rx) { + retry_rx = false; + continue; + } return res; } res = tmp; @@ -147,10 +158,12 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt, /* parse response */ if (coap_parse(pkt, payload, res) < 0) { DEBUG("nanocoap: error parsing packet\n"); - res = -EBADMSG; + retry_rx = true; + continue; } else if (coap_get_id(pkt) != id) { - res = -EBADMSG; + DEBUG("nanocoap: ID mismatch %u != %u\n", coap_get_id(pkt), id); + retry_rx = true; continue; }