mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-28 07:51:19 +01:00
gcoap: Process CON responses
This generalizes the existing code for answering CoAP pings into general message-layer responses. Such responses are now also sent as a reaction to CON responses, which can otherwise follow the same code path as existing other responses. As a side effect, issues that would crop up when responding to odd empty requests that have token length set are resolved. Contributes-To: https://github.com/RIOT-OS/RIOT/issues/14169
This commit is contained in:
parent
8c9bc2ada0
commit
ff00d66d69
@ -41,6 +41,9 @@
|
||||
#define GCOAP_RESOURCE_WRONG_METHOD -1
|
||||
#define GCOAP_RESOURCE_NO_PATH -2
|
||||
|
||||
/* Sentinel value indicating that no immediate response is required */
|
||||
#define NO_IMMEDIATE_REPLY (-1)
|
||||
|
||||
/* End of the range to pick a random timeout */
|
||||
#define TIMEOUT_RANGE_END (CONFIG_COAP_ACK_TIMEOUT * CONFIG_COAP_RANDOM_FACTOR_1000 / 1000)
|
||||
|
||||
@ -133,6 +136,15 @@ static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg)
|
||||
coap_pkt_t pdu;
|
||||
sock_udp_ep_t remote;
|
||||
gcoap_request_memo_t *memo = NULL;
|
||||
/* 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
|
||||
* of the function there will be
|
||||
* * that value will be put in the code field,
|
||||
* * token length cleared,
|
||||
* * code set to EMPTY, and
|
||||
* * the message is returned with the rest of its header intact.
|
||||
*/
|
||||
int8_t messagelayer_emptyresponse_type = NO_IMMEDIATE_REPLY;
|
||||
|
||||
(void)arg;
|
||||
if (type & SOCK_ASYNC_MSG_RECV) {
|
||||
@ -157,13 +169,7 @@ static void _on_sock_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg)
|
||||
if (coap_get_code_raw(&pdu) == COAP_CODE_EMPTY) {
|
||||
/* ping request */
|
||||
if (coap_get_type(&pdu) == COAP_TYPE_CON) {
|
||||
coap_hdr_set_type(pdu.hdr, COAP_TYPE_RST);
|
||||
|
||||
ssize_t bytes = sock_udp_send(sock, _listen_buf,
|
||||
sizeof(coap_hdr_t), &remote);
|
||||
if (bytes <= 0) {
|
||||
DEBUG("gcoap: ping response failed: %d\n", (int)bytes);
|
||||
}
|
||||
messagelayer_emptyresponse_type = COAP_TYPE_RST;
|
||||
} else if (coap_get_type(&pdu) == COAP_TYPE_NON) {
|
||||
DEBUG("gcoap: empty NON msg\n");
|
||||
}
|
||||
@ -200,6 +206,10 @@ empty_as_response:
|
||||
_find_req_memo(&memo, &pdu, &remote);
|
||||
if (memo) {
|
||||
switch (coap_get_type(&pdu)) {
|
||||
case COAP_TYPE_CON:
|
||||
messagelayer_emptyresponse_type = COAP_TYPE_ACK;
|
||||
DEBUG("gcoap: Answering CON response with ACK\n");
|
||||
/* fall through */
|
||||
case COAP_TYPE_NON:
|
||||
case COAP_TYPE_ACK:
|
||||
if (memo->resp_evt_tmout.queue) {
|
||||
@ -215,9 +225,6 @@ empty_as_response:
|
||||
}
|
||||
memo->state = GCOAP_MEMO_UNUSED;
|
||||
break;
|
||||
case COAP_TYPE_CON:
|
||||
DEBUG("gcoap: separate CON response not handled yet\n");
|
||||
break;
|
||||
default:
|
||||
DEBUG("gcoap: illegal response type: %u\n", coap_get_type(&pdu));
|
||||
break;
|
||||
@ -231,6 +238,23 @@ empty_as_response:
|
||||
DEBUG("gcoap: illegal code class: %u\n", coap_get_code_class(&pdu));
|
||||
}
|
||||
}
|
||||
|
||||
if (messagelayer_emptyresponse_type != NO_IMMEDIATE_REPLY) {
|
||||
coap_hdr_set_type(pdu.hdr, (uint8_t)messagelayer_emptyresponse_type);
|
||||
coap_hdr_set_code(pdu.hdr, COAP_CODE_EMPTY);
|
||||
/* Set the token length to 0, preserving the CoAP version as it was and
|
||||
* the empty message type that was just set.
|
||||
*
|
||||
* FIXME: Introduce an internal function to set or truncate the token
|
||||
* */
|
||||
pdu.hdr->ver_t_tkl &= 0xf0;
|
||||
|
||||
ssize_t bytes = sock_udp_send(sock, _listen_buf,
|
||||
sizeof(coap_hdr_t), &remote);
|
||||
if (bytes <= 0) {
|
||||
DEBUG("gcoap: empty response failed: %d\n", (int)bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handles response timeout for a request; resend confirmable if needed. */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user