mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #20284 from benpicco/coap_build_reply_header
nanocoap: add coap_build_reply_header()
This commit is contained in:
commit
2d459157f1
@ -535,6 +535,11 @@ typedef enum {
|
||||
#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)
|
||||
|
||||
/**
|
||||
* @defgroup net_coap_conf CoAP compile configurations
|
||||
* @ingroup net_coap
|
||||
|
@ -2115,6 +2115,36 @@ ssize_t coap_payload_put_bytes(coap_pkt_t *pkt, const void *data, size_t len);
|
||||
*/
|
||||
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
|
||||
* 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)
|
||||
*
|
||||
|
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
@ -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 {
|
||||
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user