Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nanocoap: add coap_build_reply_header() #20284

Merged
merged 4 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions sys/include/net/coap.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
* Used in a CoAP request to signal that the request payload conveys both an
* EDHOC message_3 and OSCORE protected data, combined together.
*
* @see [draft-ietf-core-oscore-edhoc-02](https://datatracker.ietf.org/doc/draft-ietf-core-oscore-edhoc/02/)

Check warning on line 88 in sys/include/net/coap.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
*/
#define COAP_OPT_EDHOC (21)
#define COAP_OPT_BLOCK2 (23)
Expand Down Expand Up @@ -354,7 +354,7 @@
#define COAP_FORMAT_SWID_CBOR (258)
/**
* @brief Content-Type `application/pkixcmp`
* @see [draft-ietf-ace-cmpv2-coap-transport](https://datatracker.ietf.org/doc/draft-ietf-ace-cmpv2-coap-transport/)

Check warning on line 357 in sys/include/net/coap.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
* @see [RFC 4210](https://datatracker.ietf.org/doc/html/rfc4210)
*/
#define COAP_FORMAT_PKIXCMP (259)
Expand Down Expand Up @@ -441,22 +441,22 @@
#define COAP_FORMAT_YAML_DATA_CBOR_ID_NAME (341)
/**
* @brief Content-Type `application/td+json`
* @see [Web of Things (WoT) Thing Description 1.1](https://www.w3.org/TR/wot-thing-description11/)

Check warning on line 444 in sys/include/net/coap.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
*/
#define COAP_FORMAT_TD_JSON (432)
/**
* @brief Content-Type `application/tm+json`
* @see [Web of Things (WoT) Thing Description 1.1](https://www.w3.org/TR/wot-thing-description11/)

Check warning on line 449 in sys/include/net/coap.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
*/
#define COAP_FORMAT_TM_JSON (433)
/**
* @brief Content-Type `application/dns-message`
* @see [draft-ietf-core-dns-over-coap](https://datatracker.ietf.org/doc/draft-ietf-core-dns-over-coap/)

Check warning on line 454 in sys/include/net/coap.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
*/
#define COAP_FORMAT_DNS_MESSAGE (553)
/**
* @brief Content-Type `application/voucher-cose+cbor`
* @see [draft-ietf-anima-constrained-voucher](https://datatracker.ietf.org/doc/draft-ietf-anima-constrained-voucher/)

Check warning on line 459 in sys/include/net/coap.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
* @note Temporary registration until April 12, 2024.
*/
#define COAP_FORMAT_VOUCER_COSE_CBOR (836)
Expand Down Expand Up @@ -488,17 +488,17 @@
#define COAP_FORMAT_CBOR_DEFLATE (11060)
/**
* @brief Content-Type `application/vnd.oma.lwm2m+tlv`
* @see [OMA-TS-LightweightM2M-V1_0](https://www.openmobilealliance.org/release/LightweightM2M/V1_0-20170208-A/OMA-TS-LightweightM2M-V1_0-20170208-A.pdf)

Check warning on line 491 in sys/include/net/coap.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
*/
#define COAP_FORMAT_VND_OMA_LWM2M_TLV (11542)
/**
* @brief Content-Type `application/vnd.oma.lwm2m+json`
* @see [OMA-TS-LightweightM2M-V1_0](https://www.openmobilealliance.org/release/LightweightM2M/V1_0-20170208-A/OMA-TS-LightweightM2M-V1_0-20170208-A.pdf)

Check warning on line 496 in sys/include/net/coap.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
*/
#define COAP_FORMAT_VND_OMA_LWM2M_JSON (11543)
/**
* @brief Content-Type `application/vnd.oma.lwm2m+cbor`
* @see [OMA-TS-LightweightM2M-V1_2](https://www.openmobilealliance.org/release/LightweightM2M/V1_2-20201110-A/HTML-Version/OMA-TS-LightweightM2M_Core-V1_2-20201110-A.html)

Check warning on line 501 in sys/include/net/coap.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
*/
#define COAP_FORMAT_VND_OMA_LWM2M_CBOR (11544)
/**
Expand Down Expand Up @@ -535,6 +535,11 @@
#define COAP_ETAG_LENGTH_MAX (8U) /**< maximum length of the ETag option */
/** @} */

/**
* @brief Marks the boundary between header and payload
*/
#define COAP_PAYLOAD_MARKER (0xFF)
benpicco marked this conversation as resolved.
Show resolved Hide resolved

/**
* @defgroup net_coap_conf CoAP compile configurations
* @ingroup net_coap
Expand Down
30 changes: 30 additions & 0 deletions sys/include/net/nanocoap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1843,7 +1843,7 @@
*
* @returns amount of bytes written to @p buf
*/
size_t coap_put_option(uint8_t *buf, uint16_t lastonum, uint16_t onum, const void *odata, size_t olen);

Check warning on line 1846 in sys/include/net/nanocoap.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters

/**
* @brief Insert block1 option into buffer
Expand Down Expand Up @@ -2115,6 +2115,36 @@
*/
ssize_t coap_payload_put_char(coap_pkt_t *pkt, char c);

/**
* @brief Create CoAP reply header (convenience function)
*
* This function generates the reply CoAP header and sets
* the payload pointer inside the response buffer to point to
* the start of the payload, so that it can be written directly
* after the header.
*
* @param[in] pkt packet to reply to
* @param[in] code reply code (e.g., COAP_CODE_204)
* @param[out] buf buffer to write reply to
* @param[in] len size of @p buf
* @param[in] ct content type of payload
* if ct < 0 this will be ignored
* @param[out] payload Will be set to the start of the payload inside
* @p buf.
* May be set to NULL if no payload response is
mguetschow marked this conversation as resolved.
Show resolved Hide resolved
* wanted (no-reply option)
* @param[out] payload_len_max max length of payload left in @p buf
*
* @returns size of reply header on success
* @returns 0 if no reply should be sent
* @returns <0 on error
* @returns -ENOSPC if @p buf too small
*/
ssize_t coap_build_reply_header(coap_pkt_t *pkt, unsigned code,
void *buf, size_t len,
int ct,
void **payload, size_t *payload_len_max);

/**
* @brief Create CoAP reply (convenience function)
*
Expand Down
88 changes: 72 additions & 16 deletions sys/net/application_layer/nanocoap/nanocoap.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len)
while (pkt_pos < pkt_end) {
uint8_t *option_start = pkt_pos;
uint8_t option_byte = *pkt_pos++;
if (option_byte == 0xff) {
if (option_byte == COAP_PAYLOAD_MARKER) {
pkt->payload = pkt_pos;
pkt->payload_len = buf + len - pkt_pos;
DEBUG("payload len = %u\n", pkt->payload_len);
Expand Down Expand Up @@ -232,7 +232,7 @@ static uint8_t *_parse_option(const coap_pkt_t *pkt,
uint8_t *hdr_end = pkt->payload;

if ((pkt_pos >= hdr_end)
|| (((pkt_pos + 1) == hdr_end) && (*pkt_pos == 0xFF))) {
|| (((pkt_pos + 1) == hdr_end) && (*pkt_pos == COAP_PAYLOAD_MARKER))) {
return NULL;
}

Expand Down Expand Up @@ -545,29 +545,85 @@ ssize_t coap_tree_handler(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_
return coap_build_reply(pkt, COAP_CODE_404, resp_buf, resp_buf_len, 0);
}

ssize_t coap_build_reply_header(coap_pkt_t *pkt, unsigned code,
void *buf, size_t len,
int ct,
void **payload, size_t *payload_len_max)
{
uint8_t *bufpos = buf;
uint32_t no_response;
unsigned tkl = coap_get_token_len(pkt);
size_t hdr_len = sizeof(coap_hdr_t) + tkl;
uint8_t type = coap_get_type(pkt) == COAP_TYPE_CON
? COAP_TYPE_ACK
: COAP_TYPE_NON;

if (hdr_len > len) {
return -ENOBUFS;
}

bufpos += coap_build_hdr(buf, type, coap_get_token(pkt), tkl,
code, ntohs(pkt->hdr->id));

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 */
assume(no_response_index < 7);

const uint8_t mask = 1 << no_response_index;
if (no_response & mask) {
if (payload) {
*payload = NULL;
*payload_len_max = 0;
payload = NULL;
}

/* no-response requested, only send empty ACK or nothing */
if (type != COAP_TYPE_ACK) {
return 0;
mguetschow marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

if (payload) {
if (ct >= 0) {
bufpos += coap_put_option_ct(bufpos, 0, ct);
}
*bufpos++ = COAP_PAYLOAD_MARKER;
*payload = bufpos;
hdr_len = bufpos - (uint8_t *)buf;
*payload_len_max = len - hdr_len;
}

/* with the nanoCoAP API we can't detect the overflow before it happens */
assert(hdr_len <= len);

return hdr_len;
}

ssize_t coap_reply_simple(coap_pkt_t *pkt,
unsigned code,
uint8_t *buf, size_t len,
unsigned ct,
const void *payload, size_t payload_len)
{
uint8_t *payload_start = buf + coap_get_total_hdr_len(pkt);
uint8_t *bufpos = payload_start;
void *payload_start;
size_t payload_len_max;

if (payload_len) {
bufpos += coap_put_option_ct(bufpos, 0, ct);
*bufpos++ = 0xff;
ssize_t header_len = coap_build_reply_header(pkt, code, buf, len, ct,
payload ? &payload_start : NULL,
&payload_len_max);
if (payload == NULL || header_len <= 0) {
return header_len;
}

ssize_t res = coap_build_reply(pkt, code, buf, len,
bufpos - payload_start + payload_len);

if (payload_len && (res > 0)) {
assert(payload);
memcpy(bufpos, payload, payload_len);
if (payload_len > payload_len_max) {
return -ENOBUFS;
}

return res;
memcpy(payload_start, payload, payload_len);

return header_len + payload_len;
}

ssize_t coap_build_reply(coap_pkt_t *pkt, unsigned code,
Expand Down Expand Up @@ -1112,7 +1168,7 @@ ssize_t coap_opt_finish(coap_pkt_t *pkt, uint16_t flags)
return -ENOSPC;
}

*pkt->payload++ = 0xFF;
*pkt->payload++ = COAP_PAYLOAD_MARKER;
pkt->payload_len--;
}
else {
Expand Down Expand Up @@ -1337,7 +1393,7 @@ ssize_t coap_well_known_core_default_handler(coap_pkt_t *pkt, uint8_t *buf, \
bufpos += coap_put_option_ct(bufpos, 0, COAP_FORMAT_LINK);
bufpos += coap_opt_put_block2(bufpos, COAP_OPT_CONTENT_FORMAT, &slicer, 1);

*bufpos++ = 0xff;
*bufpos++ = COAP_PAYLOAD_MARKER;

for (unsigned i = 0; i < coap_resources_numof; i++) {
if (i) {
Expand Down
Loading