1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #20030 from benpicco/nanocoap_fileserver

gcoap_fileserver: rename to nanocoap_fileserver
This commit is contained in:
benpicco 2024-02-01 09:08:49 +00:00 committed by GitHub
commit d00fdcb301
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 146 additions and 122 deletions

View File

@ -21,9 +21,9 @@ USEMODULE += shell_cmds_default
# enable the fileserver module
USEMODULE += gcoap_fileserver
USEMODULE += gcoap_fileserver_callback
USEMODULE += gcoap_fileserver_delete
USEMODULE += gcoap_fileserver_put
USEMODULE += nanocoap_fileserver_callback
USEMODULE += nanocoap_fileserver_delete
USEMODULE += nanocoap_fileserver_put
# select network modules
USEMODULE += gnrc_ipv6_default

View File

@ -20,7 +20,7 @@
#include <stdio.h>
#include "kernel_defines.h"
#include "net/gcoap.h"
#include "net/gcoap/fileserver.h"
#include "net/nanocoap/fileserver.h"
#include "shell.h"
#include "vfs_default.h"
@ -31,14 +31,14 @@ static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
static const coap_resource_t _resources[] = {
{ "/vfs",
COAP_GET |
#if IS_USED(MODULE_GCOAP_FILESERVER_PUT)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_PUT)
COAP_PUT |
#endif
#if IS_USED(MODULE_GCOAP_FILESERVER_DELETE)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_DELETE)
COAP_DELETE |
#endif
COAP_MATCH_SUBTREE,
gcoap_fileserver_handler, VFS_DEFAULT_DATA },
nanocoap_fileserver_handler, VFS_DEFAULT_DATA },
};
static gcoap_listener_t _listener = {
@ -46,22 +46,22 @@ static gcoap_listener_t _listener = {
.resources_len = ARRAY_SIZE(_resources),
};
static void _event_cb(gcoap_fileserver_event_t event, gcoap_fileserver_event_ctx_t *ctx)
static void _event_cb(nanocoap_fileserver_event_t event, nanocoap_fileserver_event_ctx_t *ctx)
{
switch (event) {
case GCOAP_FILESERVER_GET_FILE_START:
case NANOCOAP_FILESERVER_GET_FILE_START:
printf("gcoap fileserver: Download started: %s\n", ctx->path);
break;
case GCOAP_FILESERVER_GET_FILE_END:
case NANOCOAP_FILESERVER_GET_FILE_END:
printf("gcoap fileserver: Download finished: %s\n", ctx->path);
break;
case GCOAP_FILESERVER_PUT_FILE_START:
case NANOCOAP_FILESERVER_PUT_FILE_START:
printf("gcoap fileserver: Upload started: %s\n", ctx->path);
break;
case GCOAP_FILESERVER_PUT_FILE_END:
case NANOCOAP_FILESERVER_PUT_FILE_END:
printf("gcoap fileserver: Upload finished: %s\n", ctx->path);
break;
case GCOAP_FILESERVER_DELETE_FILE:
case NANOCOAP_FILESERVER_DELETE_FILE:
printf("gcoap fileserver: Delete %s\n", ctx->path);
break;
}
@ -72,8 +72,8 @@ int main(void)
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
gcoap_register_listener(&_listener);
if (IS_USED(MODULE_GCOAP_FILESERVER_CALLBACK)) {
gcoap_fileserver_set_event_cb(_event_cb, NULL);
if (IS_USED(MODULE_NANOCOAP_FILESERVER_CALLBACK)) {
nanocoap_fileserver_set_event_cb(_event_cb, NULL);
}
char line_buf[SHELL_DEFAULT_BUFSIZE];

View File

@ -47,13 +47,9 @@ endif
HIGH_MEMORY_BOARDS := native same54-xpro mcb2388
ifneq (,$(filter $(BOARD),$(HIGH_MEMORY_BOARDS)))
USEMODULE += gcoap_fileserver
USEMODULE += nanocoap_fileserver
USEMODULE += vfs_default
# we don't want to run GCoAP
CFLAGS += -DCONFIG_GCOAP_NO_AUTO_INIT=1
CFLAGS += -DCONFIG_NANOCOAP_SERVER_WELL_KNOWN_CORE=1
# always enable auto-format for native
ifeq ($(BOARD),native)
USEMODULE += vfs_auto_format

View File

@ -183,21 +183,21 @@ NANOCOAP_RESOURCE(sha256) {
};
/* we can also include the fileserver module */
#ifdef MODULE_GCOAP_FILESERVER
#include "net/gcoap/fileserver.h"
#ifdef MODULE_NANOCOAP_FILESERVER
#include "net/nanocoap/fileserver.h"
#include "vfs_default.h"
NANOCOAP_RESOURCE(fileserver) {
.path = "/vfs",
.methods = COAP_GET
#if IS_USED(MODULE_GCOAP_FILESERVER_PUT)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_PUT)
| COAP_PUT
#endif
#if IS_USED(MODULE_GCOAP_FILESERVER_DELETE)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_DELETE)
| COAP_DELETE
#endif
| COAP_MATCH_SUBTREE,
.handler = gcoap_fileserver_handler,
.handler = nanocoap_fileserver_handler,
.context = VFS_DEFAULT_DATA
};
#endif

View File

@ -70,9 +70,6 @@ PSEUDOMODULES += fatfs_vfs_format
PSEUDOMODULES += fmt_%
PSEUDOMODULES += gcoap_forward_proxy
PSEUDOMODULES += gcoap_fileserver
PSEUDOMODULES += gcoap_fileserver_callback
PSEUDOMODULES += gcoap_fileserver_delete
PSEUDOMODULES += gcoap_fileserver_put
PSEUDOMODULES += gcoap_dtls
## @addtogroup net_gcoap_dns
## @{
@ -341,6 +338,9 @@ PSEUDOMODULES += md5sum
## @}
PSEUDOMODULES += mtd_write_page
PSEUDOMODULES += nanocoap_%
PSEUDOMODULES += nanocoap_fileserver_callback
PSEUDOMODULES += nanocoap_fileserver_delete
PSEUDOMODULES += nanocoap_fileserver_put
PSEUDOMODULES += netdev_default
PSEUDOMODULES += netdev_ieee802154_%
PSEUDOMODULES += netdev_ieee802154_rx_timestamp

View File

@ -472,17 +472,21 @@ endif
ifneq (,$(filter gcoap_fileserver,$(USEMODULE)))
USEMODULE += gcoap
USEMODULE += nanocoap_fileserver
endif
ifneq (,$(filter nanocoap_fileserver,$(USEMODULE)))
USEMODULE += checksum
USEMODULE += vfs
endif
ifneq (,$(filter gcoap_fileserver_delete,$(USEMODULE)))
USEMODULE += gcoap_fileserver
ifneq (,$(filter nanocoap_fileserver_delete,$(USEMODULE)))
USEMODULE += nanocoap_fileserver
USEMODULE += vfs_util
endif
ifneq (,$(filter gcoap_fileserver_put,$(USEMODULE)))
USEMODULE += gcoap_fileserver
ifneq (,$(filter nanocoap_fileserver_put,$(USEMODULE)))
USEMODULE += nanocoap_fileserver
endif
ifneq (,$(filter gcoap_forward_proxy,$(USEMODULE)))

View File

@ -7,8 +7,8 @@
*/
/**
* @defgroup net_gcoap_fileserver GCoAP file server
* @ingroup net_gcoap
* @defgroup net_nanocoap_fileserver CoAP file server
* @ingroup net_nanocoap
* @brief Library for serving files from the VFS to CoAP clients
*
* # About
@ -41,9 +41,9 @@
*
* # Usage
*
* * ``USEMODULE += gcoap_fileserver``
* * ``USEMODULE += nanocoap_fileserver``
*
* * Enter a @ref gcoap_fileserver_handler handler into your CoAP server's
* * Enter a @ref nanocoap_fileserver_handler handler into your CoAP server's
* resource list like this:
*
* ```
@ -52,7 +52,7 @@
* {
* .path = "/files/sd",
* .methods = COAP_GET | COAP_MATCH_SUBTREE,
* .handler = gcoap_fileserver_handler,
* .handler = nanocoap_fileserver_handler,
* .context = "/sd0"
* },
* ...
@ -65,7 +65,7 @@
* The allowed methods dictate whether it's read-only (``COAP_GET``) or
* read-write (``COAP_GET | COAP_PUT | COAP_DELETE``).
* If you want to support ``PUT`` and `DELETE`, you need to enable the modules
* ``gcoap_fileserver_put`` and ``gcoap_fileserver_delete``.
* ``nanocoap_fileserver_put`` and ``nanocoap_fileserver_delete``.
*
* @{
*
@ -75,8 +75,8 @@
* @author chrysn <chrysn@fsfe.org>
*/
#ifndef NET_GCOAP_FILESERVER_H
#define NET_GCOAP_FILESERVER_H
#ifndef NET_NANOCOAP_FILESERVER_H
#define NET_NANOCOAP_FILESERVER_H
#ifdef __cplusplus
extern "C" {
@ -93,16 +93,16 @@ extern "C" {
/**
* @brief GCoAP fileserver event types
*
* @note This requires the gcoap_fileserver_callback module.
* @note This requires the nanocoap_fileserver_callback module.
*/
typedef enum {
GCOAP_FILESERVER_GET_FILE_START, /**< file download started */
GCOAP_FILESERVER_GET_FILE_END, /**< file download finished */
GCOAP_FILESERVER_PUT_FILE_START, /**< file upload started */
GCOAP_FILESERVER_PUT_FILE_END, /**< file upload finished */
GCOAP_FILESERVER_DELETE_FILE, /**< file deletion requested
NANOCOAP_FILESERVER_GET_FILE_START, /**< file download started */
NANOCOAP_FILESERVER_GET_FILE_END, /**< file download finished */
NANOCOAP_FILESERVER_PUT_FILE_START, /**< file upload started */
NANOCOAP_FILESERVER_PUT_FILE_END, /**< file upload finished */
NANOCOAP_FILESERVER_DELETE_FILE, /**< file deletion requested
(called before file is deleted) */
} gcoap_fileserver_event_t;
} nanocoap_fileserver_event_t;
/**
* @brief GCoAP fileserver event context
@ -110,7 +110,7 @@ typedef enum {
typedef struct {
const char *path; /**< VFS path of the affected file */
void *user_ctx; /**< Optional user supplied context */
} gcoap_fileserver_event_ctx_t;
} nanocoap_fileserver_event_ctx_t;
/**
* @brief GCoAP fileserver event callback type
@ -119,12 +119,12 @@ typedef struct {
* @param[in] ctx Event context information
*
*/
typedef void (*gcoap_fileserver_event_handler_t)(gcoap_fileserver_event_t event,
gcoap_fileserver_event_ctx_t *ctx);
typedef void (*nanocoap_fileserver_event_handler_t)(nanocoap_fileserver_event_t event,
nanocoap_fileserver_event_ctx_t *ctx);
/**
* @brief Register a consumer for GCoAP fileserver events
* Requires the `gcoap_fileserver_callback` module
* Requires the `nanocoap_fileserver_callback` module
*
* The Callback is called on each fileserver event and executed
* within the GCoAP thread.
@ -133,13 +133,13 @@ typedef void (*gcoap_fileserver_event_handler_t)(gcoap_fileserver_event_t event,
* @param[in] arg Custom callback function context
*
*/
void gcoap_fileserver_set_event_cb(gcoap_fileserver_event_handler_t cb, void *arg);
void nanocoap_fileserver_set_event_cb(nanocoap_fileserver_event_handler_t cb, void *arg);
/**
* @brief File server handler
*
* Serve a directory from the VFS as a CoAP resource tree.
* @see net_gcoap_fileserver
* @see net_nanocoap_fileserver
*
* @param[in] pdu CoAP request package
* @param[out] buf Buffer for the response
@ -149,12 +149,13 @@ void gcoap_fileserver_set_event_cb(gcoap_fileserver_event_handler_t cb, void *ar
* @return size of the response on success
* negative error
*/
ssize_t gcoap_fileserver_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx);
ssize_t nanocoap_fileserver_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len,
coap_request_ctx_t *ctx);
#ifdef __cplusplus
}
#endif
#endif /* NET_GCOAP_FILESERVER_H */
#endif /* NET_NANOCOAP_FILESERVER_H */
/** @} */

