net/gcoap: Protect message ID state with atomic updates.

Also changed semantics for storage of message ID, from last ID to next ID.
This change provides idiomatic use of the return value of the atomic
function, without other side effects on gcoap.
master
Ken Bannister 6 years ago
parent ed9899ad57
commit 24b21dbfbc

@ -209,6 +209,8 @@
#ifndef NET_GCOAP_H
#define NET_GCOAP_H
#include <stdint.h>
#include <stdatomic.h>
#include "net/sock/udp.h"
#include "nanocoap.h"
#include "xtimer.h"
@ -442,7 +444,7 @@ typedef struct {
/**< Storage for open requests; if first
byte of an entry is zero, the entry
is available */
uint16_t last_message_id; /**< Last message ID used */
atomic_uint next_message_id; /**< Next message ID to use */
sock_udp_ep_t observers[GCOAP_OBS_CLIENTS_MAX];
/**< Observe clients; allows reuse for
observe memos */

@ -590,7 +590,7 @@ kernel_pid_t gcoap_init(void)
memset(&_coap_state.observers[0], 0, sizeof(_coap_state.observers));
memset(&_coap_state.observe_memos[0], 0, sizeof(_coap_state.observe_memos));
/* randomize initial value */
_coap_state.last_message_id = random_uint32() & 0xFFFF;
atomic_init(&_coap_state.next_message_id, (unsigned)random_uint32());
return _pid;
}
@ -609,7 +609,6 @@ void gcoap_register_listener(gcoap_listener_t *listener)
int gcoap_req_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code,
char *path) {
ssize_t hdrlen;
(void)len;
pdu->hdr = (coap_hdr_t *)buf;
@ -624,11 +623,13 @@ int gcoap_req_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code,
&rand,
(GCOAP_TOKENLEN - i >= 4) ? 4 : GCOAP_TOKENLEN - i);
}
hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, &token[0], GCOAP_TOKENLEN,
code, ++_coap_state.last_message_id);
uint16_t msgid = (uint16_t)atomic_fetch_add(&_coap_state.next_message_id, 1);
ssize_t hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, &token[0], GCOAP_TOKENLEN,
code, msgid);
#else
hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, NULL, GCOAP_TOKENLEN,
code, ++_coap_state.last_message_id);
uint16_t msgid = (uint16_t)atomic_fetch_add(&_coap_state.next_message_id, 1);
ssize_t hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, NULL, GCOAP_TOKENLEN,
code, msgid);
#endif
if (hdrlen > 0) {
@ -742,7 +743,6 @@ int gcoap_resp_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code)
int gcoap_obs_init(coap_pkt_t *pdu, uint8_t *buf, size_t len,
const coap_resource_t *resource)
{
ssize_t hdrlen;
gcoap_observe_memo_t *memo = NULL;
_find_obs_memo_resource(&memo, resource);
@ -751,10 +751,11 @@ int gcoap_obs_init(coap_pkt_t *pdu, uint8_t *buf, size_t len,
return GCOAP_OBS_INIT_UNUSED;
}
pdu->hdr = (coap_hdr_t *)buf;
hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, &memo->token[0],
memo->token_len, COAP_CODE_CONTENT,
++_coap_state.last_message_id);
pdu->hdr = (coap_hdr_t *)buf;
uint16_t msgid = (uint16_t)atomic_fetch_add(&_coap_state.next_message_id, 1);
ssize_t hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, &memo->token[0],
memo->token_len, COAP_CODE_CONTENT, msgid);
if (hdrlen > 0) {
uint32_t now = xtimer_now_usec();
pdu->observe_value = (now >> GCOAP_OBS_TICK_EXPONENT) & 0xFFFFFF;

Loading…
Cancel
Save