diff --git a/Makefile.dep b/Makefile.dep index 6a93d54740e255e7c44503a8f4037d450e9ce324..3c9a0a1a0d0915ed263db6acbfe6f7a918a10105 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -708,9 +708,20 @@ ifneq (,$(filter skald,$(USEMODULE))) USEMODULE += random endif +ifneq (,$(filter rdcli_simple_standalone,$(USEMODULE))) + USEMODULE += rdcli_simple + USEMODULE += xtimer +endif + +ifneq (,$(filter rdcli_simple,$(USEMODULE))) + USEMODULE += rdcli_common + USEMODULE += fmt +endif + ifneq (,$(filter rdcli_common,$(USEMODULE))) - USEMODULE += luid USEMODULE += fmt + USEMODULE += gcoap + USEMODULE += luid endif # always select gpio (until explicit dependencies are sorted out) diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 15b562684e3efafd5f4f6fb89c65ad99b94717a6..ebb54ee0a9cf0d9373e5ea19f61b0441059ee287 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -64,6 +64,7 @@ PSEUDOMODULES += pktqueue PSEUDOMODULES += printf_float PSEUDOMODULES += prng PSEUDOMODULES += prng_% +PSEUDOMODULES += rdcli_simple_standalone PSEUDOMODULES += saul_adc PSEUDOMODULES += saul_default PSEUDOMODULES += saul_gpio diff --git a/sys/Makefile b/sys/Makefile index 3c48acd69d12bca5bfd4b625b17669f39ff2ac8a..f08ec774aed1a3be8bf77b526f0325138b7631dc 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -130,6 +130,9 @@ endif ifneq (,$(filter rdcli_common,$(USEMODULE))) DIRS += net/application_layer/rdcli_common endif +ifneq (,$(filter rdcli_simple,$(USEMODULE))) + DIRS += net/application_layer/rdcli_simple +endif DIRS += $(dir $(wildcard $(addsuffix /Makefile, $(USEMODULE)))) diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c index 4896751c2644a32bb230acc07f7cd2b4dc64ad8a..6cdaded5b3ddbc6a32b03f9e227bfdc93685fa0d 100644 --- a/sys/auto_init/auto_init.c +++ b/sys/auto_init/auto_init.c @@ -164,6 +164,11 @@ void auto_init(void) extern void rdcli_common_init(void); rdcli_common_init(); #endif +#ifdef MODULE_RDCLI_SIMPLE_STANDALONE + DEBUG("Auto init rdcli_simple module\n"); + extern void rdcli_simple_run(void); + rdcli_simple_run(); +#endif /* initialize network devices */ #ifdef MODULE_AUTO_INIT_GNRC_NETIF diff --git a/sys/include/net/rdcli_common.h b/sys/include/net/rdcli_common.h index 005928b219801648fb1a3593f6333ea3a8ea2a87..2077b3b3122e47fd1d0717f2c6ceb012dce73790 100644 --- a/sys/include/net/rdcli_common.h +++ b/sys/include/net/rdcli_common.h @@ -46,6 +46,19 @@ static inline const char *rdcli_common_get_ep(void) return (const char *)rdcli_ep; } +/** + * @brief Add selected query string options to a gcoap request + * + * This function adds: + * - `ep` -> as extracted by rdcli_commont_get_ep() + * - [optional] `lt` -> if defined by RDCLI_LT + * - [optional] 'd' -> if defined by RDCLI_D + * + * @return 0 on success + * @return <0 on error + */ +int rdcli_common_add_qstring(coap_pkt_t *pkt); + #ifdef __cplusplus } #endif diff --git a/sys/include/net/rdcli_config.h b/sys/include/net/rdcli_config.h index 906d37fc66752c29518ee7a91095c975afaf0aa7..1acd5d7578b8a0cfa2e31baf2312b824d095b1eb 100644 --- a/sys/include/net/rdcli_config.h +++ b/sys/include/net/rdcli_config.h @@ -26,6 +26,27 @@ extern "C" { #endif +/** + * @brief Default lifetime in seconds (the default is 1 day) + */ +#ifndef RDCLI_LT +#define RDCLI_LT (86400UL) +#endif + +/** + * @brief Delay until the RD client starts to try registering (in seconds) + */ +#ifndef RDCLI_STARTUP_DELAY +#define RDCLI_STARTUP_DELAY (3U) +#endif + +/** + * @brief Default client update interval (default is half the lifetime) + */ +#ifndef RDCLI_UPDATE_INTERVAL +#define RDCLI_UPDATE_INTERVAL (RDCLI_LT / 2) +#endif + /** * @name Endpoint ID definition * @@ -52,6 +73,20 @@ extern "C" { #endif /** @} */ +/** + * @brief Default IPv6 address to use when looking for RDs + */ +#ifndef RDCLI_SERVER_ADDR +#define RDCLI_SERVER_ADDR IPV6_ADDR_ALL_NODES_LINK_LOCAL +#endif + +/** + * @brief Default Port to use when looking for RDs + */ +#ifndef RDCLI_SERVER_PORT +#define RDCLI_SERVER_PORT COAP_PORT +#endif + #ifdef __cplusplus } #endif diff --git a/sys/include/net/rdcli_simple.h b/sys/include/net/rdcli_simple.h new file mode 100644 index 0000000000000000000000000000000000000000..1e5d08ffc486b41e8fd8a498ba5a078101ef96a6 --- /dev/null +++ b/sys/include/net/rdcli_simple.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 Freie Universität Berlin + * + * 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_rdcli_simple Simple CoRE Resource Directory Registration + * @ingroup net_rdcli + * @brief CoAP-based CoRE Resource Directory client supporting the simple + * registration only + * @{ + * + * @file + * @brief Interface for a simple CoRE RD registration + * + * @author Hauke Petersen <hauke.petersen@fu-berlin.de> + */ + +#ifndef NET_RDCLI_SIMPLE_H +#define NET_RDCLI_SIMPLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initiate the node registration by sending an empty CoAP POST message + * to the RD server's /.well-known/core resource + */ +int rdcli_simple_register(void); + +/** + * @brief Spawn a new thread that registers the node and updates the + * registration with all responding RDs using the simple registration + * process + */ +void rdcli_simple_run(void); + +#ifdef __cplusplus +} +#endif + +#endif /* NET_RDCLI_SIMPLE_H */ +/** @} */ diff --git a/sys/net/application_layer/rdcli_common/rdcli_common.c b/sys/net/application_layer/rdcli_common/rdcli_common.c index d8298930c48b3f8422f54bc7c0c672dc75c84c41..d3c2d24ccd796abc5c9026a8bae910cc872f5433 100644 --- a/sys/net/application_layer/rdcli_common/rdcli_common.c +++ b/sys/net/application_layer/rdcli_common/rdcli_common.c @@ -21,6 +21,7 @@ #include "fmt.h" #include "luid.h" +#include "net/gcoap.h" #include "net/rdcli_common.h" #define ENABLE_DEBUG (0) @@ -58,3 +59,32 @@ void rdcli_common_init(void) rdcli_ep[pos] = '\0'; } + +int rdcli_common_add_qstring(coap_pkt_t *pkt) +{ + /* extend the url with some query string options */ + int res = gcoap_add_qstring(pkt, "ep", rdcli_ep); + if (res < 0) { + return res; + } + + /* [optional] set the lifetime parameter */ +#if RDCLI_LT + char lt[11]; + lt[fmt_u32_dec(lt, RDCLI_LT)] = '\0'; + res = gcoap_add_qstring(pkt, "lt", lt); + if (res < 0) { + return res; + } +#endif + + /* [optional] set the domain parameter */ +#ifdef RDCLI_D + res = gcoap_add_qstring(pkt, "d", RDCLI_D); + if (res < 0) { + return res; + } +#endif + + return 0; +} diff --git a/sys/net/application_layer/rdcli_simple/Makefile b/sys/net/application_layer/rdcli_simple/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..997bf2fc8045f3a44e422ea43e69a36811539e1e --- /dev/null +++ b/sys/net/application_layer/rdcli_simple/Makefile @@ -0,0 +1,7 @@ +SRC = rdcli_simple.c + +ifneq (,$(filter rdcli_simple_standalone,$(USEMODULE))) + SRC += rdcli_simple_standalone.c +endif + +include $(RIOTBASE)/Makefile.base diff --git a/sys/net/application_layer/rdcli_simple/rdcli_simple.c b/sys/net/application_layer/rdcli_simple/rdcli_simple.c new file mode 100644 index 0000000000000000000000000000000000000000..cb86eeef838c4d140b9491f559047a681d4040ae --- /dev/null +++ b/sys/net/application_layer/rdcli_simple/rdcli_simple.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2017 Freie Universität Berlin + * + * 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_rdcli_simple + * @{ + * + * @file + * @brief Simplified CoAP resource directory client implementation + * + * @author Hauke Petersen <hauke.petersen@fu-berlin.de> + * + * @} + */ + +#include <string.h> + +#include "fmt.h" +#include "net/gcoap.h" +#include "net/rdcli_config.h" +#include "net/rdcli_common.h" +#include "net/rdcli_simple.h" + +#define BUFSIZE (128U) + +static coap_pkt_t pkt; +static uint8_t buf[BUFSIZE]; + +/* allocate an UDP endpoint to the RD server */ +static const sock_udp_ep_t remote = { + .family = AF_INET6, + .netif = SOCK_ADDR_ANY_NETIF, + .addr = RDCLI_SERVER_ADDR , + .port = RDCLI_SERVER_PORT +}; + +int rdcli_simple_register(void) +{ + /* build the initial CON packet */ + int res = gcoap_req_init(&pkt, buf, sizeof(buf), COAP_METHOD_POST, + "/.well-known/core"); + if (res < 0) { + return res; + } + /* make packet confirmable */ + coap_hdr_set_type(pkt.hdr, COAP_TYPE_CON); + /* add Uri-Query options */ + res = rdcli_common_add_qstring(&pkt); + if (res < 0) { + return res; + } + /* finish, we don't have any payload */ + ssize_t len = gcoap_finish(&pkt, 0, COAP_FORMAT_LINK); + return (int)gcoap_req_send2(buf, len, &remote, NULL); +} diff --git a/sys/net/application_layer/rdcli_simple/rdcli_simple_standalone.c b/sys/net/application_layer/rdcli_simple/rdcli_simple_standalone.c new file mode 100644 index 0000000000000000000000000000000000000000..868250ff19895c15dfc710d4401b2565bfa498bc --- /dev/null +++ b/sys/net/application_layer/rdcli_simple/rdcli_simple_standalone.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 Freie Universität Berlin + * + * 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_rdcli_simple + * @{ + * + * @file + * @brief Standalone extension for the simple RD registration client + * + * @author Hauke Petersen <hauke.petersen@fu-berlin.de> + * + * @} + */ + +#include "log.h" +#include "thread.h" +#include "xtimer.h" +#include "net/rdcli_config.h" +#include "net/rdcli_simple.h" + +#define STACKSIZE (THREAD_STACKSIZE_DEFAULT) +#define PRIO (THREAD_PRIORITY_MAIN - 1) +#define TNAME "rdcli_simple" + +static char _stack[STACKSIZE]; + +static void *reg_runner(void *arg) +{ + (void)arg; + + /* wait some seconds to give the address configuration some time to settle */ + xtimer_sleep(RDCLI_STARTUP_DELAY); + + while (1) { + int res = rdcli_simple_register(); + if (res < 0) { + LOG_ERROR("[rdcli_simple] error: unable to trigger registration\n"); + } + xtimer_sleep(RDCLI_UPDATE_INTERVAL); + } + + return NULL; /* should never be reached */ +} + +void rdcli_simple_run(void) +{ + thread_create(_stack, sizeof(_stack), PRIO, 0, reg_runner, NULL, TNAME); +}