1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 22:43:50 +01:00

Merge pull request #21270 from fabian18/pr/nanocoap_static_buffers

nanocoap: avoid non `static` buffers of configurable size
This commit is contained in:
fabian18 2025-03-31 22:46:38 +00:00 committed by GitHub
commit 9e55e5611f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 59 additions and 47 deletions

View File

@ -45,12 +45,15 @@ typedef int (*coap_link_format_handler_t)(char *entry, void *ctx);
* @param[in] path path of the resource
* @param[in] cb Callback to execute for each resource entry
* @param[in] arg Optional callback argument
* @param[out] dirent_buf Response buffer
* @param[in] dirent_buf_len Length of the response buffer
*
* @returns 0 on success
* @returns <0 on error
*/
int nanocoap_link_format_get(nanocoap_sock_t *sock, const char *path,
coap_link_format_handler_t cb, void *arg);
coap_link_format_handler_t cb, void *arg,
char *dirent_buf, size_t dirent_buf_len);
/**
* @brief Downloads the resource behind @p url via blockwise GET
@ -58,12 +61,15 @@ int nanocoap_link_format_get(nanocoap_sock_t *sock, const char *path,
* @param[in] url URL to the resource
* @param[in] cb Callback to execute for each resource entry
* @param[in] arg Optional callback argument
* @param[out] dirent_buf Response buffer
* @param[in] dirent_buf_len Length of the response buffer
*
* @returns 0 on success
* @returns <0 on error
*/
int nanocoap_link_format_get_url(const char *url,
coap_link_format_handler_t cb, void *arg);
coap_link_format_handler_t cb, void *arg,
char *dirent_buf, size_t dirent_buf_len);
#ifdef __cplusplus
}

View File

@ -211,6 +211,8 @@ typedef struct {
nanocoap_socket_type_t type; /**< Socket type (UDP, DTLS) */
#endif
uint16_t msg_id; /**< next CoAP message ID */
uint8_t hdr_buf[CONFIG_NANOCOAP_BLOCK_HEADER_MAX]; /**< buffer for CoAP header with options,
token and payload marker */
} nanocoap_sock_t;
/**
@ -555,14 +557,14 @@ static inline void nanocoap_sock_close(nanocoap_sock_t *sock)
*
* @param[in] sock socket to use for the request
* @param[in] path remote path and query
* @param[out] buf buffer to write response to
* @param[in] len length of @p buffer
* @param[out] response buffer to write response to
* @param[in] len_max length of @p buffer
*
* @returns length of response payload on success
* @returns @see nanocoap_sock_request_cb on error
*/
ssize_t nanocoap_sock_get(nanocoap_sock_t *sock, const char *path, void *buf,
size_t len);
ssize_t nanocoap_sock_get(nanocoap_sock_t *sock, const char *path,
void *response, size_t len_max);
/**
* @brief Simple non-confirmable GET

View File

@ -30,6 +30,8 @@
#define ENABLE_DEBUG 0
#include "debug.h"
static char _dirent_buf[CONFIG_NANOCOAP_QS_MAX];
static int nanocoap_fs_mount(vfs_mount_t *mountp)
{
nanocoap_fs_t *fs = mountp->private_data;
@ -288,7 +290,8 @@ static int nanocoap_fs_readdir(vfs_DIR *dirp, vfs_dirent_t *entry)
.offset = dir->offset++,
};
res = nanocoap_link_format_get(&fs->sock, dir->urlbuf, _dir_cb, &ctx);
res = nanocoap_link_format_get(&fs->sock, dir->urlbuf, _dir_cb, &ctx,
_dirent_buf, sizeof(_dirent_buf));
if (res == -EINTR) {
/* we use this to abort listing early */
res = 1;

View File

