Skip to content

Commit

Permalink
gcoap_fileserver: New module to serve VFS via CoAP
Browse files Browse the repository at this point in the history
  • Loading branch information
chrysn authored and benpicco committed May 10, 2022
1 parent 59ec6f1 commit 904ec2b
Show file tree
Hide file tree
Showing 7 changed files with 519 additions and 1 deletion.
1 change: 1 addition & 0 deletions dist/tools/doccheck/exclude_patterns
Original file line number Diff line number Diff line change
Expand Up @@ -14275,6 +14275,7 @@ sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_BLOCK2 \(macro definiti
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_CONTENT_FORMAT \(macro definition\) of group net_coap is not documented\.
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_LOCATION_PATH \(macro definition\) of group net_coap is not documented\.
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_LOCATION_QUERY \(macro definition\) of group net_coap is not documented\.
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_ETAG \(macro definition\) of group net_coap is not documented\.
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_OBSERVE \(macro definition\) of group net_coap is not documented\.
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_PROXY_SCHEME \(macro definition\) of group net_coap is not documented\.
sys/include/net/coap\.h:[0-9]+: warning: Member COAP_OPT_PROXY_URI \(macro definition\) of group net_coap is not documented\.
Expand Down
1 change: 1 addition & 0 deletions makefiles/pseudomodules.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ PSEUDOMODULES += evtimer_on_ztimer
PSEUDOMODULES += fatfs_vfs_format
PSEUDOMODULES += fmt_%
PSEUDOMODULES += gcoap_forward_proxy
PSEUDOMODULES += gcoap_fileserver
PSEUDOMODULES += gcoap_dtls
PSEUDOMODULES += fido2_tests
PSEUDOMODULES += gnrc_dhcpv6_%
Expand Down
6 changes: 6 additions & 0 deletions sys/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,12 @@ ifneq (,$(filter vfs_default,$(USEMODULE)))
DEFAULT_MODULE += vfs_auto_mount
endif

ifneq (,$(filter gcoap_fileserver,$(USEMODULE)))
USEMODULE += gcoap
USEMODULE += checksum
USEMODULE += vfs
endif

ifneq (,$(filter vfs,$(USEMODULE)))
USEMODULE += posix_headers
ifeq (native, $(BOARD))
Expand Down
1 change: 1 addition & 0 deletions sys/include/net/coap.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ extern "C" {
* @{
*/
#define COAP_OPT_URI_HOST (3)
#define COAP_OPT_ETAG (4)
#define COAP_OPT_OBSERVE (6)
#define COAP_OPT_LOCATION_PATH (8)
#define COAP_OPT_URI_PATH (11)
Expand Down
13 changes: 12 additions & 1 deletion sys/include/net/gcoap.h
Original file line number Diff line number Diff line change
Expand Up @@ -626,8 +626,19 @@ extern "C" {
#define GCOAP_DTLS_EXTRA_STACKSIZE (0)
#endif

/**
* @brief Extra stack for VFS operations
*/
#if IS_USED(MODULE_GCOAP_FILESERVER)
#include "vfs.h"
#define GCOAP_VFS_EXTRA_STACKSIZE (VFS_DIR_BUFFER_SIZE + VFS_FILE_BUFFER_SIZE)
#else
#define GCOAP_VFS_EXTRA_STACKSIZE (0)
#endif

#define GCOAP_STACK_SIZE (THREAD_STACKSIZE_DEFAULT + DEBUG_EXTRA_STACKSIZE \
+ sizeof(coap_pkt_t) + GCOAP_DTLS_EXTRA_STACKSIZE)
+ sizeof(coap_pkt_t) + GCOAP_DTLS_EXTRA_STACKSIZE \
+ GCOAP_VFS_EXTRA_STACKSIZE)
#endif
/** @} */

Expand Down
122 changes: 122 additions & 0 deletions sys/include/net/gcoap/fileserver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Copyright (C) 2020 chrysn
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @defgroup net_gcoap_fileserver GCoAP file server
* @ingroup net_gcoap
* @brief Library for serving files from the VFS to CoAP clients
*
* # About
*
* This maps files in the local file system onto a resources in CoAP. In that,
* it is what is called a static web server in the unconstrained web.
*
* As usual, GET operations are used to read files<!-- WRITESUPPORT, and PUT writes to files.
* In the current implementation, PUTs are expressed as random-access, meaning
* that files are not updated atomically -->.
*
* Directories are expressed to URIs with trailing slashes<!-- WRITESUPPORT, and are always
* created implicitly when files are PUT under them; they can be DELETEd when
* empty -->.
*
* @note The file server uses ETag for cache validation. The ETags are built
* from the file system stat values. As clients rely on the ETag to differ when
* the file changes, it is important that file modification times are set. The
* precise time values do not matter, but if a file is changed in place and
* neither its length nor its modification time is varied, then clients will
* not become aware of the change or may even mix up the versions half way
* through if they have a part of the old version cached.
*
* # Usage
*
* * ``USEMODULE += gcoap_fileserver``
*
* * Have a @ref gcoap_fileserver_entry_t populated with the path you want to serve,
* and the number of path components to strip from incoming requests:
*
* ```
* static const gcoap_fileserver_entry_t files_sd = {
* .root = "/sd0",
* .resource = "/files/sd"
* };
* ```
*
* * Enter a @ref gcoap_fileserver_handler handler into your CoAP server's
* resource list like this:
*
* ```
* static const coap_resource_t _resources[] = {
* ...
* { "/files/sd", COAP_GET | COAP_MATCH_SUBTREE, gcoap_fileserver_handler, (void*)&files_sd },
* ...
* }
* ```
*
* The allowed methods dictate whether it's read-only (``COAP_GET``) or (in the
* future<!-- WRITESUPPORT -->) read-write (``COAP_GET | COAP_PUT | COAP_DELETE``).
*
* @{
*
* @file
* @brief Resource handler for the CoAP file system server
*
* @author chrysn <[email protected]>
*/

#ifndef NET_GCOAP_FILESERVER_H
#define NET_GCOAP_FILESERVER_H

#ifdef __cplusplus
extern "C" {
#endif

#include "net/nanocoap.h"

/**
* @brief File server starting point
*
* This struct needs to be present at the ctx of a gcoap_fileserver_handler entry
* in a resource list.
*
*/
typedef struct {
/**
* @brief Path in the VFS that should be served.
*
* This does not need a trailing slash.
*/
const char *root;
/**
* @brief The associated CoAP resource path
*/
const char *resource;
} gcoap_fileserver_entry_t;

/**
* @brief File server handler
*
* Serve a directory from the VFS as a CoAP resource tree.
* @see net_gcoap_fileserver
*
* @param[in] pdu CoAP request package
* @param[out] buf Buffer for the response
* @param[in] len Response buffer length
* @param[in] ctx pointer to a @ref gcoap_fileserver_entry_t
*
* @return size of the response on success
* negative error
*/
ssize_t gcoap_fileserver_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx);

#ifdef __cplusplus
}
#endif

#endif /* NET_GCOAP_FILESERVER_H */

/** @} */
Loading

0 comments on commit 904ec2b

Please sign in to comment.