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

ccn-lite: initial import of an example

This commit is contained in:
Oleg Hahm 2015-10-26 17:41:52 +01:00
parent fc8dd7fdd7
commit f3d16b85a5
6 changed files with 389 additions and 8 deletions

View File

@ -0,0 +1,39 @@
APPLICATION = ccn-lite-relay
# If no BOARD is found in the environment, use this default:
BOARD ?= native
BOARD_WHITELIST := fox iotlab-m3 msba2 mulle native pba-d-01-kw2x samr21-xpro
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..
CFLAGS += -DDEVELHELP
CFLAGS += -DUSE_LINKLAYER
CFLAGS += -DUSE_IPV6
CFLAGS += -DCCNL_UAPI_H_
CFLAGS += -DUSE_SUITE_NDNTLV
CFLAGS += -DNEEDS_PREFIX_MATCHING
CFLAGS += -DNEEDS_PACKET_CRAFTING
CFLAGS += -DUSE_HMAC256
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1
USEMODULE += ps
USEMODULE += shell
USEMODULE += shell_commands
# Include packages that pull up and auto-init the link layer.
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
USEMODULE += gnrc_netif_default
USEMODULE += auto_init_gnrc_netif
USEMODULE += timex
USEMODULE += xtimer
USEMODULE += random
USEMODULE += prng_minstd
USEPKG += ccn-lite
USEMODULE += ccn-lite-utils
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,61 @@
# CCN-Lite on RIOT
This application demonstrates how to use the Content-Centric Networking stack
from [CCN-Lite](http://www.ccn-lite.net/) on RIOT. In the current state you can
use only one packet format, `ndn2013`, and only relay over the link-layer
(Ethernet, IEEE~802.15.4 or what else is supported by your network device).
## The shell commands
RIOT provides three shell to interact with the CCN-Lite stack:
* `ccnl_open` - opens and configures a network device to be used for CCN-Lite.
It expects one parameter specifying the PID of the network
device. (You can figure out the PID of your network device(s)
by calling `ifconfig`.) In this example, this should always be
3, hence, calling `ccnl_open 3` should work. (If you specify an
incorrect ID, you should get an error message.) You have to
call this command, before you can actually send or receive
anything.
* `ccnl_int` - generates and sends out an Interest. The command expects one
mandatory and one optional parameter. The first parameter
specifies the exact name (or a prefix) to request, the second
parameter specifies the link-layer address of the relay to use.
If the second parameter is omitted, the Interest will be
broadcasted. You may call it like this:
`ccnl_int /riot/peter/schmerzl b6:e5:94:26:ab:da`
* `ccnl_cont` - generates and populates Content. The command expects one
mandatory and one optional parameter. The first parameter
specifies the name of the content to be created, the second
parameter specifies the content itself. The second parameter may
include spaces, e.g. you can call:
`ccnl_cont /riot/peter/schmerzl Hello World! Hello RIOT!`
## Example setup
An example usage of this application could be setup like this:
1. Open a terminal window, navigate to the RIOT directory, and enter
`dist/tools/tapsetup/tapsetup -c`.
2. Open a second terminal window and navigate to this directory in both of
windows.
3. Call `make -B clean all term` in the first terminal and `PORT=tap1 make
term` in the second one.
4. Enter `open 3` in both terminals.
5. Enter `ccnl_cont /riot/peter/schmerzl Hello World! Hello RIOT!` on the first
terminal.
6. Enter `ccnl_int /riot/peter/schmerzl` in the second terminal.
7. See the content being displayed. Be happy!
## Wireshark dissector
One can use the Wireshark dissector from the named-data project
(https://github.com/named-data/ndn-tools/tree/master/tools/dissect-wireshark)
for analyzing the traffic in Wireshark.
However, please note, that - in order to be compatible with the default
CCN-Lite upstream configuration - a different Ethertype (`0x0801` instead of
`0x8624`) is used.
The simplest way to get this working is to copy the `ndn.lua` file into your
local Wireshark plugin directory (e.g. `$HOME/.wireshark/plugins`) and update
https://github.com/named-data/ndn-tools/blob/master/tools/dissect-wireshark/ndn.lua#L408
to `0x0801).

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2015 Inria
*
* 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.
*/
#include <stdio.h>
#include <string.h>
#include "ccn-lite-riot.h"
#include "ccnl-pkt-ndntlv.h"
#include "ccnl-defs.h"
#include "ccnl-ext.h"
#include "ccnl-pkt-ndntlv.h"
#define MAX_CONTENT (64)
static char *_default_content = "Start the RIOT!";
static unsigned char _out[CCNL_MAX_PACKET_SIZE];
static void _usage(char *argv)
{
printf("usage: %s <URI> [content]\n"
"%% %s /riot/peter/schmerzl (default content)\n"
"%% %s /riot/peter/schmerzl RIOT\n",
argv, argv, argv);
}
int _ccnl_content(int argc, char **argv)
{
char *body = _default_content;
int arg_len = strlen(_default_content) + 1;
int offs = CCNL_MAX_PACKET_SIZE;
if (argc < 2) {
_usage(argv[0]);
return -1;
}
if (argc > 2) {
char buf[MAX_CONTENT];
memset(buf, ' ', MAX_CONTENT);
char *buf_ptr = buf;
for (int i = 2; (i < argc) && (buf_ptr < (buf + MAX_CONTENT)); i++) {
arg_len = strlen(argv[i]);
if ((buf_ptr + arg_len) > (buf + MAX_CONTENT)) {
arg_len = (buf + MAX_CONTENT) - buf_ptr;
}
strncpy(buf_ptr, argv[i], arg_len);
buf_ptr += arg_len + 1;
}
*buf_ptr = '\0';
body = buf;
arg_len = strlen(body);
}
int suite = CCNL_SUITE_NDNTLV;
struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(argv[1], suite, NULL, NULL);
arg_len = ccnl_ndntlv_prependContent(prefix, (unsigned char*) body, arg_len, NULL, NULL, &offs, _out);
unsigned char *olddata;
unsigned char *data = olddata = _out + offs;
int len;
unsigned typ;
if (ccnl_ndntlv_dehead(&data, &arg_len, (int*) &typ, &len) ||
typ != NDN_TLV_Data) {
return -1;
}
struct ccnl_content_s *c = 0;
struct ccnl_pkt_s *pk = ccnl_ndntlv_bytes2pkt(typ, olddata, &data, &arg_len);
c = ccnl_content_new(&theRelay, &pk);
ccnl_content_add2cache(&theRelay, c);
c->flags |= CCNL_CONTENT_FLAGS_STATIC;
return 0;
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (C) 2013-15, Christian Tschudin, University of Basel
* Copyright (C) 2015, Oliver Hahm, Inria
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* File history:
* 2015-11-09 created (based on ccn-lite-peek.c)
*/
#include <unistd.h>
#include "random.h"
#include "xtimer.h"
#include "timex.h"
#include "arpa/inet.h"
#include "net/packet.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/netapi.h"
#include "ccn-lite-riot.h"
#include "ccnl-core.h"
#include "ccnl-headers.h"
#include "ccnl-pkt-ndntlv.h"
#include "ccnl-defs.h"
#include "ccnl-ext.h"
#include "ccnl-pkt-ccntlv.h"
/**
* Maximum number of Interest retransmissions
*/
#define CCNL_INTEREST_RETRIES (3)
#define MAX_ADDR_LEN (8U)
#define BUF_SIZE (128)
static unsigned char _int_buf[BUF_SIZE];
static unsigned char _cont_buf[BUF_SIZE];
static void _usage(char *arg)
{
printf("usage: %s <URI> [relay]\n"
"%% %s /riot/peter/schmerzl (classic lookup)\n",
arg, arg);
}
int _ccnl_interest(int argc, char **argv)
{
if (argc < 2) {
_usage(argv[0]);
return -1;
}
/* XXX: https://xkcd.com/221/ */
genrand_init(0x4);
/* initialize address with 0xFF for broadcast */
size_t addr_len = MAX_ADDR_LEN;
uint8_t relay_addr[MAX_ADDR_LEN];
memset(relay_addr, UINT8_MAX, MAX_ADDR_LEN);
if (argc > 2) {
addr_len = gnrc_netif_addr_from_str(relay_addr, sizeof(relay_addr), argv[2]);
}
for (int cnt = 0; cnt < CCNL_INTEREST_RETRIES; cnt++) {
ccnl_send_interest(CCNL_SUITE_NDNTLV, argv[1], relay_addr, addr_len, NULL, _int_buf, BUF_SIZE);
ccnl_wait_for_chunk(_cont_buf, BUF_SIZE);
}
return 0;
}

View File

@ -0,0 +1,109 @@
/*
* Copyright (C) 2015 Inria
*
* 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 Basic ccn-lite relay example (produce and consumer via shell)
*
* @author Oliver Hahm <oliver.hahm@inria.fr>
*
* @}
*/
#include <stdio.h>
#include "thread.h"
#include "msg.h"
#include "timex.h"
#include "shell_commands.h"
#include "net/packet.h"
#include "net/netopt.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netapi.h"
#include "ccn-lite-riot.h"
#include "ccnl-core.h"
#include "ccnl-headers.h"
#include "ccnl-pkt-ndntlv.h"
#include "ccnl-defs.h"
#include "net/gnrc/nettype.h"
/* main thread's message queue */
#define MAIN_QUEUE_SIZE (8)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
/* check for one-time initialization */
static bool started = false;
/* shell command functions */
static int _ccnl_open(int argc, char **argv);
extern int _ccnl_content(int argc, char **argv);
extern int _ccnl_interest(int argc, char **argv);
static const shell_command_t shell_commands[] = {
{ "open", "opens an interface or socket", _ccnl_open},
{ "interest", "sends an interest", _ccnl_interest},
{ "content", "create content and populated it", _ccnl_content},
{ NULL, NULL, NULL }
};
/* usage for open command */
static void _usage(void)
{
puts("ccnl <interface>");
}
static int _ccnl_open(int argc, char **argv)
{
/* check if already running */
if (started) {
puts("Already opened an interface for CCN!");
return -1;
}
/* check if parameter is given */
if (argc != 2) {
_usage();
return -1;
}
/* check if given number is a valid netif PID */
int pid = atoi(argv[1]);
if (!gnrc_netif_exist(pid)) {
printf("%i is not a valid interface!\n", pid);
return -1;
}
ccnl_start();
/* set the relay's PID, configure the interface to interface to use CCN
* nettype */
if (ccnl_open_netif(pid, GNRC_NETTYPE_CCN) < 0) {
puts("Error registering at network interface!");
return -1;
}
started = true;
return 0;
}
int main(void)
{
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
puts("Basic CCN-Lite example");
ccnl_core_init();
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
return 0;
}

View File

@ -110,25 +110,34 @@ extern "C" {
*/
#define CONSTSTR(s) s
/**
* Stack size for CCN-Lite event loop
*/
#define CCNL_STACK_SIZE (THREAD_STACKSIZE_MAIN)
/**
* Size of the message queue of CCN-Lite's event loop
*/
#define CCNL_QUEUE_SIZE (8)
/**
* Struct holding CCN-Lite's central relay information
*/
extern struct ccnl_relay_s theRelay;
/**
* @brief The main CCN-Lite event-loop
* @brief Start the main CCN-Lite event-loop
*
* @note This function does not terminate
*
* @param[in] ccnl Reference to the CCN-Lite relay
* @return The PID of the event-loop's thread
*/
void ccnl_event_loop(struct ccnl_relay_s *ccnl);
kernel_pid_t ccnl_start(void);
/**
* @brief Opens a @ref gnrc_netif_t device for use with CCN-Lite
* @brief Opens a @ref net_gnrc_netif device for use with CCN-Lite
*
* @param[in] if_pid The pid of the @ref gnrc_netif_t device driver
* @param[in] netreg_type The @ref gnrc_nettype_t @p if_pid should be configured to use
* @param[in] if_pid The pid of the @ref net_gnrc_netif device driver
* @param[in] netreg_type The @ref net_gnrc_nettype @p if_pid should be
* configured to use
*
* @return 0 on success,
* @return -EINVAL if eventloop could not be registered for @p netreg_type