Skip to content

Commit d1f3934

Browse files
authored
Merge pull request #18 from PeterKietzmann/add_rpl_task
Initial import of task-09 (basic RPL)
2 parents 43edeae + 0578680 commit d1f3934

7 files changed

Lines changed: 399 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ For links go to [https://github.com/RIOT-OS/Tutorials](https://github.com/RIOT-O
4949
* [Task 5: Using network devices](task-05/)
5050
* [Task 6: Sending and receiving UDP packets](task-06/)
5151
* [Task 7: The GNRC network stack](task-07/)
52+
* [Task 8: CCN-Lite on RIOT](task-08/)
53+
* [Task 9: RIOT and RPL](task-09/)
5254

5355
## Troubleshooting
5456

task-07/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,5 @@ gnrc_pktbuf_release(pkt);
6464
* Send your neighbor some messages using `udp send`
6565
6666
[Read the Doc](http://doc.riot-os.org/group__net__gnrc.html)
67+
68+
[next task](../task-08)

task-08/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@ RIOT provides three shell to interact with the CCN-Lite stack:
4949
(see [http://doc.riot-os.org/group__pkg__ccnlite.html](http://doc.riot-os.org/group__pkg__ccnlite.html)
5050
* Use `ccnl_set_local_producer()` to create content on the fly
5151

52+
[next task](../task-09)

task-09/Makefile

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# name of your application
2+
APPLICATION = task-09
3+
4+
# If no BOARD is found in the environment, use this default:
5+
BOARD ?= native
6+
7+
# This has to be the absolute path to the RIOT base directory:
8+
RIOTBASE ?= $(CURDIR)/../RIOT
9+
10+
BOARD_INSUFFICIENT_MEMORY := airfy-beacon chronos msb-430 msb-430h nrf51dongle \
11+
nrf6310 nucleo-f103 nucleo-f334 pca10000 pca10005 spark-core \
12+
stm32f0discovery telosb weio wsn430-v1_3b wsn430-v1_4 \
13+
yunjia-nrf51822 z1 nucleo-f072
14+
15+
# Include packages that pull up and auto-init the link layer.
16+
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
17+
USEMODULE += gnrc_netdev_default
18+
USEMODULE += auto_init_gnrc_netif
19+
# Specify the mandatory networking modules for IPv6 and UDP
20+
USEMODULE += gnrc_ipv6_router_default
21+
USEMODULE += gnrc_udp
22+
# Add a routing protocol
23+
USEMODULE += gnrc_rpl
24+
USEMODULE += auto_init_gnrc_rpl
25+
# This application dumps received packets to STDIO using the pktdump module
26+
USEMODULE += gnrc_pktdump
27+
# Additional networking modules that can be dropped if not needed
28+
USEMODULE += gnrc_icmpv6_echo
29+
# Add also the shell, some shell commands
30+
USEMODULE += shell
31+
USEMODULE += shell_commands
32+
USEMODULE += ps
33+
USEMODULE += netstats_l2
34+
USEMODULE += netstats_ipv6
35+
USEMODULE += netstats_rpl
36+
37+
# Set a custom 802.15.4 channel if needed
38+
DEFAULT_CHANNEL ?= 26
39+
CFLAGS += -DDEFAULT_CHANNEL=$(DEFAULT_CHANNEL)
40+
41+
CFLAGS += -DGNRC_RPL_LIFETIME_UNIT=1 -DGNRC_RPL_DEFAULT_LIFETIME=32
42+
CFLAGS += -DGNRC_RPL_REGULAR_DAO_INTERVAL=13
43+
CFLAGS += -DGNRC_RPL_DEFAULT_DIO_INTERVAL_DOUBLINGS=13
44+
45+
# Comment this out to disable code in RIOT that does safety checking
46+
# which is not needed in a production environment but helps in the
47+
# development process:
48+
CFLAGS += -DDEVELHELP
49+
50+
# Comment this out to join RPL DODAGs even if DIOs do not contain
51+
# DODAG Configuration Options (see the doc for more info)
52+
# CFLAGS += -DGNRC_RPL_DODAG_CONF_OPTIONAL_ON_JOIN
53+
54+
# Change this to 0 show compiler invocation lines by default:
55+
QUIET ?= 1
56+
57+
include $(RIOTBASE)/Makefile.include

task-09/README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
[previous task](../task-08)
2+
3+
# Task 9: RIOT and RPL
4+
5+
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.
6+
7+
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.
8+
9+
## Prerequisites
10+
11+
* Compile the application and run on your `BOARD`
12+
* For this task you need at least three boards (you can form groups with your neighbors)
13+
* Each "group" should change to an individual RF channel. It can be changed by e.g.
14+
15+
```
16+
ifconfig <if_id> set chan 11
17+
18+
```
19+
20+
Use the `ifconfig` command to obtain the `<id_id>`.
21+
22+
* 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.
23+
24+
25+
## Task 9.1: Initialize RPL
26+
27+
* 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`:
28+
29+
```
30+
ifconfig <if_id> add 2001:db8::1
31+
```
32+
33+
* 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)
34+
35+
```
36+
rpl root 1 2001:db8::1
37+
```
38+
39+
## Analyse the topology
40+
41+
* On not-root nodes, look at the output of `ifconfig` again. You should see that a global unicast IPv6 address has been set automatically.
42+
43+
* 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?
44+
45+
* 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.
46+
47+
48+
## Pinging "distant" nodes
49+
50+
* Use the ping6 command to ping global address of a "distant" node.
51+
* Most likely, in this setup the root node will be the only intermediate hop. It should print some rough information about forwarding IPv6 packets
52+
* Additionally you can try to transmit UDP packets (explore the `udp` commandset)

task-09/main.c

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright (C) 2015 Freie Universität Berlin
3+
* Copyright (C) 2016 Hochschule für Angewandte Wissenschaften Hamburg
4+
*
5+
* This file is subject to the terms and conditions of the GNU Lesser
6+
* General Public License v2.1. See the file LICENSE in the top level
7+
* directory for more details.
8+
*/
9+
10+
/**
11+
* @ingroup examples
12+
* @{
13+
*
14+
* @file
15+
* @brief Example application for demonstrating the RIOT network stack
16+
*
17+
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
18+
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
19+
*
20+
* @}
21+
*/
22+
23+
#include <stdio.h>
24+
25+
#include "shell.h"
26+
#include "msg.h"
27+
#include "thread.h"
28+
29+
#include "net/gnrc.h"
30+
#include "net/gnrc/ipv6/netif.h"
31+
#include "net/gnrc/ipv6.h"
32+
33+
#define MAIN_QUEUE_SIZE (8)
34+
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
35+
36+
extern int udp_cmd(int argc, char **argv);
37+
38+
static const shell_command_t shell_commands[] = {
39+
{ "udp", "send data over UDP and listen on UDP ports", udp_cmd },
40+
{ NULL, NULL, NULL }
41+
};
42+
43+
#ifdef MODULE_GNRC_SIXLOWPAN
44+
static char _stack[THREAD_STACKSIZE_MAIN];
45+
46+
static void *_ipv6_fwd_eventloop(void *arg)
47+
{
48+
(void)arg;
49+
50+
msg_t msg, msg_q[8];
51+
gnrc_netreg_entry_t me_reg;
52+
53+
msg_init_queue(msg_q, 8);
54+
55+
me_reg.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL;
56+
me_reg.pid = thread_getpid();
57+
58+
gnrc_netreg_register(GNRC_NETTYPE_SIXLOWPAN, &me_reg);
59+
60+
while(1) {
61+
msg_receive(&msg);
62+
gnrc_pktsnip_t *pkt = msg.content.ptr;
63+
if(msg.type == GNRC_NETAPI_MSG_TYPE_SND) {
64+
gnrc_pktsnip_t *ipv6 = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6);
65+
ipv6 = ipv6->data;
66+
67+
ipv6_hdr_t *ipv6_hdr =(ipv6_hdr_t *)ipv6;
68+
69+
/* get the first IPv6 interface and prints its address */
70+
kernel_pid_t ifs[GNRC_NETIF_NUMOF];
71+
gnrc_netif_get(ifs);
72+
gnrc_ipv6_netif_t *entry = gnrc_ipv6_netif_get(ifs[0]);
73+
for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) {
74+
if ( (!ipv6_addr_is_link_local(&entry->addrs[i].addr)) && (!ipv6_addr_is_link_local(&ipv6_hdr->src))
75+
&& (!ipv6_addr_is_link_local(&ipv6_hdr->dst)) && !(entry->addrs[i].flags & GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST)
76+
&& (!ipv6_addr_is_unspecified(&entry->addrs[i].addr)) ) {
77+
78+
if(!ipv6_addr_equal(&entry->addrs[i].addr, &(ipv6_hdr->src))){
79+
80+
char addr_str[IPV6_ADDR_MAX_STR_LEN];
81+
printf("IPv6 ROUTER: forward from src = %s ", ipv6_addr_to_str(addr_str, &(ipv6_hdr->src), sizeof(addr_str)) );
82+
printf("to dst = %s\n",ipv6_addr_to_str(addr_str, &(ipv6_hdr->dst), sizeof(addr_str)));
83+
}
84+
}
85+
}
86+
}
87+
gnrc_pktbuf_release(pkt);
88+
}
89+
/* never reached */
90+
return NULL;
91+
}
92+
#endif
93+
94+
int main(void)
95+
{
96+
/* we need a message queue for the thread running the shell in order to
97+
* receive potentially fast incoming networking packets */
98+
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
99+
puts("RIOT network stack example application");
100+
101+
#ifdef MODULE_GNRC_SIXLOWPAN
102+
thread_create(_stack, sizeof(_stack), (THREAD_PRIORITY_MAIN - 4),
103+
THREAD_CREATE_STACKTEST, _ipv6_fwd_eventloop, NULL, "ipv6_fwd");
104+
#endif
105+
/* start shell */
106+
puts("All up, running the shell now");
107+
char line_buf[SHELL_DEFAULT_BUFSIZE];
108+
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
109+
110+
/* should be never reached */
111+
return 0;
112+
}

0 commit comments

Comments
 (0)