diff --git a/doc/doxygen/riot.doxyfile b/doc/doxygen/riot.doxyfile index e7ea3d1324c9ce1dcafb37725adfaf8225e3acbe..8b21edbc74c46a9c2d56ca5cc0e1c13c6bd2424a 100644 --- a/doc/doxygen/riot.doxyfile +++ b/doc/doxygen/riot.doxyfile @@ -759,6 +759,7 @@ INPUT = ../../doc.txt \ ../../boards \ ../../drivers \ ../../sys \ + ../../pkg \ src/ \ src/mainpage.md \ src/getting-started.md @@ -836,6 +837,8 @@ EXCLUDE_PATTERNS = */board/*/tools/* \ */cpu/kw2x/include/MKW22D5.h \ */cpu/k64f/include/MK64F12.h \ */cpu/ezr32wg/include/ezr* \ + */pkg/*/*/* \ + */pkg/tlsf/patch.txt \ # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names diff --git a/examples/ccn-lite-relay/Makefile b/examples/ccn-lite-relay/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3e38084114d667ee2ee5e45621a86a27156c1243 --- /dev/null +++ b/examples/ccn-lite-relay/Makefile @@ -0,0 +1,44 @@ +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 + + +ifneq (,$(filter-out native,$(BOARD))) + USEPKG += tlsf +endif + +USEPKG += ccn-lite +USEMODULE += ccn-lite-utils + +include $(RIOTBASE)/Makefile.include diff --git a/examples/ccn-lite-relay/README.md b/examples/ccn-lite-relay/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b053cba4681c5ab20547be4042c050d6b5cfc47b --- /dev/null +++ b/examples/ccn-lite-relay/README.md @@ -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). diff --git a/examples/ccn-lite-relay/main.c b/examples/ccn-lite-relay/main.c new file mode 100644 index 0000000000000000000000000000000000000000..4ff2f121921576efcc39ac9c09053645b52ced2f --- /dev/null +++ b/examples/ccn-lite-relay/main.c @@ -0,0 +1,56 @@ +/* + * 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> + +/* TODO: currently TLSF has to be disabled for native because of its stricter + * CFLAGS (-pedantic) */ +#ifndef BOARD_NATIVE +# include "tlsf-malloc.h" +#endif +#include "msg.h" +#include "shell.h" +#include "ccn-lite-riot.h" + +/* main thread's message queue */ +#define MAIN_QUEUE_SIZE (8) +static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; + +#ifndef BOARD_NATIVE + /* some buffer for the heap */ +# define TLSF_BUFFER (10240 / sizeof(uint32_t)) + static uint32_t _tlsf_heap[TLSF_BUFFER]; +#endif + +int main(void) +{ +#ifndef BOARD_NATIVE + tlsf_add_pool(_tlsf_heap, sizeof(_tlsf_heap)); +#endif + 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(NULL, line_buf, SHELL_DEFAULT_BUFSIZE); + return 0; +} diff --git a/pkg/ccn-lite/Makefile b/pkg/ccn-lite/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e703d8a48041c3cb5c2f491fbe05220d4ff5ca43 --- /dev/null +++ b/pkg/ccn-lite/Makefile @@ -0,0 +1,36 @@ +PKG_NAME=ccn-lite +PKG_URL=https://github.com/OlegHahm/ccn-lite/ +PKG_VERSION=riot_integration_preparation +PKG_DIR=$(CURDIR)/$(PKG_NAME) + +ifneq ($(RIOTBOARD),) +include $(RIOTBOARD)/$(BOARD)/Makefile.include +endif + +.PHONY: all clean distclean + +export RIOT_CFLAGS = ${CFLAGS} ${INCLUDES} + +all: $(PKG_DIR)/Makefile + "$(MAKE)" -C $(PKG_DIR)/src lib-ccn-lite.a + "$(MAKE)" -C $(PKG_DIR)/src lib-ccn-lite-utils.a + cp $(PKG_DIR)/src/lib-ccn-lite.a ${BINDIR}/ccn-lite.a + cp $(PKG_DIR)/src/lib-ccn-lite-utils.a ${BINDIR}/ccn-lite-utils.a + +$(PKG_DIR)/Makefile: $(PKG_DIR)/.git/config + +$(PKG_DIR)/.git/config: + test -d "$(PKG_DIR)" || git clone "$(PKG_URL)" "$(PKG_DIR)"; \ + cd "$(PKG_DIR)" && git checkout -f "$(PKG_VERSION)" + +clean:: + @echo "Cleaning up CCN-Lite package..." + @cd "$(PKG_DIR)" 2> /dev/null > /dev/null && \ + git clean -x -f && \ + git reset --hard "$(PKG_VERSION)" + +distclean:: + rm -rf "$(PKG_DIR)" + +Makefile.include: + @true diff --git a/pkg/ccn-lite/Makefile.include b/pkg/ccn-lite/Makefile.include new file mode 100644 index 0000000000000000000000000000000000000000..4751bbd9265ed32dcbea16a07fb21c939c76274c --- /dev/null +++ b/pkg/ccn-lite/Makefile.include @@ -0,0 +1,2 @@ +INCLUDES += -I$(RIOTBASE)/pkg/ccn-lite -I$(RIOTBASE)/pkg/ccn-lite/ccn-lite/src +INCLUDES += -I$(RIOTBASE)/sys/posix/include diff --git a/pkg/ccn-lite/ccn-lite-riot.h b/pkg/ccn-lite/ccn-lite-riot.h new file mode 100644 index 0000000000000000000000000000000000000000..b9144dba8c4196528d3522c19cfd53083d0c440f --- /dev/null +++ b/pkg/ccn-lite/ccn-lite-riot.h @@ -0,0 +1,177 @@ +/* + * 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. + */ + +#ifndef CCN_LITE_RIOT_H +#define CCN_LITE_RIOT_H + +/** + * @defgroup pkg_ccnlite CCN-Lite stack + * @ingroup pkg + * @brief Provides a NDN implementation + * + * This package provides the CCN-Lite stack as a port of NDN for RIOT. + * + * @{ + */ + +/** + * Use RIOT specific configuration in CCN-Lite + */ +#define CCNL_RIOT + +#include <unistd.h> +#include "kernel_types.h" +#include "arpa/inet.h" +#include "net/packet.h" +#include "net/ethernet/hdr.h" +#include "sys/socket.h" +#include "ccnl-defs.h" +#include "ccnl-core.h" +#include "ccnl-headers.h" +#include "net/gnrc/netreg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Define the log level of the CCN-Lite stack + */ +#define LOG_LEVEL LOG_DEBUG +#include "log.h" + +/** + * @name Dynamic memory allocation used in CCN-Lite + * + * @{ + */ +#define ccnl_malloc(s) malloc(s) +#define ccnl_calloc(n,s) calloc(n,s) +#define ccnl_realloc(p,s) realloc(p,s) +#define ccnl_free(p) free(p) +/** + * @} + */ + +/** + * Closing an interface or socket from CCN-Lite + */ +#define ccnl_close_socket(s) close(s) + +/** + * @name Log levels used by CCN-Lite debugging + * + * @{ + */ +#define FATAL LOG_ERROR +#define ERROR LOG_ERROR +#define WARNING LOG_WARNING +#define INFO LOG_INFO +#define DEBUG LOG_DEBUG +#define TRACE LOG_DEBUG +#define VERBOSE LOG_ALL +/** + * @} + */ + +/** + * @name CCN-Lite's debugging macros + * + * @{ + */ +#define DEBUGMSG(LVL, ...) do { \ + if ((LVL)>debug_level) break; \ + LOG(LVL, __VA_ARGS__); \ + } while (0) + +#define DEBUGMSG_CORE(...) DEBUGMSG(__VA_ARGS__) +#define DEBUGMSG_CFWD(...) DEBUGMSG(__VA_ARGS__) +#define DEBUGMSG_CUTL(...) DEBUGMSG(__VA_ARGS__) +#define DEBUGMSG_PIOT(...) DEBUGMSG(__VA_ARGS__) + +#define DEBUGSTMT(LVL, ...) do { \ + if ((LVL)>debug_level) break; \ + __VA_ARGS__; \ + } while (0) + +#define TRACEIN(...) do {} while(0) +#define TRACEOUT(...) do {} while(0) +/** + * @} + */ + +/** + * Constant string + */ +#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 Start the main CCN-Lite event-loop + * + * @return The PID of the event-loop's thread + */ +kernel_pid_t ccnl_start(void); + +/** + * @brief Opens a @ref net_gnrc_netif device for use with CCN-Lite + * + * @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 + */ +int ccnl_open_netif(kernel_pid_t if_pid, gnrc_nettype_t netreg_type); + +/** + * @brief Sends out an Interest + * + * @param[in] suite CCN packet format + * @param[in] name The name that is requested + * @param[in] addr The relay's address to send to + * @param[in] addr_len Length of @p addr + * @param[in] chunknum Number of the requested content chunk + * @param[out] buf Buffer to write the content chunk to + * @param[in] buf_len Size of @p buf + * + * @return 0 on successfully sent Interest + * @return -1 if Interested couldn't be sent + */ +int ccnl_send_interest(int suite, char *name, uint8_t *addr, size_t addr_len, + unsigned int *chunknum, unsigned char *buf, + size_t buf_len); + +/** + * @brief Waits for incoming content chunk + * + * @return 0 if a content was received + * @return -ETIMEDOUT if no chunk was received until timeout + */ +int ccnl_wait_for_chunk(void *buf, size_t buf_len); + +#ifdef __cplusplus +} +#endif +#endif /* CCN_LITE_RIOT_H */ +/** @} */ diff --git a/pkg/doc.txt b/pkg/doc.txt new file mode 100644 index 0000000000000000000000000000000000000000..d97acce3eb6c1a0ba5dff42d7d2b76f84f5f3e6d --- /dev/null +++ b/pkg/doc.txt @@ -0,0 +1,15 @@ +/* + * 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. + */ + +/** + * @defgroup pkg Packages + * @brief RIOT supports the integration of external libraries. These + * libraries can be used as BSD-like packages, i.e. they are + * downloaded automatically at compile-time (if needed) and linked + * against RIOT. + */ diff --git a/sys/include/net/af.h b/sys/include/net/af.h index 925dee5405bc5ce0efaad319b2f5cc4798d4b7ce..ff4017d3cb89d12c83de73e1af5d3bf11250bf03 100644 --- a/sys/include/net/af.h +++ b/sys/include/net/af.h @@ -31,6 +31,8 @@ enum { #define AF_UNSPEC AF_UNSPEC /**< unspecified address family (as macro) */ AF_UNIX, /**< local to host (pipes, portals) address family. */ #define AF_UNIX AF_UNIX /**< unspecified address family (as macro) */ + AF_PACKET, /**< packet family */ +#define AF_PACKET AF_PACKET /**< packet family (as macro) */ AF_INET, /**< internetwork address family: UDP, TCP, etc. */ #define AF_INET AF_INET /**< internetwork address family: UDP, TCP, etc. (as macro) */ AF_INET6, /**< internetwork address family with IPv6: UDP, TCP, etc. */ diff --git a/sys/include/net/ethernet/hdr.h b/sys/include/net/ethernet/hdr.h index 6860afcfe488bcf80e5f2c7c375de504ae5c8fe2..ec39186ad1c092b401ca1833ab29af1aa9b5217d 100644 --- a/sys/include/net/ethernet/hdr.h +++ b/sys/include/net/ethernet/hdr.h @@ -32,6 +32,12 @@ extern "C" { #define ETHERNET_ADDR_LEN (6) /**< Length of an Ethernet address */ +#ifndef ETH_ALEN +#define ETH_ALEN ETHERNET_ADDR_LEN /**< convenient alias for @ref + ETHERNET_ADDR_LEN to comply with + *NIX code */ +#endif + /** * @brief Ethernet header */ diff --git a/sys/include/net/ethertype.h b/sys/include/net/ethertype.h index 8ca3f408ad3860d8e6e17667ce60a133d1a21304..1f823f7899c2bcb1eb0f8128229b746177523434 100644 --- a/sys/include/net/ethertype.h +++ b/sys/include/net/ethertype.h @@ -34,6 +34,7 @@ extern "C" { #define ETHERTYPE_RESERVED (0x0000) /**< Reserved */ #define ETHERTYPE_IPV4 (0x0800) /**< Internet protocol version 4 */ #define ETHERTYPE_ARP (0x0806) /**< Address resolution protocol */ +#define ETHERTYPE_NDN (0x0801) /**< Parc CCNX */ #define ETHERTYPE_IPV6 (0x86dd) /**< Internet protocol version 6 */ #define ETHERTYPE_UNKNOWN (0xffff) /**< Reserved (no protocol specified) */ diff --git a/sys/include/net/gnrc/nettype.h b/sys/include/net/gnrc/nettype.h index 110dfd67f9ad745ed9334db91335bedec454c68b..635909b551ee3e8cec97f3d14b77b50af5c1aa96 100644 --- a/sys/include/net/gnrc/nettype.h +++ b/sys/include/net/gnrc/nettype.h @@ -84,6 +84,11 @@ typedef enum { * @} */ +#ifdef MODULE_CCN_LITE + GNRC_NETTYPE_CCN, /**< Protocol is CCN */ + GNRC_NETTYPE_CCN_CHUNK, /**< Protocol is CCN, packet contains a content + chunk */ +#endif /** * @{ @@ -113,6 +118,10 @@ static inline gnrc_nettype_t gnrc_nettype_from_ethertype(uint16_t type) #ifdef MODULE_GNRC_IPV6 case ETHERTYPE_IPV6: return GNRC_NETTYPE_IPV6; +#endif +#ifdef MODULE_CCN_LITE + case ETHERTYPE_NDN: + return GNRC_NETTYPE_CCN; #endif default: return GNRC_NETTYPE_UNDEF; @@ -136,6 +145,10 @@ static inline uint16_t gnrc_nettype_to_ethertype(gnrc_nettype_t type) #ifdef MODULE_GNRC_IPV6 case GNRC_NETTYPE_IPV6: return ETHERTYPE_IPV6; +#endif +#ifdef MODULE_CCN_LITE + case GNRC_NETTYPE_CCN: + return ETHERTYPE_NDN; #endif default: return ETHERTYPE_UNKNOWN; diff --git a/sys/include/net/packet.h b/sys/include/net/packet.h new file mode 100644 index 0000000000000000000000000000000000000000..043f58852a079d6a421fd643f21879259f3f49f0 --- /dev/null +++ b/sys/include/net/packet.h @@ -0,0 +1,48 @@ +/* + * 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. + */ + +/** + * @defgroup net_packet Packet interface on device level + * @ingroup net + * @brief Packet address family definitions + * @{ + * + * @file + * @brief Defines the struct for @ref AF_PACKET sockets + * + * @author Oliver Hahm <oliver.hahm@inria.fr> + */ + +#ifndef PACKET_H +#define PACKET_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Link-Layer socket descriptor + */ +struct sockaddr_ll { + unsigned short sll_family; /**< Always AF_PACKET */ + unsigned short sll_protocol; /**< Physical-layer protocol */ + int sll_ifindex; /**< Interface number */ + unsigned short sll_hatype; /**< ARP hardware type */ + unsigned char sll_pkttype; /**< Packet type */ + unsigned char sll_halen; /**< Length of address */ + unsigned char sll_addr[8]; /**< Physical-layer address */ +}; + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ +#endif /* PACKET_H */ diff --git a/sys/shell/commands/Makefile b/sys/shell/commands/Makefile index 4b283a1a50c58c763556412cb043b4746e6a6b61..616c5fb5e9ffbb9183ebc5873f8e06375be09f10 100644 --- a/sys/shell/commands/Makefile +++ b/sys/shell/commands/Makefile @@ -60,6 +60,9 @@ endif ifneq (,$(filter saul_reg,$(USEMODULE))) SRC += sc_saul_reg.c endif +ifneq (,$(filter ccn-lite-utils,$(USEMODULE))) + SRC += sc_ccnl.c +endif # TODO # Conditional building not possible at the moment due to diff --git a/sys/shell/commands/sc_ccnl.c b/sys/shell/commands/sc_ccnl.c new file mode 100644 index 0000000000000000000000000000000000000000..fb61e65062321bc6672dd5cef1daccf535af52a1 --- /dev/null +++ b/sys/shell/commands/sc_ccnl.c @@ -0,0 +1,179 @@ +/* + * 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 sys_shell_commands + * @{ + * + * @file + * @brief Shell commands to interact with the CCN-Lite stack + * + * @author Oliver Hahm <oliver.hahm@inria.fr> + * + * @} + */ + +#include "random.h" +#include "net/gnrc/netif.h" +#include "ccn-lite-riot.h" +#include "ccnl-pkt-ndntlv.h" + +#define MAX_CONTENT (64) + +/** + * 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 char *_default_content = "Start the RIOT!"; +static unsigned char _out[CCNL_MAX_PACKET_SIZE]; + +/* check for one-time initialization */ +static bool started = false; + +/* usage for open command */ +static void _open_usage(void) +{ + puts("ccnl <interface>"); +} + +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) { + _open_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; +} + + +static void _content_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) { + _content_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; +} + +static void _interest_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) { + _interest_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; +} diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index b21f82005a74f93617ada6db88fc07e7d6201f7f..32aa16702cbfaf544c2f7d4e4c85dafde273e2ad 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -118,6 +118,12 @@ extern int _gnrc_6ctx(int argc, char **argv); #endif #endif +#ifdef MODULE_CCN_LITE_UTILS +extern int _ccnl_open(int argc, char **argv); +extern int _ccnl_content(int argc, char **argv); +extern int _ccnl_interest(int argc, char **argv); +#endif + const shell_command_t _shell_command_list[] = { {"reboot", "Reboot the node", _reboot_handler}, #ifdef MODULE_CONFIG @@ -193,6 +199,11 @@ const shell_command_t _shell_command_list[] = { #endif #ifdef MODULE_SAUL_REG {"saul", "interact with sensors and actuators using SAUL", _saul }, +#endif +#ifdef MODULE_CCN_LITE_UTILS + { "ccnl_open", "opens an interface or socket", _ccnl_open}, + { "ccnl_int", "sends an interest", _ccnl_interest}, + { "ccnl_cont", "create content and populated it", _ccnl_content}, #endif {NULL, NULL, NULL} };