Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ For links go to [https://github.com/RIOT-OS/Tutorials](https://github.com/RIOT-O
* [Task 5: Using network devices](task-05/)
* [Task 6: Sending and receiving UDP packets](task-06/)
* [Task 7: The GNRC network stack](task-07/)
* [Task 8: CCN-Lite on RIOT](task-08/)
* [Task 9: RIOT and RPL](task-09/)

## Troubleshooting

Expand Down
2 changes: 2 additions & 0 deletions task-07/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ gnrc_pktbuf_release(pkt);
* Send your neighbor some messages using `udp send`

[Read the Doc](http://doc.riot-os.org/group__net__gnrc.html)

[next task](../task-08)
1 change: 1 addition & 0 deletions task-08/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,4 @@ RIOT provides three shell to interact with the CCN-Lite stack:
(see [http://doc.riot-os.org/group__pkg__ccnlite.html](http://doc.riot-os.org/group__pkg__ccnlite.html)
* Use `ccnl_set_local_producer()` to create content on the fly

[next task](../task-09)
57 changes: 57 additions & 0 deletions task-09/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# name of your application
APPLICATION = task-09

# 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)/../RIOT

BOARD_INSUFFICIENT_MEMORY := airfy-beacon chronos msb-430 msb-430h nrf51dongle \
nrf6310 nucleo-f103 nucleo-f334 pca10000 pca10005 spark-core \
stm32f0discovery telosb weio wsn430-v1_3b wsn430-v1_4 \
yunjia-nrf51822 z1 nucleo-f072

# 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_netdev_default
USEMODULE += auto_init_gnrc_netif
# Specify the mandatory networking modules for IPv6 and UDP
USEMODULE += gnrc_ipv6_router_default
USEMODULE += gnrc_udp
# Add a routing protocol
USEMODULE += gnrc_rpl
USEMODULE += auto_init_gnrc_rpl
# This application dumps received packets to STDIO using the pktdump module
USEMODULE += gnrc_pktdump
# Additional networking modules that can be dropped if not needed
USEMODULE += gnrc_icmpv6_echo
# Add also the shell, some shell commands
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps
USEMODULE += netstats_l2
USEMODULE += netstats_ipv6
USEMODULE += netstats_rpl

# Set a custom 802.15.4 channel if needed
DEFAULT_CHANNEL ?= 26
CFLAGS += -DDEFAULT_CHANNEL=$(DEFAULT_CHANNEL)

CFLAGS += -DGNRC_RPL_LIFETIME_UNIT=1 -DGNRC_RPL_DEFAULT_LIFETIME=32
CFLAGS += -DGNRC_RPL_REGULAR_DAO_INTERVAL=13
CFLAGS += -DGNRC_RPL_DEFAULT_DIO_INTERVAL_DOUBLINGS=13

# 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:
CFLAGS += -DDEVELHELP

# Comment this out to join RPL DODAGs even if DIOs do not contain
# DODAG Configuration Options (see the doc for more info)
# CFLAGS += -DGNRC_RPL_DODAG_CONF_OPTIONAL_ON_JOIN

# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1

include $(RIOTBASE)/Makefile.include
52 changes: 52 additions & 0 deletions task-09/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
[previous task](../task-08)

# Task 9: RIOT and RPL

This task will demonstrate basic routing functionalities in RIOT provided by the [RPL](https://tools.ietf.org/html/rfc6550) (IPv6 Routing Protocol for Low-Power and Lossy Networks) routing protocol and multihop communication.

It uses an adapted version of the default [`gnrc_networking`](https://github.com/RIOT-OS/RIOT/tree/master/examples/gnrc_networking) example in the RIOT repository.

## Prerequisites

* Compile the application and run on your `BOARD`
* For this task you need at least three boards (you can form groups with your neighbors)
* Each "group" should change to an individual RF channel. It can be changed by e.g.

```
ifconfig <if_id> set chan 11

```

Use the `ifconfig` command to obtain the `<id_id>`.

* Check if this worked by looking at the output of `ifconfig` again. Also have a look at the preconfigured IPv6 addresses that all have a local scope.


## Task 9.1: Initialize RPL

* In order to use RPL we have to choose **one** RPL root node and configure a global IPv6 address for it. This is simply done by adding the address to the network interface (`<if_id>`) via `ifconfig`:

```
ifconfig <if_id> add 2001:db8::1
```

* To start the routing process and the generation of a RPL DODAG (Destination Oriented Directed Acyclic Graph), we need to start the root node with an Instance ID (here `1`) and a DODAG ID (here its global IPv6 address)

```
rpl root 1 2001:db8::1
```

## Analyse the topology

* On not-root nodes, look at the output of `ifconfig` again. You should see that a global unicast IPv6 address has been set automatically.

* Typing `rpl` gives you some information about the nodes position in the DODAG. Check the local IPv6 address of the selected parent node. Look for value `R:` which describes the "rank" or more general, the position in the DODAG according to the metric. What is the increment for one hop?

* RPL fills the FIB (Forwarding Information Base) table which is consulted when forwarding packets. Check the entries on the root node and see the relation between the destination and next hop addresses.


## Pinging "distant" nodes

* Use the ping6 command to ping global address of a "distant" node.
* Most likely, in this setup the root node will be the only intermediate hop. It should print some rough information about forwarding IPv6 packets
* Additionally you can try to transmit UDP packets (explore the `udp` commandset)
112 changes: 112 additions & 0 deletions task-09/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
* Copyright (C) 2016 Hochschule für Angewandte Wissenschaften 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 Example application for demonstrating the RIOT network stack
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
*
* @}
*/

#include <stdio.h>

#include "shell.h"
#include "msg.h"
#include "thread.h"

#include "net/gnrc.h"
#include "net/gnrc/ipv6/netif.h"
#include "net/gnrc/ipv6.h"

#define MAIN_QUEUE_SIZE (8)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];

extern int udp_cmd(int argc, char **argv);

static const shell_command_t shell_commands[] = {
{ "udp", "send data over UDP and listen on UDP ports", udp_cmd },
{ NULL, NULL, NULL }
};

#ifdef MODULE_GNRC_SIXLOWPAN
static char _stack[THREAD_STACKSIZE_MAIN];

static void *_ipv6_fwd_eventloop(void *arg)
{
(void)arg;

msg_t msg, msg_q[8];
gnrc_netreg_entry_t me_reg;

msg_init_queue(msg_q, 8);

me_reg.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL;
me_reg.pid = thread_getpid();

gnrc_netreg_register(GNRC_NETTYPE_SIXLOWPAN, &me_reg);

while(1) {
msg_receive(&msg);
gnrc_pktsnip_t *pkt = msg.content.ptr;
if(msg.type == GNRC_NETAPI_MSG_TYPE_SND) {
gnrc_pktsnip_t *ipv6 = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6);
ipv6 = ipv6->data;

ipv6_hdr_t *ipv6_hdr =(ipv6_hdr_t *)ipv6;

/* get the first IPv6 interface and prints its address */
kernel_pid_t ifs[GNRC_NETIF_NUMOF];
gnrc_netif_get(ifs);
gnrc_ipv6_netif_t *entry = gnrc_ipv6_netif_get(ifs[0]);
for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) {
if ( (!ipv6_addr_is_link_local(&entry->addrs[i].addr)) && (!ipv6_addr_is_link_local(&ipv6_hdr->src))
&& (!ipv6_addr_is_link_local(&ipv6_hdr->dst)) && !(entry->addrs[i].flags & GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST)
&& (!ipv6_addr_is_unspecified(&entry->addrs[i].addr)) ) {

if(!ipv6_addr_equal(&entry->addrs[i].addr, &(ipv6_hdr->src))){

char addr_str[IPV6_ADDR_MAX_STR_LEN];
printf("IPv6 ROUTER: forward from src = %s ", ipv6_addr_to_str(addr_str, &(ipv6_hdr->src), sizeof(addr_str)) );
printf("to dst = %s\n",ipv6_addr_to_str(addr_str, &(ipv6_hdr->dst), sizeof(addr_str)));
}
}
}
}
gnrc_pktbuf_release(pkt);
}
/* never reached */
return NULL;
}
#endif

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("RIOT network stack example application");

#ifdef MODULE_GNRC_SIXLOWPAN
thread_create(_stack, sizeof(_stack), (THREAD_PRIORITY_MAIN - 4),
THREAD_CREATE_STACKTEST, _ipv6_fwd_eventloop, NULL, "ipv6_fwd");
#endif
/* start shell */
puts("All up, running the shell now");
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);

/* should be never reached */
return 0;
}
Loading