diff --git a/sys/include/net/nanocoap.h b/sys/include/net/nanocoap.h index c782ea2345..fc857ad05c 100644 --- a/sys/include/net/nanocoap.h +++ b/sys/include/net/nanocoap.h @@ -239,11 +239,6 @@ typedef struct { /** * @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; /** @@ -322,6 +317,32 @@ typedef const struct { const size_t resources_numof; /**< number of entries in array */ } coap_resource_subtree_t; +/** + * @brief Initialize CoAP request context + * + * @param[in] ctx Pointer to the request context to initialize + * @param[in] remote Remote endpoint that made the request + */ +void coap_request_ctx_init(coap_request_ctx_t *ctx, sock_udp_ep_t *remote); + +/** + * @brief CoAP resource request handler context + * @internal + */ +struct _coap_request_ctx { + const coap_resource_t *resource; /**< resource of the request */ + sock_udp_ep_t *remote; /**< remote endpoint of the request */ +#if defined(MODULE_GCOAP) || DOXYGEN + /** + * @brief transport the packet was received over + * @see @ref gcoap_socket_type_t for values. + * @note @ref gcoap_socket_type_t can not be used, as this would + * cyclically include the @ref net_gcoap header. + */ + uint32_t tl_type; +#endif +}; + /** * @brief Get resource path associated with a CoAP request * @@ -353,8 +374,6 @@ uint32_t coap_request_ctx_get_tl_type(const coap_request_ctx_t *ctx); /** * @brief Get the remote endpoint from which the request was received * - * @note This is currently only implemented for GCoAP - * * @param[in] ctx The request context * * @return Remote endpoint from which the request originated @@ -1846,11 +1865,13 @@ ssize_t coap_build_reply(coap_pkt_t *pkt, unsigned code, * @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] ctx CoAP request context information * * @returns size of reply packet on success * @returns <0 on error */ -ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len); +ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len, + coap_request_ctx_t *ctx); /** * @brief Pass a coap request to a matching handler @@ -1861,6 +1882,7 @@ ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_le * @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] ctx CoAP request context information * @param[in] resources Array of coap endpoint resources * @param[in] resources_numof length of the coap endpoint resources * @@ -1868,7 +1890,7 @@ ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_le * @returns <0 on error */ ssize_t coap_tree_handler(coap_pkt_t *pkt, uint8_t *resp_buf, - unsigned resp_buf_len, + unsigned resp_buf_len, coap_request_ctx_t *ctx, const coap_resource_t *resources, size_t resources_numof); diff --git a/sys/net/application_layer/gcoap/gcoap.c b/sys/net/application_layer/gcoap/gcoap.c index aaa0e1afba..aa7909de1e 100644 --- a/sys/net/application_layer/gcoap/gcoap.c +++ b/sys/net/application_layer/gcoap/gcoap.c @@ -29,7 +29,6 @@ #include "net/coap.h" #include "net/gcoap.h" #include "net/gcoap/forward_proxy.h" -#include "nanocoap_internal.h" #include "net/nanocoap/cache.h" #include "net/sock/async/event.h" #include "net/sock/util.h" diff --git a/sys/net/application_layer/nanocoap/nanocoap.c b/sys/net/application_layer/nanocoap/nanocoap.c index 937b40568f..f768ffd8d4 100644 --- a/sys/net/application_layer/nanocoap/nanocoap.c +++ b/sys/net/application_layer/nanocoap/nanocoap.c @@ -27,7 +27,7 @@ #include #include "bitarithm.h" -#include "nanocoap_internal.h" +#include "net/nanocoap.h" #define ENABLE_DEBUG 0 #include "debug.h" @@ -414,8 +414,11 @@ bool coap_has_unprocessed_critical_options(const coap_pkt_t *pkt) return false; } -ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len) +ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len, + coap_request_ctx_t *ctx) { + assert(ctx); + if (coap_get_code_class(pkt) != COAP_REQ) { DEBUG("coap_handle_req(): not a request.\n"); return -EBADMSG; @@ -424,8 +427,8 @@ ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_le if (pkt->hdr->code == 0) { return coap_build_reply(pkt, COAP_CODE_EMPTY, resp_buf, resp_buf_len, 0); } - return coap_tree_handler(pkt, resp_buf, resp_buf_len, coap_resources, - coap_resources_numof); + return coap_tree_handler(pkt, resp_buf, resp_buf_len, ctx, + coap_resources, coap_resources_numof); } ssize_t coap_subtree_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, @@ -433,13 +436,12 @@ ssize_t coap_subtree_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, { assert(context); coap_resource_subtree_t *subtree = coap_request_ctx_get_context(context); - return coap_tree_handler(pkt, buf, len, subtree->resources, + return coap_tree_handler(pkt, buf, len, context, subtree->resources, subtree->resources_numof); } -ssize_t coap_tree_handler(coap_pkt_t *pkt, uint8_t *resp_buf, - unsigned resp_buf_len, - const coap_resource_t *resources, +ssize_t coap_tree_handler(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_len, + coap_request_ctx_t *ctx, const coap_resource_t *resources, size_t resources_numof) { coap_method_flags_t method_flag = coap_method2flag(coap_get_code_detail(pkt)); @@ -461,10 +463,8 @@ ssize_t coap_tree_handler(coap_pkt_t *pkt, uint8_t *resp_buf, continue; } - coap_request_ctx_t ctx = { - .resource = resource, - }; - return resource->handler(pkt, resp_buf, resp_buf_len, &ctx); + ctx->resource = resource; + return resource->handler(pkt, resp_buf, resp_buf_len, ctx); } return coap_build_reply(pkt, COAP_CODE_404, resp_buf, resp_buf_len, 0); @@ -1260,6 +1260,12 @@ unsigned coap_get_len(coap_pkt_t *pkt) return pktlen; } +void coap_request_ctx_init(coap_request_ctx_t *ctx, sock_udp_ep_t *remote) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->remote = remote; +} + const char *coap_request_ctx_get_path(const coap_request_ctx_t *ctx) { return ctx->resource->path; @@ -1282,10 +1288,5 @@ uint32_t coap_request_ctx_get_tl_type(const coap_request_ctx_t *ctx) const sock_udp_ep_t *coap_request_ctx_get_remote_udp(const coap_request_ctx_t *ctx) { -#ifdef MODULE_GCOAP return ctx->remote; -#else - (void)ctx; - return NULL; -#endif } diff --git a/sys/net/application_layer/nanocoap/nanocoap_internal.h b/sys/net/application_layer/nanocoap/nanocoap_internal.h deleted file mode 100644 index cada93135f..0000000000 --- a/sys/net/application_layer/nanocoap/nanocoap_internal.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2022 ML!PA Consulting GmbH - * - * 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. - */ - -/** - * @ingroup net_nanocoap - * @{ - * - * @file - * @brief NanoCoAP internals - * - * @author Benjamin Valentin - */ - -#ifndef NANOCOAP_INTERNAL_H -#define NANOCOAP_INTERNAL_H - -#include "net/nanocoap.h" -#if defined(MODULE_SOCK_UDP) || defined(DOXYGEN) -#include "net/sock/udp.h" -#else -typedef void sock_udp_ep_t; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Internal CoAP resource request handler context - */ -struct _coap_request_ctx { - const coap_resource_t *resource; /**< resource of the request */ -#if defined(MODULE_GCOAP) || DOXYGEN - /** - * @brief transport the packet was received over - * @see @ref gcoap_socket_type_t for values. - * @note @ref gcoap_socket_type_t can not be used, as this would - * cyclically include the @ref net_gcoap header. - */ - uint32_t tl_type; - sock_udp_ep_t *remote; /**< remote endpoint of the request */ -#endif -}; - -#ifdef __cplusplus -} -#endif -#endif /* NANOCOAP_INTERNAL_H */ -/** @} */ diff --git a/sys/net/application_layer/nanocoap/sock.c b/sys/net/application_layer/nanocoap/sock.c index 4c26428478..e09c3a6b23 100644 --- a/sys/net/application_layer/nanocoap/sock.c +++ b/sys/net/application_layer/nanocoap/sock.c @@ -644,6 +644,9 @@ int nanocoap_server(sock_udp_ep_t *local, uint8_t *buf, size_t bufsize) { nanocoap_sock_t sock; sock_udp_ep_t remote; + coap_request_ctx_t ctx = { + .remote = &remote, + }; if (!local->port) { local->port = COAP_PORT; @@ -665,7 +668,7 @@ int nanocoap_server(sock_udp_ep_t *local, uint8_t *buf, size_t bufsize) DEBUG("error parsing packet\n"); continue; } - if ((res = coap_handle_req(&pkt, buf, bufsize)) > 0) { + if ((res = coap_handle_req(&pkt, buf, bufsize, &ctx)) > 0) { sock_udp_send(&sock, buf, res, &remote); } else { diff --git a/tests/nanocoap_cli/nanocli_server.c b/tests/nanocoap_cli/nanocli_server.c index 58a79c95e4..620fb59e65 100644 --- a/tests/nanocoap_cli/nanocli_server.c +++ b/tests/nanocoap_cli/nanocli_server.c @@ -59,11 +59,15 @@ static int _nanocoap_server(sock_udp_ep_t *local, uint8_t *buf, size_t bufsize, } else { coap_pkt_t pkt; + coap_request_ctx_t ctx = { + .remote = &remote, + }; + if (coap_parse(&pkt, (uint8_t *)buf, res) < 0) { DEBUG("nanocoap: error parsing packet\n"); continue; } - if ((res = coap_handle_req(&pkt, buf, bufsize)) > 0) { + if ((res = coap_handle_req(&pkt, buf, bufsize, &ctx)) > 0) { res = sock_udp_send(&sock, buf, res, &remote); } }