diff --git a/examples/gcoap/gcoap_cli.c b/examples/gcoap/gcoap_cli.c index d952b53c98..f1a2f6fb71 100644 --- a/examples/gcoap/gcoap_cli.c +++ b/examples/gcoap/gcoap_cli.c @@ -31,13 +31,13 @@ static void _resp_handler(unsigned req_state, coap_pkt_t* pdu, sock_udp_ep_t *remote); -static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len); -static ssize_t _riot_board_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len); +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 */ static const coap_resource_t _resources[] = { - { "/cli/stats", COAP_GET | COAP_PUT, _stats_handler }, - { "/riot/board", COAP_GET, _riot_board_handler }, + { "/cli/stats", COAP_GET | COAP_PUT, _stats_handler, NULL }, + { "/riot/board", COAP_GET, _riot_board_handler, NULL }, }; static gcoap_listener_t _listener = { @@ -98,8 +98,10 @@ static void _resp_handler(unsigned req_state, coap_pkt_t* pdu, * 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) +static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) { + (void)ctx; + /* read coap method type in packet */ unsigned method_flag = coap_method2flag(coap_get_code_detail(pdu)); @@ -129,8 +131,9 @@ static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len) return 0; } -static ssize_t _riot_board_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len) +static ssize_t _riot_board_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx) { + (void)ctx; gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); /* write the RIOT board name in the response buffer */ memcpy(pdu->payload, RIOT_BOARD, strlen(RIOT_BOARD)); diff --git a/examples/nanocoap_server/coap_handler.c b/examples/nanocoap_server/coap_handler.c index 5c1716a3bc..06bd294f0b 100644 --- a/examples/nanocoap_server/coap_handler.c +++ b/examples/nanocoap_server/coap_handler.c @@ -16,14 +16,17 @@ /* internal value that can be read/written via CoAP */ static uint8_t internal_value = 0; -static ssize_t _riot_board_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len) +static ssize_t _riot_board_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *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_value_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len) +static ssize_t _riot_value_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context) { + (void) context; + ssize_t p = 0; char rsp[16]; unsigned code = COAP_CODE_EMPTY; @@ -55,8 +58,8 @@ static ssize_t _riot_value_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len) /* must be sorted by path (alphabetically) */ const coap_resource_t coap_resources[] = { COAP_WELL_KNOWN_CORE_DEFAULT_HANDLER, - { "/riot/board", COAP_GET, _riot_board_handler }, - { "/riot/value", COAP_GET | COAP_PUT | COAP_POST, _riot_value_handler }, + { "/riot/board", COAP_GET, _riot_board_handler, NULL }, + { "/riot/value", COAP_GET | COAP_PUT | COAP_POST, _riot_value_handler, NULL }, }; const unsigned coap_resources_numof = sizeof(coap_resources) / sizeof(coap_resources[0]); diff --git a/sys/include/net/nanocoap.h b/sys/include/net/nanocoap.h index ad525814f1..3ea265d4ff 100644 --- a/sys/include/net/nanocoap.h +++ b/sys/include/net/nanocoap.h @@ -233,7 +233,7 @@ typedef struct { /** * @brief Resource handler type */ -typedef ssize_t (*coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len); +typedef ssize_t (*coap_handler_t)(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context); /** * @brief Type for CoAP resource entry @@ -242,6 +242,7 @@ typedef struct { const char *path; /**< URI path of resource */ unsigned methods; /**< OR'ed methods this resource allows */ coap_handler_t handler; /**< ptr to resource handler */ + void *context; /**< ptr to user defined context data */ } coap_resource_t; /** @@ -595,13 +596,18 @@ static inline uint32_t coap_get_observe(coap_pkt_t *pkt) * application */ extern ssize_t coap_well_known_core_default_handler(coap_pkt_t *pkt, \ - uint8_t *buf, size_t len); + uint8_t *buf, size_t len, + void *context); /** * @brief Resource definition for the default .well-known/core handler */ #define COAP_WELL_KNOWN_CORE_DEFAULT_HANDLER \ - { "/.well-known/core", COAP_GET, coap_well_known_core_default_handler } + { \ + .path = "/.well-known/core", \ + .methods = COAP_GET, \ + .handler = coap_well_known_core_default_handler \ + } #ifdef __cplusplus } diff --git a/sys/net/application_layer/gcoap/gcoap.c b/sys/net/application_layer/gcoap/gcoap.c index 2788c1d663..36a06aace3 100644 --- a/sys/net/application_layer/gcoap/gcoap.c +++ b/sys/net/application_layer/gcoap/gcoap.c @@ -29,7 +29,7 @@ /* Internal functions */ static void *_event_loop(void *arg); static void _listen(sock_udp_t *sock); -static ssize_t _well_known_core_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len); +static ssize_t _well_known_core_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); static ssize_t _write_options(coap_pkt_t *pdu, uint8_t *buf, size_t len); static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len, sock_udp_ep_t *remote); @@ -48,7 +48,7 @@ static void _find_obs_memo_resource(gcoap_observe_memo_t **memo, /* Internal variables */ const coap_resource_t _default_resources[] = { - { "/.well-known/core", COAP_GET, _well_known_core_handler }, + { "/.well-known/core", COAP_GET, _well_known_core_handler, NULL }, }; static gcoap_listener_t _default_listener = { @@ -310,7 +310,7 @@ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len, return -1; } - ssize_t pdu_len = resource->handler(pdu, buf, len); + ssize_t pdu_len = resource->handler(pdu, buf, len, resource->context); if (pdu_len < 0) { pdu_len = gcoap_response(pdu, buf, len, COAP_CODE_INTERNAL_SERVER_ERROR); @@ -457,8 +457,9 @@ static void _expire_request(gcoap_request_memo_t *memo) * Handler for /.well-known/core. Lists registered handlers, except for * /.well-known/core itself. */ -static ssize_t _well_known_core_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len) +static ssize_t _well_known_core_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx) { + (void)ctx; /* write header */ gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT); int plen = gcoap_get_resource_list(pdu->payload, (size_t)pdu->payload_len, diff --git a/sys/net/application_layer/nanocoap/nanocoap.c b/sys/net/application_layer/nanocoap/nanocoap.c index 5b8a60f3a1..27e810524f 100644 --- a/sys/net/application_layer/nanocoap/nanocoap.c +++ b/sys/net/application_layer/nanocoap/nanocoap.c @@ -155,11 +155,12 @@ ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_le unsigned method_flag = coap_method2flag(coap_get_code_detail(pkt)); for (unsigned i = 0; i < coap_resources_numof; i++) { - if (!(coap_resources[i].methods & method_flag)) { + const coap_resource_t *resource = &coap_resources[i]; + if (!(resource->methods & method_flag)) { continue; } - int res = strcmp((char *)pkt->url, coap_resources[i].path); + int res = strcmp((char *)pkt->url, resource->path); if (res > 0) { continue; } @@ -167,7 +168,7 @@ ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_le break; } else { - return coap_resources[i].handler(pkt, resp_buf, resp_buf_len); + return resource->handler(pkt, resp_buf, resp_buf_len, resource->context); } } @@ -381,8 +382,10 @@ size_t coap_put_option_uri(uint8_t *buf, uint16_t lastonum, const char *uri, uin } ssize_t coap_well_known_core_default_handler(coap_pkt_t *pkt, uint8_t *buf, \ - size_t len) + size_t len, void *context) { + (void)context; + uint8_t *payload = buf + coap_get_total_hdr_len(pkt); uint8_t *bufpos = payload; diff --git a/tests/unittests/tests-gcoap/tests-gcoap.c b/tests/unittests/tests-gcoap/tests-gcoap.c index 7de7968606..03cfa7c307 100644 --- a/tests/unittests/tests-gcoap/tests-gcoap.c +++ b/tests/unittests/tests-gcoap/tests-gcoap.c @@ -26,13 +26,13 @@ * A test set of dummy resources. The resource handlers are set to NULL. */ static const coap_resource_t resources[] = { - { "/act/switch", (COAP_GET | COAP_POST), NULL }, - { "/sensor/temp", (COAP_GET), NULL }, - { "/test/info/all", (COAP_GET), NULL }, + { .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[] = { - { "/second/part", (COAP_GET), NULL }, + { .path = "/second/part", .methods = (COAP_GET)}, }; static gcoap_listener_t listener = {