Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nanocoap_sock: clean up state management #18047

Merged
merged 1 commit into from
May 18, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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