From 108284670c19981855fa0c0c9dd30303012d6373 Mon Sep 17 00:00:00 2001 From: Hauke Petersen <hauke.petersen@fu-berlin.de> Date: Mon, 24 Jul 2017 17:42:26 +0200 Subject: [PATCH] net: added RD client for simplified registration --- Makefile.dep | 13 +++- makefiles/pseudomodules.inc.mk | 1 + sys/Makefile | 3 + sys/auto_init/auto_init.c | 5 ++ sys/include/net/rdcli_common.h | 13 ++++ sys/include/net/rdcli_config.h | 35 +++++++++++ sys/include/net/rdcli_simple.h | 47 +++++++++++++++ .../rdcli_common/rdcli_common.c | 30 ++++++++++ .../application_layer/rdcli_simple/Makefile | 7 +++ .../rdcli_simple/rdcli_simple.c | 60 +++++++++++++++++++ .../rdcli_simple/rdcli_simple_standalone.c | 54 +++++++++++++++++ 11 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 sys/include/net/rdcli_simple.h create mode 100644 sys/net/application_layer/rdcli_simple/Makefile create mode 100644 sys/net/application_layer/rdcli_simple/rdcli_simple.c create mode 100644 sys/net/application_layer/rdcli_simple/rdcli_simple_standalone.c diff --git a/Makefile.dep b/Makefile.dep index 6a93d54740..3c9a0a1a0d 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 15b562684e..ebb54ee0a9 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 3c48acd69d..f08ec774ae 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 4896751c26..6cdaded5b3 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 005928b219..2077b3b312 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 906d37fc66..1acd5d7578 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 0000000000..1e5d08ffc4 --- /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 d8298930c4..d3c2d24ccd 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 0000000000..997bf2fc80 --- /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 0000000000..cb86eeef83 --- /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 0000000000..868250ff19 --- /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); +} -- GitLab