net/gcoap: Refactor lookup for outstanding request

Add support for a confirmable request and standardize token match.
This commit is contained in:
Ken Bannister 2017-07-09 07:35:42 -04:00
parent 70be8cd5bb
commit 37f272bf2c

View File

@ -35,8 +35,7 @@ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
sock_udp_ep_t *remote); sock_udp_ep_t *remote);
static ssize_t _finish_pdu(coap_pkt_t *pdu, uint8_t *buf, size_t len); static ssize_t _finish_pdu(coap_pkt_t *pdu, uint8_t *buf, size_t len);
static void _expire_request(gcoap_request_memo_t *memo); static void _expire_request(gcoap_request_memo_t *memo);
static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *pdu, static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *pdu);
uint8_t *buf, size_t len);
static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr, static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
gcoap_listener_t **listener_ptr); gcoap_listener_t **listener_ptr);
static int _find_observer(sock_udp_ep_t **observer, sock_udp_ep_t *remote); static int _find_observer(sock_udp_ep_t **observer, sock_udp_ep_t *remote);
@ -156,7 +155,7 @@ static void _listen(sock_udp_t *sock)
/* incoming response */ /* incoming response */
else { else {
_find_req_memo(&memo, &pdu, buf, sizeof(buf)); _find_req_memo(&memo, &pdu);
if (memo) { if (memo) {
xtimer_remove(&memo->response_timer); xtimer_remove(&memo->response_timer);
memo->state = GCOAP_MEMO_RESP; memo->state = GCOAP_MEMO_RESP;
@ -331,39 +330,34 @@ static ssize_t _finish_pdu(coap_pkt_t *pdu, uint8_t *buf, size_t len)
* Finds the memo for an outstanding request within the _coap_state.open_reqs * Finds the memo for an outstanding request within the _coap_state.open_reqs
* array. Matches on token. * array. Matches on token.
* *
* src_pdu Source for the match token * memo_ptr[out] -- Registered request memo, or NULL if not found
* src_pdu[in] -- PDU for token to match
*/ */
static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *src_pdu, static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *src_pdu)
uint8_t *buf, size_t len)
{ {
gcoap_request_memo_t *memo; *memo_ptr = NULL;
coap_pkt_t memo_pdu = { .token = NULL }; /* no need to initialize struct; we only care about buffer contents below */
(void) buf; coap_pkt_t memo_pdu_data;
(void) len; coap_pkt_t *memo_pdu = &memo_pdu_data;
unsigned cmplen = coap_get_token_len(src_pdu);
for (int i = 0; i < GCOAP_REQ_WAITING_MAX; i++) { for (int i = 0; i < GCOAP_REQ_WAITING_MAX; i++) {
if (_coap_state.open_reqs[i].state == GCOAP_MEMO_UNUSED) if (_coap_state.open_reqs[i].state == GCOAP_MEMO_UNUSED)
continue; continue;
/* setup memo PDU from memo header */ gcoap_request_memo_t *memo = &_coap_state.open_reqs[i];
memo = &_coap_state.open_reqs[i]; if (memo->send_limit == GCOAP_SEND_LIMIT_NON) {
coap_hdr_t *memo_hdr = (coap_hdr_t *) &memo->msg.hdr_buf[0]; memo_pdu->hdr = (coap_hdr_t *) &memo->msg.hdr_buf[0];
memo_pdu.hdr = memo_hdr;
if (coap_get_token_len(&memo_pdu)) {
memo_pdu.token = &memo_hdr->data[0];
} }
/* match on token */ else {
if (coap_get_token_len(src_pdu) == coap_get_token_len(&memo_pdu)) { memo_pdu->hdr = (coap_hdr_t *) memo->msg.data.pdu_buf;
uint8_t *src_byte = src_pdu->token; }
uint8_t *memo_byte = memo_pdu.token;
size_t j; if (coap_get_token_len(memo_pdu) == cmplen) {
for (j = 0; j < coap_get_token_len(src_pdu); j++) { memo_pdu->token = &memo_pdu->hdr->data[0];
if (*src_byte++ != *memo_byte++) { if (memcmp(src_pdu->token, memo_pdu->token, cmplen) == 0) {
break; /* token mismatch */
}
}
if (j == coap_get_token_len(src_pdu)) {
*memo_ptr = memo; *memo_ptr = memo;
break;
} }
} }
} }