mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-25 06:23:53 +01:00
Merge pull request #17962 from benpicco/nanocoap_vfs-put
nanocoap_vfs: add nanocoap_vfs_put()
This commit is contained in:
commit
0a16f8266a
@ -86,6 +86,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef RIOT_VERSION
|
||||
#include "bitarithm.h"
|
||||
#include "bitfield.h"
|
||||
#include "byteorder.h"
|
||||
#include "iolist.h"
|
||||
@ -988,6 +989,19 @@ static inline unsigned coap_szx2size(unsigned szx)
|
||||
{
|
||||
return (1 << (szx + 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper to encode byte size into next equal or smaller SZX value
|
||||
*
|
||||
* @param[in] len Size in bytes
|
||||
*
|
||||
* @returns closest SZX value that fits into a buffer of @p len
|
||||
*/
|
||||
static inline unsigned coap_size2szx(unsigned len)
|
||||
{
|
||||
assert(len >= 16);
|
||||
return bitarithm_msb(len >> 4);
|
||||
}
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
|
||||
@ -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
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ static int _print_dir(const char *url, char *buf, size_t len)
|
||||
static int _nanocoap_get_handler(int argc, char **argv)
|
||||
{
|
||||
int res;
|
||||
char buffer[CONFIG_NANOCOAP_QS_MAX];
|
||||
char buffer[CONFIG_NANOCOAP_URI_MAX];
|
||||
char *dst, *url = argv[1];
|
||||
|
||||
if (argc < 2) {
|
||||
@ -139,4 +139,43 @@ static int _nanocoap_get_handler(int argc, char **argv)
|
||||
return res;
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
if (argc < 3) {
|
||||
printf("Usage: %s <file> <url>\n", argv[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
file = argv[1];
|
||||
url = argv[2];
|
||||
|
||||
if (_is_dir(url)) {
|
||||
const char *basename = strrchr(file, '/');
|
||||
if (basename == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (snprintf(buffer, sizeof(buffer), "%s%s",
|
||||
url, basename + 1) >= (int)sizeof(buffer)) {
|
||||
puts("Constructed URI too long");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
url = buffer;
|
||||
}
|
||||
|
||||
res = nanocoap_vfs_put_url(url, file, work_buf, sizeof(work_buf));
|
||||
if (res < 0) {
|
||||
printf("Upload failed: %s\n", strerror(-res));
|
||||
}
|
||||
else {
|
||||
printf("Saved to %s\n", url);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
SHELL_COMMAND(ncget, "download a file from a CoAP server", _nanocoap_get_handler);
|
||||
SHELL_COMMAND(ncput, "upload a file to a CoAP server", _nanocoap_put_handler);
|
||||
|
||||
@ -27,6 +27,9 @@ ifeq (,$(filter $(BOARD),$(LOW_MEMORY_BOARDS)))
|
||||
# USEMODULE += vfs_auto_format
|
||||
USEMODULE += shell_commands
|
||||
|
||||
# VFS operations require more stack on the main thread
|
||||
CFLAGS += -DTHREAD_STACKSIZE_MAIN=THREAD_STACKSIZE_LARGE
|
||||
|
||||
# always enable auto-format for native
|
||||
ifeq ($(BOARD),native)
|
||||
USEMODULE += vfs_auto_format
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user