Skip to content

Commit

Permalink
net/gcoap: introduce and use gcoap_resource_t
Browse files Browse the repository at this point in the history
  • Loading branch information
benpicco committed Jan 24, 2022
1 parent 114e05d commit 6bf20be
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 26 deletions.
6 changes: 3 additions & 3 deletions examples/gcoap/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ static const credman_credential_t credential = {
};
#endif

static ssize_t _encode_link(const coap_resource_t *resource, char *buf,
static ssize_t _encode_link(const gcoap_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);

/* CoAP resources. Must be sorted by path (ASCII order). */
static const coap_resource_t _resources[] = {
static const gcoap_resource_t _resources[] = {
{ "/cli/stats", COAP_GET | COAP_PUT, _stats_handler, NULL },
{ "/riot/board", COAP_GET, _riot_board_handler, NULL },
};
Expand All @@ -82,7 +82,7 @@ static gcoap_listener_t _listener = {


/* Adds link format params to resource list */
static ssize_t _encode_link(const coap_resource_t *resource, char *buf,
static ssize_t _encode_link(const gcoap_resource_t *resource, char *buf,
size_t maxlen, coap_link_encoder_ctx_t *context) {
ssize_t res = gcoap_encode_link(resource, buf, maxlen, context);
if (res > 0) {
Expand Down
42 changes: 34 additions & 8 deletions sys/include/net/gcoap.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
* this by uncommenting the appropriate lines in gcoap's make file.
*
* gcoap allows an application to specify a collection of request resource paths
* it wants to be notified about. Create an array of resources (coap_resource_t
* it wants to be notified about. Create an array of resources (gcoap_resource_t
* structs) ordered by the resource path, specifically the ASCII encoding of
* the path characters (digit and capital precede lower case). Use
* gcoap_register_listener() at application startup to pass in these resources,
Expand Down Expand Up @@ -649,6 +649,32 @@ extern "C" {

/** @} */

/**
* @brief Resource handler type
*
* Functions that implement this must be prepared to be called multiple times
* for the same request, as the server implementations do not perform message
* deduplication. That optimization is [described in the CoAP
* specification](https://tools.ietf.org/html/rfc7252#section-4.5).
*
* This should be trivial for requests of the GET, PUT, DELETE, FETCH and
* iPATCH methods, as they are defined as idempotent methods in CoAP.
*
* For POST, PATCH and other non-idempotent methods, this is an additional
* requirement introduced by the contract of this type.
*/
typedef ssize_t (*gcoap_handler_t)(coap_pkt_t *pkt, uint8_t *rbuf, size_t rlen, void *context);

/**
* @brief Type for CoAP resource entry
*/
typedef struct {
const char *path; /**< URI path of resource */
coap_method_flags_t methods; /**< OR'ed methods this resource allows */
gcoap_handler_t handler; /**< ptr to resource handler */
void *context; /**< ptr to user defined context data */
} gcoap_resource_t;

/**
* @brief Context information required to write a resource link
*/
Expand All @@ -670,7 +696,7 @@ typedef struct {
* @return count of bytes written to @p buf (or writable if @p buf is null)
* @return -1 on error
*/
typedef ssize_t (*gcoap_link_encoder_t)(const coap_resource_t *resource, char *buf,
typedef ssize_t (*gcoap_link_encoder_t)(const gcoap_resource_t *resource, char *buf,
size_t maxlen, coap_link_encoder_ctx_t *context);

/**
Expand Down Expand Up @@ -701,14 +727,14 @@ typedef struct gcoap_listener gcoap_listener_t;
* @return GCOAP_RESOURCE_ERROR on processing failure of the request
*/
typedef int (*gcoap_request_matcher_t)(gcoap_listener_t *listener,
const coap_resource_t **resource,
const gcoap_resource_t **resource,
const coap_pkt_t *pdu);

/**
* @brief A modular collection of resources for a server
*/
struct gcoap_listener {
const coap_resource_t *resources; /**< First element in the array of
const gcoap_resource_t *resources; /**< First element in the array of
* resources; must order alphabetically */
size_t resources_len; /**< Length of array */
gcoap_link_encoder_t link_encoder; /**< Writes a link for a resource */
Expand Down Expand Up @@ -775,7 +801,7 @@ struct gcoap_request_memo {
*/
typedef struct {
sock_udp_ep_t *observer; /**< Client endpoint; unused if null */
const coap_resource_t *resource; /**< Entity being observed */
const gcoap_resource_t *resource; /**< Entity being observed */
uint8_t token[GCOAP_TOKENLEN_MAX]; /**< Client token for notifications */
unsigned token_len; /**< Actual length of token attribute */
} gcoap_observe_memo_t;
Expand Down Expand Up @@ -971,7 +997,7 @@ static inline ssize_t gcoap_response(coap_pkt_t *pdu, uint8_t *buf,
* @return GCOAP_OBS_INIT_UNUSED if no observer for resource
*/
int gcoap_obs_init(coap_pkt_t *pdu, uint8_t *buf, size_t len,
const coap_resource_t *resource);
const gcoap_resource_t *resource);

/**
* @brief Sends a buffer containing a CoAP Observe notification to the
Expand All @@ -987,7 +1013,7 @@ int gcoap_obs_init(coap_pkt_t *pdu, uint8_t *buf, size_t len,
* @return 0 if cannot send
*/
size_t gcoap_obs_send(const uint8_t *buf, size_t len,
const coap_resource_t *resource);
const gcoap_resource_t *resource);

/**
* @brief Provides important operational statistics
Expand Down Expand Up @@ -1031,7 +1057,7 @@ int gcoap_get_resource_list(void *buf, size_t maxlen, uint8_t cf);
* @return count of bytes written to @p buf (or writable if @p buf is null)
* @return -1 on error
*/
ssize_t gcoap_encode_link(const coap_resource_t *resource, char *buf,
ssize_t gcoap_encode_link(const gcoap_resource_t *resource, char *buf,
size_t maxlen, coap_link_encoder_ctx_t *context);

#if IS_USED(MODULE_GCOAP_DTLS) || defined(DOXYGEN)
Expand Down
26 changes: 13 additions & 13 deletions sys/net/application_layer/gcoap/gcoap.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,16 @@ static void _expire_request(gcoap_request_memo_t *memo);
static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *pdu,
const sock_udp_ep_t *remote, bool by_mid);
static int _find_resource(const coap_pkt_t *pdu,
const coap_resource_t **resource_ptr,
const gcoap_resource_t **resource_ptr,
gcoap_listener_t **listener_ptr);
static int _find_observer(sock_udp_ep_t **observer, sock_udp_ep_t *remote);
static int _find_obs_memo(gcoap_observe_memo_t **memo, sock_udp_ep_t *remote,
coap_pkt_t *pdu);
static void _find_obs_memo_resource(gcoap_observe_memo_t **memo,
const coap_resource_t *resource);
const gcoap_resource_t *resource);

static int _request_matcher_default(gcoap_listener_t *listener,
const coap_resource_t **resource,
const gcoap_resource_t **resource,
const coap_pkt_t *pdu);

#if IS_USED(MODULE_GCOAP_DTLS)
Expand All @@ -85,7 +85,7 @@ static void _dtls_free_up_session(void *arg);
#endif

/* Internal variables */
const coap_resource_t _default_resources[] = {
const gcoap_resource_t _default_resources[] = {
{ "/.well-known/core", COAP_GET, _well_known_core_handler, NULL },
};

Expand Down Expand Up @@ -532,7 +532,7 @@ static void _cease_retransmission(gcoap_request_memo_t *memo) {
static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
sock_udp_ep_t *remote)
{
const coap_resource_t *resource = NULL;
const gcoap_resource_t *resource = NULL;
gcoap_listener_t *listener = NULL;
sock_udp_ep_t *observer = NULL;
gcoap_observe_memo_t *memo = NULL;
Expand Down Expand Up @@ -639,7 +639,7 @@ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
}

static int _request_matcher_default(gcoap_listener_t *listener,
const coap_resource_t **resource,
const gcoap_resource_t **resource,
const coap_pkt_t *pdu)
{
uint8_t uri[CONFIG_NANOCOAP_URI_MAX];
Expand All @@ -658,7 +658,7 @@ static int _request_matcher_default(gcoap_listener_t *listener,
for (size_t i = 0; i < listener->resources_len; i++) {
*resource = &listener->resources[i];

int res = coap_match_path(*resource, uri);
int res = coap_match_path((coap_resource_t *)*resource, uri);

/* URI mismatch */
if (res > 0) {
Expand Down Expand Up @@ -697,7 +697,7 @@ static int _request_matcher_default(gcoap_listener_t *listener,
* resource was found.
*/
static int _find_resource(const coap_pkt_t *pdu,
const coap_resource_t **resource_ptr,
const gcoap_resource_t **resource_ptr,
gcoap_listener_t **listener_ptr)
{
int ret = GCOAP_RESOURCE_NO_PATH;
Expand All @@ -706,7 +706,7 @@ static int _find_resource(const coap_pkt_t *pdu,
gcoap_listener_t *listener = _coap_state.listeners;

while (listener) {
const coap_resource_t *resource;
const gcoap_resource_t *resource;
int res = listener->request_matcher(listener, &resource, pdu);

/* check next resource on mismatch */
Expand Down Expand Up @@ -908,7 +908,7 @@ static int _find_obs_memo(gcoap_observe_memo_t **memo, sock_udp_ep_t *remote,
* resource[in] -- Resource to match
*/
static void _find_obs_memo_resource(gcoap_observe_memo_t **memo,
const coap_resource_t *resource)
const gcoap_resource_t *resource)
{
*memo = NULL;
for (int i = 0; i < CONFIG_GCOAP_OBS_REGISTRATIONS_MAX; i++) {
Expand Down Expand Up @@ -1249,7 +1249,7 @@ int gcoap_resp_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code)
}

int gcoap_obs_init(coap_pkt_t *pdu, uint8_t *buf, size_t len,
const coap_resource_t *resource)
const gcoap_resource_t *resource)
{
gcoap_observe_memo_t *memo = NULL;

Expand Down Expand Up @@ -1280,7 +1280,7 @@ int gcoap_obs_init(coap_pkt_t *pdu, uint8_t *buf, size_t len,
}

size_t gcoap_obs_send(const uint8_t *buf, size_t len,
const coap_resource_t *resource)
const gcoap_resource_t *resource)
{
gcoap_observe_memo_t *memo = NULL;
gcoap_socket_t socket;
Expand Down Expand Up @@ -1352,7 +1352,7 @@ int gcoap_get_resource_list(void *buf, size_t maxlen, uint8_t cf)
return (int)pos;
}

ssize_t gcoap_encode_link(const coap_resource_t *resource, char *buf,
ssize_t gcoap_encode_link(const gcoap_resource_t *resource, char *buf,
size_t maxlen, coap_link_encoder_ctx_t *context)
{
size_t path_len = strlen(resource->path);
Expand Down
4 changes: 2 additions & 2 deletions tests/unittests/tests-gcoap/tests-gcoap.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
/*
* A test set of dummy resources. The resource handlers are set to NULL.
*/
static const coap_resource_t resources[] = {
static const gcoap_resource_t resources[] = {
{ .path = "/act/switch", .methods = (COAP_GET | COAP_POST) },
{ .path = "/sensor/temp", .methods = (COAP_GET) },
{ .path = "/test/info/all", .methods = (COAP_GET) },
};

static const coap_resource_t resources_second[] = {
static const gcoap_resource_t resources_second[] = {
{ .path = "/second/part", .methods = (COAP_GET)},
};

Expand Down

0 comments on commit 6bf20be

Please sign in to comment.