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:
commit
9e55e5611f
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -15,6 +15,8 @@ BOARD_INSUFFICIENT_MEMORY := \
|
||||
bluepill-stm32f030c8 \
|
||||
bluepill-stm32f103c8 \
|
||||
derfmega128 \
|
||||
hifive1 \
|
||||
hifive1b \
|
||||
i-nucleo-lrwan1 \
|
||||
im880b \
|
||||
m1284p \
|
||||
|
||||
@ -10,6 +10,8 @@ BOARD_INSUFFICIENT_MEMORY := \
|
||||
atxmega-a1-xplained \
|
||||
atxmega-a1u-xpro \
|
||||
bluepill-stm32f030c8 \
|
||||
hifive1 \
|
||||
hifive1b \
|
||||
i-nucleo-lrwan1 \
|
||||
mega-xplained \
|
||||
microduino-corerf \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user