@ -85,13 +85,13 @@ static int _dirlist_cb(void *arg, size_t offset, uint8_t *buf, size_t len, int m
}
int nanocoap_link_format_get(nanocoap_sock_t *sock, const char *path,
coap_link_format_handler_t cb, void *arg)
coap_link_format_handler_t cb, void *arg,
char *dirent_buf, size_t dirent_buf_len)
{
char buffer[CONFIG_NANOCOAP_QS_MAX];
struct dir_list_ctx ctx = {
.buf = buffer,
.end = buffer + sizeof(buffer),
.cur = buffer,
.buf = dirent_buf,
.end = dirent_buf + dirent_buf_len,
.cur = dirent_buf,
.cb = cb,
.ctx = arg,
};
@ -99,7 +99,8 @@ int nanocoap_link_format_get(nanocoap_sock_t *sock, const char *path,
_dirlist_cb, &ctx);
}
int nanocoap_link_format_get_url(const char *url, coap_link_format_handler_t cb, void *arg)
int nanocoap_link_format_get_url(const char *url, coap_link_format_handler_t cb, void *arg,
char *dirent_buf, size_t dirent_buf_len)
{
nanocoap_sock_t sock;
int res = nanocoap_sock_url_connect(url, &sock);
@ -107,7 +108,7 @@ int nanocoap_link_format_get_url(const char *url, coap_link_format_handler_t cb,
return res;
}
res = nanocoap_link_format_get(&sock, sock_urlpath(url), cb, arg);
res = nanocoap_link_format_get(&sock, sock_urlpath(url), cb, arg, dirent_buf, dirent_buf_len);
nanocoap_sock_close(&sock);
return res;

View File

@ -435,9 +435,7 @@ static ssize_t _sock_get(nanocoap_sock_t *sock, const char *path,
uint8_t type,
void *response, size_t max_len)
{
/* buffer for CoAP header */
uint8_t buffer[CONFIG_NANOCOAP_BLOCK_HEADER_MAX];
uint8_t *pktpos = buffer;
uint8_t *pktpos = sock->hdr_buf;
coap_pkt_t pkt = {
.hdr = (void *)pktpos,
@ -451,6 +449,7 @@ static ssize_t _sock_get(nanocoap_sock_t *sock, const char *path,
pktpos += coap_build_hdr(pkt.hdr, type, NULL, 0, COAP_METHOD_GET,
nanocoap_sock_next_msg_id(sock));
pktpos += coap_opt_put_uri_pathquery(pktpos, NULL, path);
assert(pktpos < (uint8_t *)sock->hdr_buf + sizeof(sock->hdr_buf));
pkt.payload = pktpos;
pkt.payload_len = 0;
@ -458,18 +457,17 @@ static ssize_t _sock_get(nanocoap_sock_t *sock, const char *path,
return nanocoap_sock_request_cb(sock, &pkt, _get_put_cb, &ctx);
}
ssize_t nanocoap_sock_get(nanocoap_sock_t *sock, const char *path, void *buf, size_t len)
ssize_t nanocoap_sock_get(nanocoap_sock_t *sock, const char *path,
void *response, size_t len_max)
{
return _sock_get(sock, path, COAP_TYPE_CON, buf, len);
return _sock_get(sock, path, COAP_TYPE_CON, response, len_max);
}
ssize_t _sock_put_post(nanocoap_sock_t *sock, const char *path, unsigned code,
uint8_t type, const void *request, size_t len,
void *response, size_t max_len)
{
/* buffer for CoAP header */
uint8_t buffer[CONFIG_NANOCOAP_BLOCK_HEADER_MAX];
uint8_t *pktpos = buffer;
uint8_t *pktpos = sock->hdr_buf;
iolist_t payload = {
.iol_base = (void *)request,
@ -477,7 +475,7 @@ ssize_t _sock_put_post(nanocoap_sock_t *sock, const char *path, unsigned code,
};
coap_pkt_t pkt = {
.hdr = (void *)buffer,
.hdr = (void *)pktpos,
.snips = &payload,
};
@ -500,6 +498,7 @@ ssize_t _sock_put_post(nanocoap_sock_t *sock, const char *path, unsigned code,
/* set payload marker */
*pktpos++ = 0xFF;
}
assert(pktpos < (uint8_t *)sock->hdr_buf + sizeof(sock->hdr_buf));
pkt.payload = pktpos;
pkt.payload_len = 0;
@ -601,9 +600,7 @@ ssize_t nanocoap_sock_fetch_url(const char *url,
ssize_t nanocoap_sock_delete(nanocoap_sock_t *sock, const char *path)
{
/* buffer for CoAP header */
uint8_t buffer[CONFIG_NANOCOAP_BLOCK_HEADER_MAX];
uint8_t *pktpos = buffer;
uint8_t *pktpos = sock->hdr_buf;
coap_pkt_t pkt = {
.hdr = (void *)pktpos,
@ -612,6 +609,7 @@ ssize_t nanocoap_sock_delete(nanocoap_sock_t *sock, const char *path)
pktpos += coap_build_hdr(pkt.hdr, COAP_TYPE_CON, NULL, 0, COAP_METHOD_DELETE,
nanocoap_sock_next_msg_id(sock));
pktpos += coap_opt_put_uri_pathquery(pktpos, NULL, path);
assert(pktpos < (uint8_t *)sock->hdr_buf + sizeof(sock->hdr_buf));
pkt.payload = pktpos;
@ -720,14 +718,13 @@ int nanocoap_sock_block_request(coap_block_request_t *req,
}
int res;
uint8_t buf[CONFIG_NANOCOAP_BLOCK_HEADER_MAX];
iolist_t snip = {
.iol_base = (void *)data,
.iol_len = len,
};
coap_pkt_t pkt = {
.hdr = (void *)buf,
.hdr = (void *)req->sock->hdr_buf,
.snips = &snip,
};
@ -743,6 +740,7 @@ int nanocoap_sock_block_request(coap_block_request_t *req,
/* set payload marker */
*pktpos++ = 0xFF;
}
assert(pktpos < (uint8_t *)req->sock->hdr_buf + sizeof(req->sock->hdr_buf));
pkt.payload = pktpos;
pkt.payload_len = 0;
@ -760,8 +758,6 @@ int nanocoap_sock_get_blockwise(nanocoap_sock_t *sock, const char *path,
coap_blksize_t blksize,
coap_blockwise_cb_t callback, void *arg)
{
uint8_t buf[CONFIG_NANOCOAP_BLOCK_HEADER_MAX];
_block_ctx_t ctx = {
.callback = callback,
.arg = arg,
@ -776,7 +772,7 @@ int nanocoap_sock_get_blockwise(nanocoap_sock_t *sock, const char *path,
while (ctx.more) {
DEBUG("nanocoap: fetching block %"PRIu32"\n", ctx.blknum);
int res = _fetch_block(sock, buf, sizeof(buf), path, blksize, &ctx);
int res = _fetch_block(sock, sock->hdr_buf, sizeof(sock->hdr_buf), path, blksize, &ctx);
if (res == -EAGAIN) {
if (--retries) {
continue;
@ -853,8 +849,6 @@ int nanocoap_sock_get_slice(nanocoap_sock_t *sock, const char *path,
coap_blksize_t blksize, size_t offset,
void *dst, size_t len)
{
uint8_t buf[CONFIG_NANOCOAP_BLOCK_HEADER_MAX];
/* try to find optimal blocksize */
unsigned num_blocks = _num_blks(offset, len, blksize);
for (uint8_t szx = 0; szx < blksize; ++szx) {
@ -885,7 +879,7 @@ int nanocoap_sock_get_slice(nanocoap_sock_t *sock, const char *path,
while (dst_ctx.len) {
DEBUG("nanocoap: fetching block %"PRIu32"\n", ctx.blknum);
int res = _fetch_block(sock, buf, sizeof(buf), path, blksize, &ctx);
int res = _fetch_block(sock, sock->hdr_buf, sizeof(sock->hdr_buf), path, blksize, &ctx);
if (res == -EAGAIN) {
if (--retries) {
continue;

View File

@ -38,6 +38,9 @@
#define CONFIG_NCGET_DEFAULT_DATA_DIR VFS_DEFAULT_DATA
#endif
static char _uri[CONFIG_NANOCOAP_URI_MAX];
static char _response[CONFIG_NANOCOAP_QS_MAX];
struct dir_list_ctx {
char *buf;
char *cur;
@ -96,7 +99,6 @@ static int _print_cb(void *arg, size_t offset, uint8_t *buf, size_t len, int mor
static int _nanocoap_get_handler(int argc, char **argv)
{
int res;
char buffer[CONFIG_NANOCOAP_URI_MAX];
char *dst, *url = argv[1];
if (argc < 2) {
@ -107,7 +109,8 @@ static int _nanocoap_get_handler(int argc, char **argv)
if (_is_dir(url) && argc < 3) {
bool _ctx = false;
res = nanocoap_link_format_get_url(url, _resource_cb, &_ctx);
res = nanocoap_link_format_get_url(url, _resource_cb, &_ctx,
_response, sizeof(_response));
if (res) {
printf("Request failed: %s\n", strerror(-res));
}
@ -120,22 +123,22 @@ static int _nanocoap_get_handler(int argc, char **argv)
printf("invalid url: '%s'\n", url);
return -EINVAL;
}
if (snprintf(buffer, sizeof(buffer), "%s%s",
CONFIG_NCGET_DEFAULT_DATA_DIR, dst) >= (int)sizeof(buffer)) {
if (snprintf(_uri, sizeof(_uri), "%s%s",
CONFIG_NCGET_DEFAULT_DATA_DIR, dst) >= (int)sizeof(_uri)) {
printf("Output file path too long\n");
return -ENOBUFS;
}
dst = buffer;
dst = _uri;
} else {
char *filename = strrchr(url, '/');
dst = argv[2];
if (vfs_is_dir(dst) > 0 && filename) {
if (snprintf(buffer, sizeof(buffer), "%s%s",
dst, filename) >= (int)sizeof(buffer)) {
if (snprintf(_uri, sizeof(_uri), "%s%s",
dst, filename) >= (int)sizeof(_uri)) {
printf("Output file path too long\n");
return -ENOBUFS;
}
dst = buffer;
dst = _uri;
}
}
@ -158,8 +161,7 @@ static int _nanocoap_put_handler(int argc, char **argv)
{
int res;
char *file, *url;
char buffer[CONFIG_NANOCOAP_URI_MAX];
char work_buf[coap_szx2size(CONFIG_NANOCOAP_BLOCKSIZE_DEFAULT) + 1];
static char work_buf[coap_szx2size(CONFIG_NANOCOAP_BLOCKSIZE_DEFAULT) + 1];
if (argc < 3) {
printf("Usage: %s <file> <url>\n", argv[0]);
@ -174,12 +176,12 @@ static int _nanocoap_put_handler(int argc, char **argv)
if (basename == NULL) {
return -EINVAL;
}
if (snprintf(buffer, sizeof(buffer), "%s%s",
url, basename + 1) >= (int)sizeof(buffer)) {
if (snprintf(_uri, sizeof(_uri), "%s%s",
url, basename + 1) >= (int)sizeof(_uri)) {
puts("Constructed URI too long");
return -ENOBUFS;
}
url = buffer;
url = _uri;
}
if (strcmp(file, "-") == 0) {

View File

@ -15,6 +15,8 @@ BOARD_INSUFFICIENT_MEMORY := \
bluepill-stm32f030c8 \
bluepill-stm32f103c8 \
derfmega128 \
hifive1 \
hifive1b \
i-nucleo-lrwan1 \
im880b \
m1284p \

View File

@ -10,6 +10,8 @@ BOARD_INSUFFICIENT_MEMORY := \
atxmega-a1-xplained \
atxmega-a1u-xpro \
bluepill-stm32f030c8 \
hifive1 \
hifive1b \
i-nucleo-lrwan1 \
mega-xplained \
microduino-corerf \