1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

examples: add RD lookup client example

This commit is contained in:
Aiman Ismail 2019-11-12 14:52:47 +01:00 committed by M Aiman Ismail
parent 869052dcd8
commit 99950d1f7c
5 changed files with 307 additions and 0 deletions

34
examples/cord_lc/Makefile Normal file
View File

@ -0,0 +1,34 @@
# name of your application
APPLICATION = cord_lc
# If no BOARD is found in the environment, use this default:
BOARD ?= native
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..
USEMODULE += gnrc_netdev_default
USEMODULE += auto_init_gnrc_netif
USEMODULE += gnrc_ipv6_default
USEMODULE += gnrc_icmpv6_echo
USEMODULE += cord_lc
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps
# The default size of GCOAP_PDU_BUF_SIZE can be too small for the response
# from the RD server. Use a larger value if the client drops response packet
# from RD server.
CFLAGS += -DCONFIG_GCOAP_PDU_BUF_SIZE=512
# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
DEVELHELP ?= 1
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,34 @@
BOARD_INSUFFICIENT_MEMORY := \
arduino-duemilanove \
arduino-leonardo \
arduino-mega2560 \
arduino-nano \
arduino-uno \
atmega1284p \
atmega328p \
chronos \
derfmega128 \
hifive1 \
hifive1b \
i-nucleo-lrwan1 \
im880b \
mega-xplained \
microduino-corerf \
msb-430 \
msb-430h \
nucleo-f030r8 \
nucleo-f031k6 \
nucleo-f042k6 \
nucleo-f303k8 \
nucleo-f334r8 \
nucleo-l031k6 \
nucleo-l053r8 \
stm32f030f4-demo \
stm32f0discovery \
stm32l0538-disco \
telosb \
waspmote-pro \
wsn430-v1_3b \
wsn430-v1_4 \
z1 \
#

View File

@ -0,0 +1,16 @@
CoRE Resource Directory: Lookup Example
=========================================
This example application demonstrates the usage of RIOT's Resource Directory
(RD) lookup module, called `cord_lc`. This module supports the lookup of
resources and endpoints as defined in
[draft-ietf-core-resource-directory-20](https://tools.ietf.org/html/draft-ietf-core-resource-directory-23).
The lookup can be done in two modes: a) raw: result of the lookup is returned
as is. b) pre-parsed: result of the lookup is parsed and only one link is
returned for each call.
Usage
=====
The examples includes a shell command that you can use to interact with a given
RD, called `cord_lc`. Simply use that shell command without parameters for
more information on its usage.

View File

