Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nanocoap: define and use coap_request_ctx_t for request handlers #17957

Merged
merged 8 commits into from
Jul 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/cord_ep/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static void _on_ep_event(cord_ep_standalone_event_t event)

/* define some dummy CoAP resources */
static ssize_t _handler_dummy(coap_pkt_t *pdu,
uint8_t *buf, size_t len, void *ctx)
uint8_t *buf, size_t len, coap_request_ctx_t *ctx)
{
(void)ctx;

Expand All @@ -64,7 +64,7 @@ static ssize_t _handler_dummy(coap_pkt_t *pdu,
}

static ssize_t _handler_info(coap_pkt_t *pdu,
uint8_t *buf, size_t len, void *ctx)
uint8_t *buf, size_t len, coap_request_ctx_t *ctx)
{
(void)ctx;

Expand Down
6 changes: 3 additions & 3 deletions examples/cord_epsim/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ static ssize_t text_resp(coap_pkt_t *pdu, uint8_t *buf, size_t len,
return resp_len + slen;
}

static ssize_t handler_info(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx)
static ssize_t handler_info(coap_pkt_t *pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx)
{
(void)ctx;
return text_resp(pdu, buf, len, riot_info, COAP_FORMAT_JSON);
}

static ssize_t handler_text(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx)
static ssize_t handler_text(coap_pkt_t *pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx)
{
return text_resp(pdu, buf, len, (char *)ctx, COAP_FORMAT_TEXT);
return text_resp(pdu, buf, len, coap_request_ctx_get_context(ctx), COAP_FORMAT_TEXT);
}

static const coap_resource_t resources[] = {
Expand Down
8 changes: 4 additions & 4 deletions examples/gcoap/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ static const credman_credential_t credential = {

static ssize_t _encode_link(const coap_resource_t *resource, char *buf,
size_t maxlen, coap_link_encoder_ctx_t *context);
static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx);
static ssize_t _riot_board_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx);
static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx);
static ssize_t _riot_board_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx);

/* CoAP resources. Must be sorted by path (ASCII order). */
static const coap_resource_t _resources[] = {
Expand Down Expand Up @@ -108,7 +108,7 @@ static ssize_t _encode_link(const coap_resource_t *resource, char *buf,
* allows any two byte value for example purposes. Semantically, the only
* valid action is to set the value to 0.
*/
static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx)
static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx)
{
(void)ctx;

Expand Down Expand Up @@ -142,7 +142,7 @@ static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *c
return 0;
}

static ssize_t _riot_board_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx)
static ssize_t _riot_board_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx)
{
(void)ctx;
gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT);
Expand Down
8 changes: 4 additions & 4 deletions examples/gcoap_block_server/gcoap_block.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
#define ENABLE_DEBUG (0)
#include "debug.h"

static ssize_t _sha256_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx);
static ssize_t _riot_block2_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx);
static ssize_t _sha256_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx);
static ssize_t _riot_block2_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx);

/* CoAP resources */
static const coap_resource_t _resources[] = {
Expand All @@ -47,7 +47,7 @@ static const uint8_t block2_intro[] = "This is RIOT (Version: ";
static const uint8_t block2_board[] = " running on a ";
static const uint8_t block2_mcu[] = " board with a ";

static ssize_t _riot_block2_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx)
static ssize_t _riot_block2_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx)
{
(void)ctx;
coap_block_slicer_t slicer;
Expand Down Expand Up @@ -80,7 +80,7 @@ static ssize_t _riot_block2_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, v

/*
* Uses block1 POSTs to generate an sha256 digest. */
static ssize_t _sha256_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx)
static ssize_t _sha256_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx)
{
(void)ctx;

Expand Down
7 changes: 1 addition & 6 deletions examples/gcoap_fileserver/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,9 @@
#define MAIN_QUEUE_SIZE (4)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];

static const gcoap_fileserver_entry_t _vfs_entry = {
.root = VFS_DEFAULT_DATA,
.resource = "/vfs",
};

/* CoAP resources. Must be sorted by path (ASCII order). */
static const coap_resource_t _resources[] = {
{ "/vfs", COAP_GET | COAP_MATCH_SUBTREE, gcoap_fileserver_handler, (void *)&_vfs_entry },
{ "/vfs", COAP_GET | COAP_MATCH_SUBTREE, gcoap_fileserver_handler, VFS_DEFAULT_DATA },
};

static gcoap_listener_t _listener = {
Expand Down
10 changes: 5 additions & 5 deletions examples/nanocoap_server/coap_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ static const uint8_t block2_intro[] = "This is RIOT (Version: ";
static const uint8_t block2_board[] = " running on a ";
static const uint8_t block2_mcu[] = " board with a ";

static ssize_t _echo_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context)
static ssize_t _echo_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, coap_request_ctx_t *context)
{
(void)context;
char uri[CONFIG_NANOCOAP_URI_MAX];
Expand All @@ -37,14 +37,14 @@ static ssize_t _echo_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *co
(uint8_t *)sub_uri, sub_uri_len);
}

