CoAP server running on top of a RPL/TSCH network

Difficulty: High

Duration: 60 minutes

Prerequisites: Configure SSH Access / Understand IPv6 subnetting / Get and compile firmware for M3 and A8-M3 nodes

Description: The aim of this tutorial is to discover Contiki’s RPL/TSCH implementation and run it. Like for the Contiki’s CoAP tutorial, you will reserve some M3 nodes on the Lille site, set them up with flashing two firmwares nodes, and create a simple IPv6 network in IoT-LAB. You will access nodes over IPv6 using a Contiki tunslip6 bridge and launch requests on a CoAP Contiki Erbium server implementation.

Standard explanation: IPv6 over the TSCH mode of IEEE 802.15.4e

We base this tutorial applications on Contiki examples from ipv6: Border Router and COAP Server. The code is available in the IoT-LAB Contiki github repository

  • contiki/examples/iotlab/
    • 05-rpl-tsch-border-router
    • 06-rpl-tsch-coap

See additionals details for explanations on how we added TSCH to these ipv6 examples.

The simplest way to run this tutorial is by doing it from an SSH frontend, since all tools are already installed there. But you can as well do it from your local environment. See additionals details section to know how.

  1. Connect to a site’s SSH frontend
    my_computer$ ssh <login>
  2. Setup the contiki repository
    <login>@lille:~$ git clone
    <login>@lille:~$ cd iot-lab
    <login>@lille:~$ make setup-contiki
    <login>@lille:~$ cd parts/contiki/
  3. In examples/iotlab/00-configuration/tsch-project-conf.h, set your PANID to something unique, to isolate your network from others. Look for the definition of IEEE802154_CONF_PANID and redefine it to some other value.
  4. If it is not alreay done, set your credentials for CLI tools with:
    <login>@lille:~/iot-lab/parts/contiki$ iotlab-auth -u <login>
  5. Submit a new experiment:
    • Duration: 60 minutes
    • Choose ten nodes: Archi = m3:at86rf231 / Site = lille / Number = 10

    Use this command with CLI tools:

    <login>@lille:~/iot-lab/parts/contiki$ iotlab-experiment submit -n tsch -d 60 -l 10,archi=m3:at86rf231+site=lille
  6. Wait for your experiment to be running:
    <login>@lille:~/iot-lab/parts/contiki$ iotlab-experiment wait
  7. Get the list of nodes of your experiments:
    <login>@lille:~/iot-lab/parts/contiki$ iotlab-experiment get -r
     "items": [
     "network_address": "", 
     "uid": "1055", 

    Pick one node that will be later used as Border Router and write down its ID and UID (e.g. m3-9 and 1055).

  8. Program your nodes
    • Border Router for m3-9:
      <login>@lille:~/iot-lab/parts/contiki$ cd examples/iotlab/05-rpl-tsch-border-router 
      <login>@lille:~/iot-lab/parts/contiki/examples/iotlab/05-rpl-tsch-border-router$ make TARGET=iotlab-m3
      <login>@lille:~/iot-lab/parts/contiki/examples/iotlab/05-rpl-tsch-border-router$ iotlab-node -up border-router.iotlab-m3 -l lille,m3,9
    • COAP Erbium server for all nodes except m3-9:
      <login>@lille:~/iot-lab/parts/contiki$ cd examples/iotlab/06-rpl-tsch-coap
      <login>@lille:~/iot-lab/parts/contiki/examples/iotlab/06-rpl-tsch-coap$ make TARGET=iotlab-m3
      <login>@lille:~/iot-lab/parts/contiki/examples/iotlab/06-rpl-tsch-coap$ iotlab-node -up er-example-server.iotlab-m3 -e lille,m3,9
  9. Launch tunslip6:
    <login>@lille:~$ sudo -v2 -L -a m3-9 -p 20000 fd00::1/64

    Note: If you have an error “overlaps with routes”, it’s because another experiment is using the same ipv6 prefix (e.g. : fd00::1/64).
    You can view ipv6 prefix used on the frontend SSH with this command and choose another prefix in IPv6Network(fd00::/8) like fddd::1/64.

    <login>@lille:~$ ip -6 route
    fd00::/64 dev tun_7589  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
    fe80::/64 dev eth1  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
    fe80::/64 dev eth0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
  10. From another terminal, ping the Border Router:
    <login>@lille:~$ ping6 fd00::1055
  11. Get the list of neighbors and links from the Border Router:
    <login>@lille:~$ lynx -dump http://[fd00::1055]

    Note: in such a dense topology like in the lille site, you may have direct connections between nodes. To test TSCH with multi-hop, you could use a dozen of nodes spread among the whole site and change the radio default configuration. Add those lines in your project-conf.h or directly in the iotlab-project-conf.h file:

    #define RF2XX_TX_POWER  PHY_POWER_m17dBm
  12. Send a CoAP request to one of your server nodes, listed in the result of the previous command:
    <login>@lille:~$ coap get coap://[fd00::9373]/.well-known/core
    (2.05)  </.well-known/core>;ct=40,</test/hello>;title="Hello world: ?len=0..";rt="Text",</test/push>;title="Periodic demo";obs,</actuators/toggle>;title="Red LED";rt="Control",</sensors/light>;title="Ambient light (supports JSON)";rt="LightSensor",</sensors/pressure>;title="Pressure (supports JSON)";rt="PressureSensor",</sensors/gyros>;title="Three axis gyroscope (supports JSON)";rt="GyroscopeSensor",</sensors/accel>;title="Three axis accelerometer (supports JSON)";rt="AccelerometerSensor",</sensors/magne>;title="Three axis magnetometer (supports JSON)";rt="MagnetometerSensor"
  13. Explore the services proposed by this CoAP node. For example, get the light sensor value:
    <login>@lille:~$ coap get coap://[fd00::9373]/sensors/light
    (2.05)	174.926758

    You can have other examples of the CoAP server services explained in this Contiki’s CoAP server tutorial

Additional details

Adding TSCH to standard examples

For these applications to run on top of RPL/TSCH Contiki’s implementation, we have addded extra configuration in their project-conf.h:

#include "../00-configuration/tsch-project-conf.h"
#include "../00-configuration/iotlab-project-conf.h"

The first enables and configures TSCH.
The second one sets up RPL for IoT-LAB:

  • IOTLAB_WITH_NON_STORING enables RPL non-storing mode (only the root keeps toplogy information). If unset, storing mode (all nodes maintain routes to their sub-graph locally) is used instead.
  • NBR_TABLE_CONF_MAX_NEIGHBORS is the maximum number of neighbors. The default value of 130 is suited to Grenob
  • RPL_NS_CONF_LINK_NUM defines the number of links used in non-storing mode. Should be set to at least the network size.
  • UIP_CONF_MAX_ROUTES defines the number of routes used in storing mode. Should be set to at least the network size.

Running this tutorial locally, i.e. from your environment

Prerequisite, be sure to have installed:

  • gcc-arm-none-eabi, the arm-gcc toolchain, see this FAQ entry
  • cli-tools, could be installed with
    pip install iotlabcli --upgrade
  • coap-cli, could be installed with a simple
    npm install -g coap-cli

At step 7, you need to bridge the Border Router to your environment through SSH tunneling. Replace the tunslip6 command with this two steps:

  1. Create a SSH tunnel:
    ssh -NT <login> -L 2000:m3-9:20000
  2. From a second terminal, run tunslip6 to start RPL and connect the network to your environment:
    cd ~/iot-lab/parts/contiki/tools
    make tunslip6
    sudo ./tunslip6 -v2 -t tun0 -L -a localhost -p 2000 fd00::1/64