@ -0,0 +1,176 @@
/*
* Copyright (C) 2018 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 examples
* @{
*
* @file
* @brief Shell command for the cord_lc module
*
* @author Aiman Ismail <muhammadaimanbin.ismail@haw-hamburg.de>
*
* @}
*/
#include <stdio.h>
#include <stdlib.h>
#include "net/cord/config.h"
#include "net/cord/lc.h"
#include "net/gcoap.h"
#include "net/sock/util.h"
static cord_lc_rd_t rd;
static sock_udp_ep_t remote;
static char rdbuf[2 * CONFIG_NANOCOAP_URI_MAX] = {0};
static unsigned rd_initialized = 0;
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;
}
/* if netif not specified in addr */
if ((ep->netif == SOCK_ADDR_ANY_NETIF) && (gnrc_netif_numof() == 1)) {
/* assign the single interface found in gnrc_netif_numof() */
ep->netif = (uint16_t)gnrc_netif_iter(NULL)->pid;
}
ep->family = AF_INET6;
if (ep->port == 0) {
ep->port = COAP_PORT;
}
return 0;
}
/**
* Parses main arguments for filters.
* Returns number of parsed filters
*/
static void _parse_filters(clif_attr_t *filters, size_t filter_count,
char **argv) {
for (unsigned i = 0; i < filter_count; i++) {
clif_attr_t *f = &filters[i];
f->key = argv[i];
char *key_end = memchr(argv[i], '=', strlen(argv[i]));
if (!key_end) {
f->key_len = strlen(f->key);
f->value = NULL;
f->value_len = 0;
}
else {
f->key_len = key_end - f->key;
f->value = key_end + 1;
f->value_len = strlen(f->value);
}
}
}
static void _print_lookup_result(struct cord_lc_result *res) {
printf("Found resource/endpoint\n");
printf("Target: %.*s\n", res->link.target_len, res->link.target);
for (unsigned i = 0; i < res->link.attrs_len; i++) {
clif_attr_t *p = &(res->link.attrs[i]);
printf("'%.*s': '%.*s'\n", p->key_len, p->key, p->value_len, p->value);
}
}
static void _print_usage(void) {
puts("usage: cord_lc <server_addr> "
"[-r] { resource | endpoint } [key=value]\n"
"Options:\n"
" -r get raw result\n"
"example: cord_lc [2001:db8:3::dead:beef]:5683 -r resource count=1 page=2\n"
"example: cord_lc [2001:db8:3::dead:beef]:5683 endpoint");
}
int cord_lc_cli_cmd(int argc, char **argv) {
char bufpool[1024] = {0};
int raw_mode = 0;
raw_mode = argc > 3 && !strcmp(argv[2], "-r");
if (argc < 3 || (raw_mode && argc < 4)) {
_print_usage();
return -1;
}
if (!rd_initialized) {
int ret = make_sock_ep(&remote, argv[1]);
if (ret < 0) {
printf("error: unable to parse address\n");
return -1;
}
puts("Performing lookup now, this may take a short while...");
ret = cord_lc_rd_init(&rd, rdbuf, sizeof(rdbuf), &remote);
if (ret < 0) {
printf("error initializing RD server %d", ret);
return -1;
}
rd_initialized = 1;
}
/* parse filters */
unsigned filter_start = raw_mode ? 4 : 3;
size_t filter_count = argc - filter_start;
clif_attr_t filter_array[filter_count];
if (filter_count > 0) {
_parse_filters(filter_array, filter_count, &argv[filter_start]);
}
cord_lc_filter_t filters = {
.array = filter_array,
.len = filter_count,
.next = NULL,
};
int retval = 0;
if (raw_mode) {
if (!strcmp(argv[3], "resource")) {
retval = cord_lc_raw(&rd, COAP_FORMAT_LINK, CORD_LC_RES, &filters,
bufpool, sizeof(bufpool));
} else if (!strcmp(argv[3], "endpoint")) {
retval = cord_lc_raw(&rd, COAP_FORMAT_LINK, CORD_LC_EP, &filters,
bufpool, sizeof(bufpool));
} else {
_print_usage();
return -1;
}
if (retval < 0) {
printf("Error during lookup %d\n", retval);
return -1;
}
printf("Lookup result:\n%.*s\n", retval, bufpool);
} else if (!strcmp(argv[2], "resource")) {
cord_lc_res_t resource;
clif_attr_t attrs[5];
resource.attrs = attrs;
resource.max_attrs = ARRAY_SIZE(attrs);
retval =
cord_lc_res(&rd, &resource, &filters, bufpool, sizeof(bufpool));
if (retval < 0) {
printf("Error during lookup %d\n", retval);
return -1;
}
_print_lookup_result(&resource);
} else if (!strcmp(argv[2], "endpoint")) {
cord_lc_ep_t endpoint;
clif_attr_t attrs[5];
endpoint.attrs = attrs;
endpoint.max_attrs = ARRAY_SIZE(attrs);
retval = cord_lc_ep(&rd, &endpoint, &filters, bufpool, sizeof(bufpool));
if (retval < 0) {
printf("Error during lookup %d\n", retval);
return -1;
}
_print_lookup_result(&endpoint);
} else {
_print_usage();
return -1;
}
return 0;
}

47
examples/cord_lc/main.c Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2018 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 examples
* @{
*
* @file
* @brief CoRE Resource Directory lookup (cord_lc) example
*
* @author Aiman Ismail <muhammadaimanbin.ismail@haw-hamburg.de>
*
* @}
*/
#include <stdio.h>
#include "shell.h"
#include "msg.h"
#define MAIN_QUEUE_SIZE (8)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
extern int cord_lc_cli_cmd(int argc, char **argv);
static const shell_command_t shell_commands[] = {
{ "cord_lc", "Cord LC example", cord_lc_cli_cmd },
{ NULL, NULL, NULL },
};
int main(void)
{
/* we need a message queue for the thread running the shell in order to
* receive potentially fast incoming networking packets */
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
puts("CoRE RD lookup client example!\n");
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
return 0;
}