1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

nanocoap: add support for no-response option

See https://datatracker.ietf.org/doc/rfc7967/
This commit is contained in:
Benjamin Valentin 2022-05-26 18:15:48 +02:00
parent 4493afb582
commit 56f36c09a0
3 changed files with 38 additions and 0 deletions

View File

@ -53,6 +53,11 @@ extern "C" {
#define COAP_OPT_BLOCK1 (27)
#define COAP_OPT_PROXY_URI (35)
#define COAP_OPT_PROXY_SCHEME (39)
/**
* @brief suppress CoAP response
* @see [RFC 7968](https://datatracker.ietf.org/doc/html/rfc7967)
*/
#define COAP_OPT_NO_RESPONSE (258)
/** @} */
/**

View File

@ -1817,6 +1817,13 @@ ssize_t coap_build_hdr(coap_hdr_t *hdr, unsigned type, uint8_t *token,
* @param[in] payload_len length of payload
*
* @returns size of reply packet on success
*
* Note that this size can be severely shortened if due to a No-Response option there
* is only an empty ACK to be sent back. The caller may just continue populating the
* payload (the space was checked to suffice), but may also skip that needless step
* if the returned length is less than the requested payload length.
*
* @returns 0 if no response should be sent due to a No-Response option in the request
* @returns <0 on error
* @returns -ENOSPC if @p rbuf too small
*/

View File

@ -513,6 +513,32 @@ ssize_t coap_build_reply(coap_pkt_t *pkt, unsigned code,
}
}
uint32_t no_response;
if (coap_opt_get_uint(pkt, COAP_OPT_NO_RESPONSE, &no_response) == 0) {
const uint8_t no_response_index = (code >> 5) - 1;
/* If the handler code misbehaved here, we'd face UB otherwise */
assert(no_response_index < 7);
const uint8_t mask = 1 << no_response_index;
/* option contains bitmap of disinterest */
if (no_response & mask) {
switch (coap_get_type(pkt)) {
case COAP_TYPE_NON:
/* no response and no ACK */
return 0;
default:
/* There is an immediate ACK response, but it is an empty response */
code = COAP_CODE_EMPTY;
len = sizeof(coap_hdr_t);
tkl = 0;
payload_len = 0;
break;
}
}
}
coap_build_hdr((coap_hdr_t *)rbuf, type, coap_get_token(pkt), tkl, code,
ntohs(pkt->hdr->id));
coap_hdr_set_type((coap_hdr_t *)rbuf, type);