Skip to content

Commit

Permalink
Merge pull request #18047 from benpicco/nanocoap-state_cleanup
Browse files Browse the repository at this point in the history
nanocoap_sock: clean up state management
  • Loading branch information
benpicco authored May 18, 2022
2 parents 5fd88e1 + 7c75852 commit e676893
Showing 1 changed file with 13 additions and 15 deletions.
28 changes: 13 additions & 15 deletions sys/net/application_layer/nanocoap/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@
#include "debug.h"

enum {
STATE_SEND_REQUEST,
STATE_AWAIT_RESPONSE,
STATE_REQUEST_SEND, /**< request was just sent or will be sent again */
STATE_RESPONSE_RCVD, /**< response received but might be invalid */
STATE_RESPONSE_OK, /**< valid response was received */
};

typedef struct {
Expand Down Expand Up @@ -125,7 +126,7 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt,
void *payload, *ctx = NULL;
const uint8_t *token = coap_get_token(pkt);
uint8_t token_len = coap_get_token_len(pkt);
uint8_t state = STATE_SEND_REQUEST;
uint8_t state = STATE_REQUEST_SEND;

/* random timeout, deadline for receive retries */
uint32_t timeout = random_uint32_range(CONFIG_COAP_ACK_TIMEOUT_MS * US_PER_MS,
Expand All @@ -138,9 +139,7 @@ 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;

/* Create the first payload snip from the request buffer */
iolist_t head = {
.iol_next = pkt->snips,
.iol_base = pkt->hdr,
Expand All @@ -149,7 +148,7 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt,

while (1) {
switch (state) {
case STATE_SEND_REQUEST:
case STATE_REQUEST_SEND:
DEBUG("nanocoap: send %u bytes (%u tries left)\n",
(unsigned)iolist_size(&head), tries_left);

Expand All @@ -171,9 +170,9 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt,

/* ctx must have been released at this point */
assert(ctx == NULL);
state = STATE_AWAIT_RESPONSE;
/* fall-through */
case STATE_AWAIT_RESPONSE:
case STATE_RESPONSE_RCVD:
case STATE_RESPONSE_OK:
DEBUG("nanocoap: waiting for response (timeout: %"PRIu32" µs)\n",
_deadline_left_us(deadline));
tmp = sock_udp_recv_buf(sock, &payload, &ctx, _deadline_left_us(deadline), NULL);
Expand All @@ -184,15 +183,14 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt,
* releases the packet.
* This assertion will trigger should the behavior change in the future.
*/
if (retry_rx) {
if (state != STATE_REQUEST_SEND) {
assert(tmp == 0 && ctx == NULL);
}
if (tmp == 0) {
/* no more data */
/* sock_udp_recv_buf() needs to be called in a loop until ctx is NULL again
* to release the buffer */
if (retry_rx) {
retry_rx = false;
if (state == STATE_RESPONSE_RCVD) {
continue;
}
return res;
Expand All @@ -202,7 +200,7 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt,
DEBUG("nanocoap: timeout\n");
timeout *= 2;
deadline = _deadline_from_interval(timeout);
state = STATE_SEND_REQUEST;
state = STATE_REQUEST_SEND;
continue;
}
if (res < 0) {
Expand All @@ -211,17 +209,17 @@ ssize_t nanocoap_sock_request_cb(nanocoap_sock_t *sock, coap_pkt_t *pkt,
}

/* parse response */
state = STATE_RESPONSE_RCVD;
if (coap_parse(pkt, payload, res) < 0) {
DEBUG("nanocoap: error parsing packet\n");
retry_rx = true;
continue;
}
else if (_id_or_token_missmatch(pkt, id, token, token_len)) {
DEBUG("nanocoap: ID mismatch %u != %u\n", coap_get_id(pkt), id);
retry_rx = true;
continue;
}

state = STATE_RESPONSE_OK;
DEBUG("nanocoap: response code=%i\n", coap_get_code(pkt));
switch (coap_get_type(pkt)) {
case COAP_TYPE_RST:
Expand Down

0 comments on commit e676893

Please sign in to comment.