View File

@ -23,8 +23,7 @@
#include "kernel_defines.h"
#include "checksum/fletcher32.h"
#include "net/gcoap/fileserver.h"
#include "net/gcoap.h"
#include "net/nanocoap/fileserver.h"
#include "vfs.h"
#include "vfs_util.h"
@ -35,12 +34,12 @@
#define COAPFILESERVER_PATH_MAX (64)
/**
* @brief fileserver event callback, only used with `gcoap_fileserver_callback`
* @brief fileserver event callback, only used with `nanocoap_fileserver_callback`
*/
static gcoap_fileserver_event_handler_t _event_cb;
static nanocoap_fileserver_event_handler_t _event_cb;
/**
* @brief fileserver event callback context, only used with `gcoap_fileserver_callback`
* @brief fileserver event callback context, only used with `nanocoap_fileserver_callback`
*/
static void *_event_ctx;
@ -111,6 +110,22 @@ static unsigned _count_char(const char *s, char c)
return count;
}
static int _resp_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code)
{
int header_len = coap_build_reply(pdu, code, buf, len, 0);
/* request contained no-response option or not enough space for response */
if (header_len <= 0) {
return -1;
}
pdu->options_len = 0;
pdu->payload = buf + header_len;
pdu->payload_len = len - header_len;
return 0;
}
/** Build an ETag based on the given file's VFS stat. If the stat fails,
* returns the error and leaves etag in any state; otherwise there's an etag
* in the stattag's field */
@ -129,7 +144,7 @@ static void stat_etag(struct stat *stat, uint32_t *etag)
/** Create a CoAP response for a given errno (eg. EACCESS -> 4.03 Forbidden
* etc., defaulting to 5.03 Internal Server Error), or interpret a positive
* value for err as a CoAP response code */
static size_t gcoap_fileserver_error_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, int err)
static size_t _error_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, int err)
{
uint8_t code = err;
if (err < 0) {
@ -143,10 +158,14 @@ static size_t gcoap_fileserver_error_handler(coap_pkt_t *pdu, uint8_t *buf, size
default:
code = COAP_CODE_INTERNAL_SERVER_ERROR;
};
DEBUG("gcoap_fileserver: Rejecting error %d (%s) as %d.%02d\n", err, strerror(err),
DEBUG("nanocoap_fileserver: Rejecting error %d (%s) as %d.%02d\n", err, strerror(err),
code >> 5, code & 0x1f);
}
return gcoap_response(pdu, buf, len, code);
if (_resp_init(pdu, buf, len, code)) {
return -1;
}
return coap_opt_finish(pdu, COAP_OPT_FINISH_NONE);
}
static void _calc_szx2(coap_pkt_t *pdu, size_t reserve, coap_block1_t *block2)
@ -161,19 +180,19 @@ static void _calc_szx2(coap_pkt_t *pdu, size_t reserve, coap_block1_t *block2)
}
}
static inline void _event_file(gcoap_fileserver_event_t event, struct requestdata *request)
static inline void _event_file(nanocoap_fileserver_event_t event, struct requestdata *request)
{
if (!IS_USED(MODULE_GCOAP_FILESERVER_CALLBACK)) {
if (!IS_USED(MODULE_NANOCOAP_FILESERVER_CALLBACK)) {
return;
}
mutex_lock(&_event_mtx);
gcoap_fileserver_event_ctx_t ctx = {
nanocoap_fileserver_event_ctx_t ctx = {
.path = request->namebuf,
.user_ctx = _event_ctx,
};
gcoap_fileserver_event_handler_t cb = _event_cb;
nanocoap_fileserver_event_handler_t cb = _event_cb;
mutex_unlock(&_event_mtx);
if (cb) {
@ -190,30 +209,30 @@ static ssize_t _get_file(coap_pkt_t *pdu, uint8_t *buf, size_t len,
{
struct stat stat;
if ((err = vfs_stat(request->namebuf, &stat)) < 0) {
return gcoap_fileserver_error_handler(pdu, buf, len, err);
return _error_handler(pdu, buf, len, err);
}
stat_etag(&stat, &etag);
}
if (request->options.exists.block2 && !coap_get_block2(pdu, &block2)) {
return gcoap_fileserver_error_handler(pdu, buf, len, COAP_CODE_BAD_OPTION);
return _error_handler(pdu, buf, len, COAP_CODE_BAD_OPTION);
}
if (request->options.exists.if_match &&
memcmp(&etag, &request->options.if_match, request->options.if_match_len)) {
return gcoap_fileserver_error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
return _error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
}
if (request->options.exists.etag &&
!memcmp(&etag, &request->options.etag, sizeof(etag))) {
gcoap_resp_init(pdu, buf, len, COAP_CODE_VALID);
_resp_init(pdu, buf, len, COAP_CODE_VALID);
coap_opt_add_opaque(pdu, COAP_OPT_ETAG, &etag, sizeof(etag));
return coap_opt_finish(pdu, COAP_OPT_FINISH_NONE);
}
int fd = vfs_open(request->namebuf, O_RDONLY, 0);
if (fd < 0) {
return gcoap_fileserver_error_handler(pdu, buf, len, fd);
return _error_handler(pdu, buf, len, fd);
}
gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT);
_resp_init(pdu, buf, len, COAP_CODE_CONTENT);
coap_opt_add_opaque(pdu, COAP_OPT_ETAG, &etag, sizeof(etag));
coap_block_slicer_t slicer;
_calc_szx2(pdu,
@ -229,7 +248,7 @@ static ssize_t _get_file(coap_pkt_t *pdu, uint8_t *buf, size_t len,
}
if (block2.blknum == 0) {
_event_file(GCOAP_FILESERVER_GET_FILE_START, request);
_event_file(NANOCOAP_FILESERVER_GET_FILE_START, request);
}
/* That'd only happen if the buffer is too small for even a 16-byte block,
@ -258,7 +277,7 @@ static ssize_t _get_file(coap_pkt_t *pdu, uint8_t *buf, size_t len,
}
if (!more) {
_event_file(GCOAP_FILESERVER_GET_FILE_END, request);
_event_file(NANOCOAP_FILESERVER_GET_FILE_END, request);
}
return resp_len + read;
@ -269,7 +288,7 @@ late_err:
return coap_get_total_hdr_len(pdu);
}
#if IS_USED(MODULE_GCOAP_FILESERVER_PUT)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_PUT)
static ssize_t _put_file(coap_pkt_t *pdu, uint8_t *buf, size_t len,
struct requestdata *request)
{
@ -283,7 +302,7 @@ static ssize_t _put_file(coap_pkt_t *pdu, uint8_t *buf, size_t len,
we save the partial content in '.f' and rename it afterwards */
if (!(ret = strlen(request->namebuf)) || (unsigned)ret >= sizeof(request->namebuf) - 1) {
/* need one more char '.' */
return gcoap_fileserver_error_handler(pdu, buf, len, -ENOBUFS);
return _error_handler(pdu, buf, len, -ENOBUFS);
}
char *file = strrchr(request->namebuf, '/');
memmove(file + 2, file + 1, strlen(file + 1));
@ -301,7 +320,7 @@ static ssize_t _put_file(coap_pkt_t *pdu, uint8_t *buf, size_t len,
goto unlink_on_error;
}
_event_file(GCOAP_FILESERVER_PUT_FILE_START, request);
_event_file(NANOCOAP_FILESERVER_PUT_FILE_START, request);
}
if (request->options.exists.if_match) {
stat_etag(&stat, &etag); /* Etag before write */
@ -362,14 +381,14 @@ static ssize_t _put_file(coap_pkt_t *pdu, uint8_t *buf, size_t len,
}
}
_event_file(GCOAP_FILESERVER_PUT_FILE_END, request);
_event_file(NANOCOAP_FILESERVER_PUT_FILE_END, request);
stat_etag(&stat, &etag); /* Etag after write */
gcoap_resp_init(pdu, buf, len, create ? COAP_CODE_CREATED : COAP_CODE_CHANGED);
_resp_init(pdu, buf, len, create ? COAP_CODE_CREATED : COAP_CODE_CHANGED);
coap_opt_add_opaque(pdu, COAP_OPT_ETAG, &etag, sizeof(etag));
}
else {
gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTINUE);
_resp_init(pdu, buf, len, COAP_CODE_CONTINUE);
block1.more = true; /* resource is created atomically */
coap_opt_add_block1_control(pdu, &block1);
}
@ -381,11 +400,11 @@ unlink_on_error:
if (create) {
vfs_unlink(request->namebuf);
}
return gcoap_fileserver_error_handler(pdu, buf, len, ret);
return _error_handler(pdu, buf, len, ret);
}
#endif
#if IS_USED(MODULE_GCOAP_FILESERVER_DELETE)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_DELETE)
static ssize_t _delete_file(coap_pkt_t *pdu, uint8_t *buf, size_t len,
struct requestdata *request)
{
@ -393,41 +412,41 @@ static ssize_t _delete_file(coap_pkt_t *pdu, uint8_t *buf, size_t len,
uint32_t etag;
struct stat stat;
if ((ret = vfs_stat(request->namebuf, &stat)) < 0) {
return gcoap_fileserver_error_handler(pdu, buf, len, ret);
return _error_handler(pdu, buf, len, ret);
}
if (request->options.exists.if_match && request->options.if_match_len) {
stat_etag(&stat, &etag);
if (memcmp(&etag, &request->options.if_match, request->options.if_match_len)) {
return gcoap_fileserver_error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
return _error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
}
}
_event_file(GCOAP_FILESERVER_DELETE_FILE, request);
_event_file(NANOCOAP_FILESERVER_DELETE_FILE, request);
if ((ret = vfs_unlink(request->namebuf)) < 0) {
return gcoap_fileserver_error_handler(pdu, buf, len, ret);
return _error_handler(pdu, buf, len, ret);
}
gcoap_resp_init(pdu, buf, len, COAP_CODE_DELETED);
_resp_init(pdu, buf, len, COAP_CODE_DELETED);
return coap_opt_finish(pdu, COAP_OPT_FINISH_NONE);
}
#endif
static ssize_t gcoap_fileserver_file_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len,
static ssize_t nanocoap_fileserver_file_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len,
struct requestdata *request)
{
switch (coap_get_code_raw(pdu)) {
case COAP_METHOD_GET:
return _get_file(pdu, buf, len, request);
#if IS_USED(MODULE_GCOAP_FILESERVER_PUT)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_PUT)
case COAP_METHOD_PUT:
return _put_file(pdu, buf, len, request);
#endif
#if IS_USED(MODULE_GCOAP_FILESERVER_DELETE)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_DELETE)
case COAP_METHOD_DELETE:
return _delete_file(pdu, buf, len, request);
#endif
default:
return gcoap_fileserver_error_handler(pdu, buf, len, COAP_CODE_METHOD_NOT_ALLOWED);
return _error_handler(pdu, buf, len, COAP_CODE_METHOD_NOT_ALLOWED);
}
}
@ -440,17 +459,17 @@ static ssize_t _get_directory(coap_pkt_t *pdu, uint8_t *buf, size_t len,
coap_block_slicer_t slicer;
coap_block1_t block2 = { .szx = CONFIG_NANOCOAP_BLOCK_SIZE_EXP_MAX };
if (request->options.exists.block2 && !coap_get_block2(pdu, &block2)) {
return gcoap_fileserver_error_handler(pdu, buf, len, COAP_OPT_FINISH_NONE);
return _error_handler(pdu, buf, len, COAP_OPT_FINISH_NONE);
}
if ((err = vfs_opendir(&dir, request->namebuf)) < 0) {
return gcoap_fileserver_error_handler(pdu, buf, len, err);
return _error_handler(pdu, buf, len, err);
}
if (request->options.exists.if_match && request->options.if_match_len) {
return gcoap_fileserver_error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
return _error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
}
DEBUG("gcoap_fileserver: Serving directory listing\n");
DEBUG("nanocoap_fileserver: Serving directory listing\n");
gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT);
_resp_init(pdu, buf, len, COAP_CODE_CONTENT);
coap_opt_add_format(pdu, COAP_FORMAT_LINK);
_calc_szx2(pdu,
5 + 1 /* reserve BLOCK2 size + payload marker */,
@ -494,7 +513,7 @@ static ssize_t _get_directory(coap_pkt_t *pdu, uint8_t *buf, size_t len,
return (uintptr_t)buf - (uintptr_t)pdu->hdr;
}
#if IS_USED(MODULE_GCOAP_FILESERVER_PUT)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_PUT)
static ssize_t _put_directory(coap_pkt_t *pdu, uint8_t *buf, size_t len,
struct requestdata *request)
{
@ -503,69 +522,69 @@ static ssize_t _put_directory(coap_pkt_t *pdu, uint8_t *buf, size_t len,
if ((err = vfs_opendir(&dir, request->namebuf)) == 0) {
vfs_closedir(&dir);
if (request->options.exists.if_match && request->options.if_match_len) {
return gcoap_fileserver_error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
return _error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
}
gcoap_resp_init(pdu, buf, len, COAP_CODE_CHANGED);
_resp_init(pdu, buf, len, COAP_CODE_CHANGED);
}
else {
if (request->options.exists.if_match) {
return gcoap_fileserver_error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
return _error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
}
if ((err = vfs_mkdir(request->namebuf, 0777)) < 0) {
return gcoap_fileserver_error_handler(pdu, buf, len, err);
return _error_handler(pdu, buf, len, err);
}
gcoap_resp_init(pdu, buf, len, COAP_CODE_CREATED);
_resp_init(pdu, buf, len, COAP_CODE_CREATED);
}
return coap_opt_finish(pdu, COAP_OPT_FINISH_NONE);
}
#endif
#if IS_USED(MODULE_GCOAP_FILESERVER_DELETE)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_DELETE)
static ssize_t _delete_directory(coap_pkt_t *pdu, uint8_t *buf, size_t len,
struct requestdata *request)
{
int err;
if (request->options.exists.if_match && request->options.if_match_len) {
if (request->options.if_match != byteorder_htonl(COAPFILESERVER_DIR_DELETE_ETAG).u32) {
return gcoap_fileserver_error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
return _error_handler(pdu, buf, len, COAP_CODE_PRECONDITION_FAILED);
}
if ((err = vfs_rmdir(request->namebuf)) < 0) {
return gcoap_fileserver_error_handler(pdu, buf, len, err);
return _error_handler(pdu, buf, len, err);
}
}
else if (IS_USED(MODULE_VFS_UTIL)) {
if ((err = vfs_unlink_recursive(request->namebuf,
request->namebuf,
sizeof(request->namebuf))) < 0) {
return gcoap_fileserver_error_handler(pdu, buf, len, err);
return _error_handler(pdu, buf, len, err);
}
}
gcoap_resp_init(pdu, buf, len, COAP_CODE_DELETED);
_resp_init(pdu, buf, len, COAP_CODE_DELETED);
return coap_opt_finish(pdu, COAP_OPT_FINISH_NONE);
}
#endif
static ssize_t gcoap_fileserver_directory_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len,
static ssize_t nanocoap_fileserver_directory_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len,
struct requestdata *request,
const char *root, const char* resource_dir)
{
switch (coap_get_code_raw(pdu)) {
case COAP_METHOD_GET:
return _get_directory(pdu, buf, len, request, root, resource_dir);
#if IS_USED(MODULE_GCOAP_FILESERVER_PUT)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_PUT)
case COAP_METHOD_PUT:
return _put_directory(pdu, buf, len, request);
#endif
#if IS_USED(MODULE_GCOAP_FILESERVER_DELETE)
#if IS_USED(MODULE_NANOCOAP_FILESERVER_DELETE)
case COAP_METHOD_DELETE:
return _delete_directory(pdu, buf, len, request);
#endif
default:
return gcoap_fileserver_error_handler(pdu, buf, len, COAP_CODE_METHOD_NOT_ALLOWED);
return _error_handler(pdu, buf, len, COAP_CODE_METHOD_NOT_ALLOWED);
}
}
ssize_t gcoap_fileserver_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len,
ssize_t nanocoap_fileserver_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len,
coap_request_ctx_t *ctx) {
const char *root = coap_request_ctx_get_context(ctx);
const char *resource = coap_request_ctx_get_path(ctx);
@ -695,14 +714,18 @@ ssize_t gcoap_fileserver_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len,
* pass a struct pointer later. So far, those could even be hooked into the
* resource list, but that'll go away once we parse more options */
return is_directory
? gcoap_fileserver_directory_handler(pdu, buf, len, &request, root, resource)
: gcoap_fileserver_file_handler(pdu, buf, len, &request);
? nanocoap_fileserver_directory_handler(pdu, buf, len, &request, root, resource)
: nanocoap_fileserver_file_handler(pdu, buf, len, &request);
error:
return gcoap_response(pdu, buf, len, errorcode);
if (_resp_init(pdu, buf, len, errorcode)) {
return -1;
}
coap_opt_finish(pdu, COAP_OPT_FINISH_NONE);
return 0;
}
#ifdef MODULE_GCOAP_FILESERVER_CALLBACK
void gcoap_fileserver_set_event_cb(gcoap_fileserver_event_handler_t cb, void *ctx)
#ifdef MODULE_NANOCOAP_FILESERVER_CALLBACK
void nanocoap_fileserver_set_event_cb(nanocoap_fileserver_event_handler_t cb, void *ctx)
{
mutex_lock(&_event_mtx);

View File

@ -10,7 +10,7 @@ USEMODULE += shell
USEMODULE += shell_cmds_default
USEMODULE += gcoap_fileserver
USEMODULE += gcoap_fileserver_put
USEMODULE += nanocoap_fileserver_put
USEMODULE += nanocoap_vfs

View File

@ -19,7 +19,7 @@
#include "fs/constfs.h"
#include "net/gcoap.h"
#include "net/gcoap/fileserver.h"
#include "net/nanocoap/fileserver.h"
#include "shell.h"
#include "vfs_default.h"
@ -31,13 +31,13 @@ static const coap_resource_t _resources[] = {
{
.path = "/const",
.methods = COAP_GET | COAP_MATCH_SUBTREE,
.handler = gcoap_fileserver_handler,
.handler = nanocoap_fileserver_handler,
.context = "/const"
},
{
.path = "/vfs",
.methods = COAP_GET | COAP_PUT | COAP_MATCH_SUBTREE,
.handler = gcoap_fileserver_handler,
.handler = nanocoap_fileserver_handler,
.context = VFS_DEFAULT_DATA
},
};