Skip to content

Commit

Permalink
Merge pull request #26 from rosetree/feature/rd-registration
Browse files Browse the repository at this point in the history
Feature/rd registration
  • Loading branch information
rosetree authored Dec 16, 2019
2 parents ec88b3e + ede4046 commit a4c7ed4
Show file tree
Hide file tree
Showing 6 changed files with 286 additions and 2 deletions.
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,20 @@ USEMODULE += shell_commands
# additional modules for debugging:
USEMODULE += ps

USEMODULE += netstats_l2
# Module for registering to Resource Directory (RD)
USEMODULE += cord_ep

# needed so that the board can be reached
USEMODULE += netstats_l2
#
# Include tinycbor for data representation
USEPKG += tinycbor
INCLUDE += $(RIOTPKG)/tinycbor/cbor.h

CFLAGS += -DGNRC_IPV6_NIB_CONF_SLAAC=1

# For debugging and demonstration purposes the lifetime is limited to 30s
CFLAGS += -DCORD_LT=30

# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
Expand All @@ -54,3 +60,4 @@ DEVELHELP ?= 1
QUIET ?= 1

include $(RIOTBASE)/Makefile.include

11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ interpreted.

[list of cbor implementations]: http://cbor.io/impls.html

## Resource Directory (RD)
A RD is a service that stores information about the COAP-routes of a device, so that a client can search for specific routes
within a network of devices, instead of querying each device itself (see [RFC CoRE Resource Directory v15](https://tools.ietf.org/html/draft-ietf-core-resource-directory-15)).

Following features are implemented in this project:
1. Automatic registration on device startup
2. Periodic update of RD entry
3. Reregistration when an update fails

The default update time is 30s and should be changed to the wanted time (in seconds) for production, by changing following line in the Makefile: `CFLAGS += -DCORD_LT=30s`.

## Build and Execute
Enter shell with board command (Phytec)

Expand Down
24 changes: 24 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,31 @@
#include <stdio.h>
#include "msg.h"
#include "shell.h"
#include "saul_cord_ep.h"

#define MAIN_QUEUE_SIZE (4)
#define CORD_EP_ADDRESS "[fdaa:bb:cc:dd::1]:5683"

static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];

extern void saul_coap_init(void);

/* we will use custom event handler for dumping cord_ep events */
static void _on_ep_event(saul_cord_ep_event_t event)
{
switch (event) {
case SAUL_CORD_EP_REGISTERED:
puts("DEBUG: Registered successfully with RD");
break;
case SAUL_CORD_EP_DEREGISTERED:
puts("DEBUG: Deregistered from RD");
break;
case SAUL_CORD_EP_UPDATED:
puts("DEBUG: Updated successfully the client registration");
break;
}
}

int main(void)
{
puts("Welcome to RIOT!\n");
Expand All @@ -36,8 +55,13 @@ int main(void)

msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);

saul_cord_ep_register_cb(_on_ep_event);
saul_cord_ep_create(CORD_EP_ADDRESS);
saul_cord_ep_run();

char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);

return 0;
}

3 changes: 2 additions & 1 deletion saul_coap.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* @brief CoAP endpoint for the SAUL registry
*
* @author Micha Rosenbaum <[email protected]>
*
* @author Matthias Bräuer <[email protected]>
* @}
*/

Expand Down Expand Up @@ -290,3 +290,4 @@ void saul_coap_init(void)
{
gcoap_register_listener(&_listener);
}

156 changes: 156 additions & 0 deletions saul_cord_ep.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/**
* Copyright (C) 2019 HAW Hamburg
*
* 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 pkg
* @{
*
* @file
* @brief Register SAUL registry to resource directory
*
* @author Matthias Bräuer <[email protected]>
*
* @}
*/

#include "saul_cord_ep.h"

#define ENABLE_DEBUG (0)
#include "debug.h"

/* stack configuration */
#define STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#define PRIO (THREAD_PRIORITY_MAIN - 1)
#define TNAME "cord_ep"

#define UPDATE_TIMEOUT (0xe537)

#define TIMEOUT_US ((uint64_t)(CORD_UPDATE_INTERVAL * US_PER_SEC))

static char _stack[STACKSIZE];

static xtimer_t _timer;
static kernel_pid_t _runner_pid;
static msg_t _msg;

static saul_cord_ep_cb_t _cb = NULL;

// The ipv6 address (and port) of the resource directory
static const char *ip = NULL;

static void _set_timer(void)
{
xtimer_set_msg64(&_timer, TIMEOUT_US, &_msg, _runner_pid);
}

