net/gcoap: split out the coap processing part of _on_sock_evt

This commit is contained in:
János Brodbeck 2020-11-05 16:04:02 +01:00
parent 565242f67e
commit c4e646037d
No known key found for this signature in database
GPG Key ID: 65C193B0D8D1BCE6

View File

@ -45,6 +45,8 @@
/* Internal functions */ /* Internal functions */
static void *_event_loop(void *arg); static void *_event_loop(void *arg);
static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg); static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg);
static void _process_coap_pdu(sock_udp_t *sock, sock_udp_ep_t *remote,
uint8_t *buf, size_t len);
static ssize_t _well_known_core_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); static ssize_t _well_known_core_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx);
static void _cease_retransmission(gcoap_request_memo_t *memo); static void _cease_retransmission(gcoap_request_memo_t *memo);
static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len, static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
@ -132,11 +134,28 @@ static void *_event_loop(void *arg)
return 0; return 0;
} }
/* Handles sock events from the event queue. */ /* Handles UDP socket events from the event queue. */
static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg) static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg)
{ {
coap_pkt_t pdu; (void)arg;
sock_udp_ep_t remote; sock_udp_ep_t remote;
if (type & SOCK_ASYNC_MSG_RECV) {
ssize_t res = sock_udp_recv(sock, _listen_buf, sizeof(_listen_buf),
0, &remote);
if (res <= 0) {
DEBUG("gcoap: udp recv failure: %d\n", (int)res);
return;
}
_process_coap_pdu(sock, &remote, _listen_buf, res);
}
}
/* Processes and evaluates the coap pdu */
static void _process_coap_pdu(sock_udp_t *sock, sock_udp_ep_t *remote,
uint8_t *buf, size_t len)
{
coap_pkt_t pdu;
gcoap_request_memo_t *memo = NULL; gcoap_request_memo_t *memo = NULL;
/* Code paths that necessitate a response on the message layer can set a /* Code paths that necessitate a response on the message layer can set a
* response type here (COAP_TYPE_RST or COAP_TYPE_ACK). If set, at the end * response type here (COAP_TYPE_RST or COAP_TYPE_ACK). If set, at the end
@ -148,16 +167,7 @@ static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg)
*/ */
int8_t messagelayer_emptyresponse_type = NO_IMMEDIATE_REPLY; int8_t messagelayer_emptyresponse_type = NO_IMMEDIATE_REPLY;
(void)arg; ssize_t res = coap_parse(&pdu, buf, len);
if (type & SOCK_ASYNC_MSG_RECV) {
ssize_t res = sock_udp_recv(sock, _listen_buf, sizeof(_listen_buf),
0, &remote);
if (res <= 0) {
DEBUG("gcoap: udp recv failure: %d\n", (int)res);
return;
}
res = coap_parse(&pdu, _listen_buf, res);
if (res < 0) { if (res < 0) {
DEBUG("gcoap: parse failure: %d\n", (int)res); DEBUG("gcoap: parse failure: %d\n", (int)res);
/* If a response, can't clear memo, but it will timeout later. */ /* If a response, can't clear memo, but it will timeout later. */
@ -174,7 +184,7 @@ static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg)
messagelayer_emptyresponse_type = COAP_TYPE_RST; messagelayer_emptyresponse_type = COAP_TYPE_RST;
DEBUG("gcoap: Answering empty CON request with RST\n"); DEBUG("gcoap: Answering empty CON request with RST\n");
} else if (coap_get_type(&pdu) == COAP_TYPE_ACK) { } else if (coap_get_type(&pdu) == COAP_TYPE_ACK) {
_find_req_memo(&memo, &pdu, &remote, true); _find_req_memo(&memo, &pdu, remote, true);
if ((memo != NULL) && (memo->send_limit != GCOAP_SEND_LIMIT_NON)) { if ((memo != NULL) && (memo->send_limit != GCOAP_SEND_LIMIT_NON)) {
DEBUG("gcoap: empty ACK processed, stopping retransmissions\n"); DEBUG("gcoap: empty ACK processed, stopping retransmissions\n");
_cease_retransmission(memo); _cease_retransmission(memo);
@ -189,10 +199,10 @@ static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg)
else if (coap_get_type(&pdu) == COAP_TYPE_NON else if (coap_get_type(&pdu) == COAP_TYPE_NON
|| coap_get_type(&pdu) == COAP_TYPE_CON) { || coap_get_type(&pdu) == COAP_TYPE_CON) {
size_t pdu_len = _handle_req(&pdu, _listen_buf, sizeof(_listen_buf), size_t pdu_len = _handle_req(&pdu, _listen_buf, sizeof(_listen_buf),
&remote); remote);
if (pdu_len > 0) { if (pdu_len > 0) {
ssize_t bytes = sock_udp_send(sock, _listen_buf, pdu_len, ssize_t bytes = sock_udp_send(sock, _listen_buf, pdu_len,
&remote); remote);
if (bytes <= 0) { if (bytes <= 0) {
DEBUG("gcoap: send response failed: %d\n", (int)bytes); DEBUG("gcoap: send response failed: %d\n", (int)bytes);
} }
@ -207,7 +217,7 @@ static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg)
case COAP_CLASS_SUCCESS: case COAP_CLASS_SUCCESS:
case COAP_CLASS_CLIENT_FAILURE: case COAP_CLASS_CLIENT_FAILURE:
case COAP_CLASS_SERVER_FAILURE: case COAP_CLASS_SERVER_FAILURE:
_find_req_memo(&memo, &pdu, &remote, false); _find_req_memo(&memo, &pdu, remote, false);
if (memo) { if (memo) {
switch (coap_get_type(&pdu)) { switch (coap_get_type(&pdu)) {
case COAP_TYPE_CON: case COAP_TYPE_CON:
@ -221,7 +231,7 @@ static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg)
} }
memo->state = GCOAP_MEMO_RESP; memo->state = GCOAP_MEMO_RESP;
if (memo->resp_handler) { if (memo->resp_handler) {
memo->resp_handler(memo, &pdu, &remote); memo->resp_handler(memo, &pdu, remote);
} }
if (memo->send_limit >= 0) { /* if confirmable */ if (memo->send_limit >= 0) { /* if confirmable */
@ -241,7 +251,6 @@ static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg)
default: default:
DEBUG("gcoap: illegal code class: %u\n", coap_get_code_class(&pdu)); DEBUG("gcoap: illegal code class: %u\n", coap_get_code_class(&pdu));
} }
}
if (messagelayer_emptyresponse_type != NO_IMMEDIATE_REPLY) { if (messagelayer_emptyresponse_type != NO_IMMEDIATE_REPLY) {
coap_hdr_set_type(pdu.hdr, (uint8_t)messagelayer_emptyresponse_type); coap_hdr_set_type(pdu.hdr, (uint8_t)messagelayer_emptyresponse_type);
@ -253,8 +262,8 @@ static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg)
* */ * */
pdu.hdr->ver_t_tkl &= 0xf0; pdu.hdr->ver_t_tkl &= 0xf0;
ssize_t bytes = sock_udp_send(sock, _listen_buf, ssize_t bytes = sock_udp_send(sock, buf,
sizeof(coap_hdr_t), &remote); sizeof(coap_hdr_t), remote);
if (bytes <= 0) { if (bytes <= 0) {
DEBUG("gcoap: empty response failed: %d\n", (int)bytes); DEBUG("gcoap: empty response failed: %d\n", (int)bytes);
} }