From bb42f6a2f48bcf9f09c3bdfb1a3236f050040951 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 18 Apr 2022 03:01:35 +0200 Subject: [PATCH] nanocoap_vfs: add nanocoap_vfs_put() --- sys/include/net/nanocoap_vfs.h | 31 +++++++++++ sys/net/application_layer/nanocoap/vfs.c | 67 +++++++++++++++++++++++- 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/sys/include/net/nanocoap_vfs.h b/sys/include/net/nanocoap_vfs.h index 2ba77fb931..c049c7720e 100644 --- a/sys/include/net/nanocoap_vfs.h +++ b/sys/include/net/nanocoap_vfs.h @@ -51,6 +51,37 @@ int nanocoap_vfs_get_url(const char *url, const char *dst); */ int nanocoap_vfs_get(nanocoap_sock_t *sock, const char *path, const char *dst); +/** + * @brief Uploads the @p file to @p url via blockwise PUT. + * + * @param[in] url URL to the resource + * @param[in] src Path to the source file + * @param[in] work_buf Buffer to read file blocks into + * @param[in] work_buf_len Size of the buffer. Should be 1 byte more + * than the desired CoAP blocksize. + * + * @returns 0 on success + * @returns <0 on error + */ +int nanocoap_vfs_put_url(const char *url, const char *src, + void *work_buf, size_t work_buf_len); + +/** + * @brief Uploads the @p file to @p path via blockwise PUT. + * + * @param[in] sock Connection to the server + * @param[in] path Remote query path to the resource + * @param[in] src Path to the source file + * @param[in] work_buf Buffer to read file blocks into + * @param[in] work_buf_len Size of the buffer. Should be 1 byte more + * than the desired CoAP blocksize. + * + * @returns 0 on success + * @returns <0 on error + */ +int nanocoap_vfs_put(nanocoap_sock_t *sock, const char *path, const char *src, + void *work_buf, size_t work_buf_len); + #ifdef __cplusplus } #endif diff --git a/sys/net/application_layer/nanocoap/vfs.c b/sys/net/application_layer/nanocoap/vfs.c index 3e1f8bfdea..9a1f058bc6 100644 --- a/sys/net/application_layer/nanocoap/vfs.c +++ b/sys/net/application_layer/nanocoap/vfs.c @@ -19,7 +19,7 @@ */ #include -#include "net/nanocoap_sock.h" +#include "net/nanocoap_vfs.h" #include "net/sock/util.h" #include "vfs.h" @@ -92,3 +92,68 @@ int nanocoap_vfs_get_url(const char *url, const char *dst) _2file, &fd); return _finalize_file(fd, res, dst, dst_tmp); } + +static int _vfs_put(coap_block_request_t *ctx, const char *file, void *buffer) +{ + int res, fd = vfs_open(file, O_RDONLY, 0644); + if (fd < 0) { + return fd; + } + + /* buffer is at least one larger than SZX value */ + int buffer_len = coap_szx2size(ctx->blksize) + 1; + + bool more = true; + while (more && (res = vfs_read(fd, buffer, buffer_len)) > 0) { + more = res == buffer_len; + res = nanocoap_sock_block_request(ctx, buffer, + res, more, NULL, NULL); + if (res < 0) { + break; + } + vfs_lseek(fd, -1, SEEK_CUR); + } + + nanocoap_block_request_done(ctx); + + vfs_close(fd); + return res; +} + +int nanocoap_vfs_put(nanocoap_sock_t *sock, const char *path, const char *src, + void *work_buf, size_t work_buf_len) +{ + DEBUG("nanocoap: uploading %s to %s\n", src, path); + + if (work_buf_len < coap_szx2size(0) + 1) { + return -ENOBUFS; + } + + coap_block_request_t ctx = { + .path = path, + .method = COAP_METHOD_PUT, + .blksize = coap_size2szx(work_buf_len - 1), + .sock = *sock, + }; + + return _vfs_put(&ctx, src, work_buf); +} + +int nanocoap_vfs_put_url(const char *url, const char *src, + void *work_buf, size_t work_buf_len) +{ + DEBUG("nanocoap: uploading %s to %s\n", src, url); + + if (work_buf_len < coap_szx2size(0) + 1) { + return -ENOBUFS; + } + + coap_block_request_t ctx; + int res = nanocoap_block_request_init_url(&ctx, url, COAP_METHOD_PUT, + coap_size2szx(work_buf_len - 1)); + if (res) { + return res; + } + + return _vfs_put(&ctx, src, work_buf); +}