/**
* @brief Execute the callback function if present.
*
* @param[in] event The event that occurred
*/
static void _notify(saul_cord_ep_event_t event) {
if (_cb != NULL) {
_cb(event);
}
}

/**
* @brief Create an UDP socket.
*
* @param[out] ep Will contain the enpoint of the IPv6 address
* @param[in] addr The IPv6 address to be used for the socket
* @return `0` on success, else `-1`
*/
static int make_sock_ep(sock_udp_ep_t *ep, const char *addr)
{
ep->port = 0;
if (sock_udp_str2ep(ep, addr) < 0) {
return -1;
}
ep->family = AF_INET6;
ep->netif = SOCK_ADDR_ANY_NETIF;
if (ep->port == 0) {
ep->port = COAP_PORT;
}
return 0;
}

/**
* @brief Try to register to resource directory service.
*/
static int register_rd(void) {
sock_udp_ep_t remote;
char *regif = NULL;

if (make_sock_ep(&remote, ip) < 0) {
puts("error: unable to parse address\n");
return 1;
}

puts("Registering with RD now, this may take a short while...");

if (cord_ep_register(&remote, regif) != CORD_EP_OK) {
_notify(SAUL_CORD_EP_DEREGISTERED);
return 1;
}

_notify(SAUL_CORD_EP_REGISTERED);

return 0;
}

static void saul_cord_ep_register(void) {
printf("DEBUG: RD-ADDRESS: %s\n", ip);

while (register_rd()) {
puts("Try again to register to RD deamon");
}

cord_ep_dump_status();
}

static void *_reg_runner(void *arg)
{
(void)arg;
msg_t in;

/* prepare context and message */
_runner_pid = thread_getpid();
_msg.type = UPDATE_TIMEOUT;

while (1) {
msg_receive(&in);
if (in.type == UPDATE_TIMEOUT) {
if (cord_ep_update() == CORD_EP_OK) {
_set_timer();
_notify(SAUL_CORD_EP_UPDATED);
}
else {
_notify(SAUL_CORD_EP_DEREGISTERED);
saul_cord_ep_register();
_set_timer();
}
}
}

return NULL; /* should never be reached */
}

void saul_cord_ep_register_cb(saul_cord_ep_cb_t cb) {
_cb = cb;
}

void saul_cord_ep_create(const char* ip_address)
{
ip = ip_address;
thread_create(_stack, sizeof(_stack), PRIO, THREAD_CREATE_STACKTEST,
_reg_runner, NULL, TNAME);
}

void saul_cord_ep_run(void) {
_set_timer();
}

85 changes: 85 additions & 0 deletions saul_cord_ep.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright (C) 2019 HAW Hamburg
*
* 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 pkg
* @{
*
* @file
* @brief Register SAUL registry to resource directory and update it periodically.
*
* @author Matthias Bräuer <[email protected]>
*
* @}
*/
#ifndef SAUL_CORD_EP_H
#define SAUL_CORD_EP_H

#include "net/nanocoap.h"
#include "net/cord/config.h"
#include "net/cord/ep.h"
#include "net/sock/util.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Possible types of events when interacting with a Resource Directory.
*/
typedef enum {
SAUL_CORD_EP_REGISTERED,
SAUL_CORD_EP_DEREGISTERED,
SAUL_CORD_EP_UPDATED,
} saul_cord_ep_event_t;

/**
* @brief Callback function signature for RD endpoint state synchronization.
*
* The registered callback function is executed in the context of the dedicated
* RD endpoint's thread.
*
* @param[in] event Type of event
*/
typedef void (*saul_cord_ep_cb_t)(saul_cord_ep_event_t event);

/**
* @brief Create the saul-cord thread.
*
* @param[in] ip_address The IPv6 address of the resource directory service
*
* @warning This function must only be called once (typically during system
* initialization)
*/
void saul_cord_ep_create(const char *ip_address);

/**
* @brief Run the saul-cord thread.
*
* @warning This function must only be called once (typically during system
* initialization)
*/
void saul_cord_ep_run(void);

/**
* @brief Register a callback to be notified about RD endpoint state changes.
*
* Only a single callback can be active at any point in time, so setting a new
* callback will override the existing one.
*
* @pre @p cb != NULL
*
* @param[in] cb The callback to be executed on RD endpoint state changes
*/
void saul_cord_ep_register_cb(saul_cord_ep_cb_t cb);


#ifdef __cplusplus
}
#endif

#endif /* SAUL_CORD_EP_H */

0 comments on commit a4c7ed4

Please sign in to comment.