static ssize_t _riot_board_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context)
static ssize_t _riot_board_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, coap_request_ctx_t *context)
{
(void)context;
return coap_reply_simple(pkt, COAP_CODE_205, buf, len,
COAP_FORMAT_TEXT, (uint8_t*)RIOT_BOARD, strlen(RIOT_BOARD));
}

static ssize_t _riot_block2_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context)
static ssize_t _riot_block2_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, coap_request_ctx_t *context)
{
(void)context;
coap_block_slicer_t slicer;
Expand Down Expand Up @@ -77,7 +77,7 @@ static ssize_t _riot_block2_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, v
buf, len, payload_len, &slicer);
}

static ssize_t _riot_value_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context)
static ssize_t _riot_value_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, coap_request_ctx_t *context)
{
(void) context;

Expand Down Expand Up @@ -112,7 +112,7 @@ static ssize_t _riot_value_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, vo
COAP_FORMAT_TEXT, (uint8_t*)rsp, p);
}

ssize_t _sha256_handler(coap_pkt_t* pkt, uint8_t *buf, size_t len, void *context)
ssize_t _sha256_handler(coap_pkt_t* pkt, uint8_t *buf, size_t len, coap_request_ctx_t *context)
{
(void)context;

Expand Down
3 changes: 2 additions & 1 deletion examples/suit_update/coap_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
#include "suit/transport/coap.h"
#include "kernel_defines.h"

static ssize_t _riot_board_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context)
static ssize_t _riot_board_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len,
coap_request_ctx_t *context)
{
(void)context;
return coap_reply_simple(pkt, COAP_CODE_205, buf, len,
Expand Down
44 changes: 11 additions & 33 deletions sys/include/net/gcoap/fileserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,25 @@
*
* * ``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 },
* {
* .path = "/files/sd",
* .methods = COAP_GET | COAP_MATCH_SUBTREE,
* .handler = gcoap_fileserver_handler,
* .context = "/sd0"
* },
* ...
* }
* ```
*
* The path argument specifies under which path the folder is served via CoAP while
* the context argument contains the path on the local filesystem that will be served.
*
* The allowed methods dictate whether it's read-only (``COAP_GET``) or (in the
* future<!-- WRITESUPPORT -->) read-write (``COAP_GET | COAP_PUT | COAP_DELETE``).
*
Expand All @@ -77,26 +75,6 @@ extern "C" {

#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
*
Expand All @@ -106,12 +84,12 @@ typedef struct {
* @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
* @param[in] ctx pointer to a @ref coap_request_ctx_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);
ssize_t gcoap_fileserver_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, coap_request_ctx_t *ctx);

#ifdef __cplusplus
}
Expand Down
46 changes: 42 additions & 4 deletions sys/include/net/nanocoap.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,16 @@ typedef struct {
#endif
} coap_pkt_t;

/**
* @brief Forward declaration of internal CoAP resource request handler context
*/
struct _coap_request_ctx;

/**
* @brief CoAP resource request handler context
*/
typedef struct _coap_request_ctx coap_request_ctx_t;

/**
* @brief Resource handler type
*
Expand All @@ -253,8 +263,17 @@ typedef struct {
*
* For POST, PATCH and other non-idempotent methods, this is an additional
* requirement introduced by the contract of this type.
*
* @param[in] pkt The request packet
* @param[out] buf Buffer for the response
* @param[in] len Size of the response buffer
* @param[in] context Request context
*
* @return Number of response bytes written on success
* Negative error on failure
*/
typedef ssize_t (*coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context);
typedef ssize_t (*coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len,
benpicco marked this conversation as resolved.
Show resolved Hide resolved
coap_request_ctx_t *context);

/**
* @brief Coap blockwise request callback descriptor
Expand Down Expand Up @@ -307,6 +326,24 @@ typedef const struct {
const size_t resources_numof; /**< number of entries in array */
} coap_resource_subtree_t;

/**
* @brief Get resource path associated with a CoAP request
*
* @param[in] ctx The request context
*
* @return Resource path of the request
*/
const char *coap_request_ctx_get_path(const coap_request_ctx_t *ctx);

/**
* @brief Get resource context associated with a CoAP request
*
* @param[in] ctx The request context
*
* @return Resource context of the request
*/
void *coap_request_ctx_get_context(const coap_request_ctx_t *ctx);

/**
* @brief Block1 helper struct
*/
Expand Down Expand Up @@ -1811,13 +1848,14 @@ ssize_t coap_tree_handler(coap_pkt_t *pkt, uint8_t *resp_buf,
* @param[in] pkt pointer to (parsed) CoAP packet
* @param[out] resp_buf buffer for response
* @param[in] resp_buf_len size of response buffer
* @param[in] context ptr to a @ref coap_resource_subtree_t instance
* @param[in] context pointer to request context, must contain context
* to @ref coap_resource_subtree_t instance
*
* @returns size of the reply packet on success
* @returns <0 on error
*/
ssize_t coap_subtree_handler(coap_pkt_t *pkt, uint8_t *resp_buf,
size_t resp_buf_len, void *context);
size_t resp_buf_len, coap_request_ctx_t *context);
benpicco marked this conversation as resolved.
Show resolved Hide resolved

/**
* @brief Convert message code (request method) into a corresponding bit field
Expand Down Expand Up @@ -1953,7 +1991,7 @@ ssize_t coap_reply_simple(coap_pkt_t *pkt,
*/
extern ssize_t coap_well_known_core_default_handler(coap_pkt_t *pkt, \
uint8_t *buf, size_t len,
void *context);
coap_request_ctx_t *context);
/**@}*/

/**
Expand Down
3 changes: 3 additions & 0 deletions sys/net/application_layer/gcoap/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ SRC := gcoap.c

SUBMODULES := 1

# Since gcoap extends nanocoap, it shall be provided with nanocoap internals
INCLUDES += -I$(RIOTBASE)/sys/net/application_layer/nanocoap

include $(RIOTBASE)/Makefile.base
21 changes: 11 additions & 10 deletions sys/net/application_layer/gcoap/fileserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ static ssize_t gcoap_fileserver_file_handler(coap_pkt_t *pdu, uint8_t *buf, size

static ssize_t gcoap_fileserver_directory_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len,
struct requestdata *request,
gcoap_fileserver_entry_t *resource)
const char *root, const char* resource_dir)
{
vfs_DIR dir;
coap_block_slicer_t slicer;
Expand All @@ -227,9 +227,8 @@ static ssize_t gcoap_fileserver_directory_handler(coap_pkt_t *pdu, uint8_t *buf,
coap_opt_add_block2(pdu, &slicer, true);
buf += coap_opt_finish(pdu, COAP_OPT_FINISH_PAYLOAD);

size_t root_len = resource->root ? strlen(resource->root) : 0;
size_t root_len = root ? strlen(root) : 0;
const char *root_dir = &request->namebuf[root_len];
const char *resource_dir = resource->resource;
size_t root_dir_len = strlen(root_dir);
size_t resource_dir_len = strlen(resource_dir);

Expand Down Expand Up @@ -264,8 +263,10 @@ static ssize_t gcoap_fileserver_directory_handler(coap_pkt_t *pdu, uint8_t *buf,
return (uintptr_t)buf - (uintptr_t)pdu->hdr;
}

ssize_t gcoap_fileserver_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx) {
gcoap_fileserver_entry_t *entry = ctx;
ssize_t gcoap_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);
struct requestdata request = {
.etag_sent = false,
.blocknum2 = 0,
Expand All @@ -276,12 +277,12 @@ ssize_t gcoap_fileserver_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void
* zeroed to get a 0-terminated string. */
size_t namelength = 0;
uint8_t errorcode = COAP_CODE_INTERNAL_SERVER_ERROR;
uint8_t strip_remaining = _count_char(entry->resource, '/');
uint8_t strip_remaining = _count_char(resource, '/');

/* If a root directory for the server was specified, use that */
if (entry->root && strlen(entry->root) > 1) {
strncpy(request.namebuf, entry->root, sizeof(request.namebuf));
namelength = strlen(entry->root);
if (root && strlen(root) > 1) {
strncpy(request.namebuf, root, sizeof(request.namebuf));
namelength = strlen(root);
}

bool is_directory = true; /* either no path component at all or trailing '/' */
Expand Down Expand Up @@ -360,7 +361,7 @@ ssize_t gcoap_fileserver_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void
* 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 */
if (is_directory) {
return gcoap_fileserver_directory_handler(pdu, buf, len, &request, entry);
return gcoap_fileserver_directory_handler(pdu, buf, len, &request, root, resource);
}
else {
return gcoap_fileserver_file_handler(pdu, buf, len, &request);
Expand Down
Loading