CoAP server with public IPv6/RPL/6LoWPAN network


Difficulty: High

Duration: 90 minutes

Prerequisites: Configure SSH Access / Get and compile firmware for M3 and A8-M3 nodes / Understand IPv6 subnetting / Public IPv6/6LoWPAN/RPL network with M3 nodes

Description: The aim of this tutorial is to discover the basics of Constrained Application Protocol (CoAP) . You will reserve some M3 nodes on the Grenoble 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.

  1. Log into the Web portal with your account credentials
  2. Submit a new experiment:
    • Set an experiment name (no spaces nor funny chars in the experiment name)
    • Duration: 60 minutes and starting “As soon as possible
    • Choose ten nodes with Architecture m3 (at86rf231) / Site = grenoble / Number = 10 and click “Add to experiment”
  3. Wait experiment state Running in the Schedule dashboard section. After click on experiment details and visualize which nodes you are booked and verify that you have Success in the deployment result
  4. Compile firmwares on SSH frontend.
    my_computer$ ssh <login>
    • Border Router: bridge between the server and the IoT-LAB IPv6 network
      <login>@grenoble:~$ cd ~/iot-lab/parts/contiki/examples/ipv6/rpl-border-router
      <login>@grenoble:~/iot-lab/parts/contiki/examples/ipv6/rpl-border-router$ make TARGET=iotlab-m3
      <login>@grenoble:~/iot-lab/parts/contiki/examples/ipv6/rpl-border-router$ ls
      ... border-router.iotlab-m3 ...
      <login>@grenoble:~/iot-lab/parts/contiki/examples/ipv6/rpl-border-router$ cp border-router.iotlab-m3 ~/
    • IoT-LAB version of CoAP Erbium server:
      <login>@grenoble:~$ cd ~/iot-lab/parts/contiki/examples/iotlab/04-er-rest-example
      <login>@grenoble:~/iot-lab/parts/contiki/examples/iotlab/04-er-rest-example$ make TARGET=iotlab-m3
      <login>@grenoble:~/iot-lab/parts/contiki/examples/iotlab/04-er-rest-example$ ls
      ... er-example-server.iotlab-m3 ...
      <login>@grenoble:~/iot-lab/parts/contiki/examples/iotlab/04-er-rest-example$ cp er-example-server.iotlab-m3 ~/

    View Border Router and CoAP Server source code on GitHub.

  5. Choose an available IPv6 prefix for the site you are experimenting on. For example in Grenoble testbed :
    • we choose 2001:660:5307:3100::/64
  6. Choose one node in your nodes list to implement the Border Router (BR) node
    • we choose node m3-1
  7. Start tunslip6 on the SSH frontend:
    • <login>@grenoble:~$ sudo -v2 -L -a m3-1 -p 20000 2001:660:5307:3100::1/64
      slip connected to ``''
      15:38:19 opened tun device ``/dev/tun0''
      0000.000 ifconfig tun0 inet `hostname` up
      0000.004 ifconfig tun0 add 2001:660:5307:3100::1/64
      0000.005 ifconfig tun0 add fe80::660:5307:3100:1/64
      0000.007 ifconfig tun0
      tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
                inet adr:  P-t-P:  Masque:
                adr inet6: 2001:660:5307:3100::1/64 Scope:Global
                adr inet6: fe80::660:5307:3100:1/64 Scope:Lien
                RX packets:0 errors:0 dropped:0 overruns:0 frame:0
                TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 lg file transmission:500
                RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
    • Note 1: leave the terminal open (you don’t want to kill tunslip6, it bridges the BR to the front-end network)
    • Note 2: If you have an error “overlaps with routes”, it’s because another experiment is using the same ipv6 prefix (e.g. : 2001:660:5307:3100::/64).

      You can view currently used IPv6 prefixes on the frontend SSH with this command

      <login>@grenoble:~$ ip -6 route
      2001:660:5307:30fff::/64 dev eth0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
      2001:660:5307:3100::/64 dev tun0  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
      fe80::/64 dev tun0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 4294967295
      default via 2001:660:5307:30ff:ff:: dev eth0  metric 1  mtu 1500 advmss 1440 hoplimit 4294967295
    • Note 3: if you did not already authenticate using iotlab-auth, do it now:
      <login>@grenoble:~$ iotlab-auth -u login
  8. Deploy the Border Router (BR) node on selected node using the CLI tool iotlab-node.
    <login>@grenoble:~$ iotlab-node --update ~/iot-lab/parts/contiki/examples/ipv6/rpl-border-router/border-router.iotlab-m3 -l grenoble,m3,1
        "0": [
  9. Get the Border Router IPv6 address from tunslip output:
    Platform starting in 1...
    [in clock_init() DEBUG] Starting systick timer at 100Hz
    0473.257 *** Address:2001:660:5307:3100::1 => 2001:0660:5307:3100
    0473.257  Starting 'Border router process' 'Web server'Got configuration message of type P
    0473.257 Setting prefix 2001:660:5307:3100::
    0473.257 Server IPv6 addresses:
    0473.257  2001:660:5307:3100::2354
    0473.257  fe80::2354
  10. Ping6 BR node using global address:
    <login>@grenoble:~$ ping6 2001:660:5307:3100::2354
  11. Choose one CoAP server node picking another node (here node 2). Open a new terminal and read serial port output
    <login>@grenoble:~$ nc m3-2 20000
  12. Flash CoAP server firmware on the other nodes.
    <login>@grenoble:~$ iotlab-node --update ~/iot-lab/parts/contiki/examples/iotlab/04-er-rest-example/er-example-server.iotlab-m3 -e grenoble,m3,1
        "0": [

    Let’s do the following with one CoAP server, for example m3-2. You can do the same with any other server.

  13. View CoAP server starting on the serial output
    <login>@grenoble:~$ nc m3-2 20000
    Platform starting in 1... 
    [in clock_init() DEBUG] Starting systick timer at 100Hz
    Starting 'IoT-LAB CoAP Server'
  14. Grab the CoAP server node’s IPv6 address from the BR’s web interface
    <login>@grenoble:~$ lynx -dump http://[2001:660:5307:3100::2354]
    2001:660:5307:3100::9982/128 (via fe80::9982) 16711353s

    Understand M3 nodes uid / ipv6 address match.

  15. Ping the CoAP server’s global address from SSH frontend
    <login>@grenoble:~$ ping6 2001:660:5307:3100::9982
  16. For resource discovery, CoAP use the /.well-known/core path to provide resource descriptions in its CoRE Link Format. Launch CoAP request with the coap-cli client installed on the frontend SSH
    <login>@grenoble:~$ coap get coap://[2001:660:5307:3100::9982]:5683/.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"
  17. Test different GET requests to the different sensors resources
    <login>@grenoble:~$ coap get coap://[2001:660:5307:3100::9982]:5683/sensors/light
    (2.05)  0
    <login>@grenoble:~$ coap get coap://[2001:660:5307:3100::9982]:5683/sensors/light
    (2.05)  0
    <login>@grenoble:~$ coap get coap://[2001:660:5307:3100::9982]:5683/sensors/pressure
    (2.05)  992
    <login>@grenoble:~$ coap get coap://[2001:660:5307:3100::9982]:5683/sensors/gyros
    (2.05)  -96;1557;-52
    <login>@grenoble:~$ coap get coap://[2001:660:5307:3100::9982]:5683/sensors/accel
    (2.05)  -107;-12;-1025
    <login>@grenoble:~$ coap get coap://[2001:660:5307:3100::9982]:5683/sensors/magne
    (2.05)  -75;-261;422
  18. Test the Hello world resource with path /test/hello
    <login>@grenoble:~$ coap get coap://[2001:660:5307:3100::9982]:5683/test/hello
    (2.05)	Hello World!
    <login>@grenoble:~$ coap get coap://[2001:660:5307:3100::9982]:5683/test/hello?len=42 # print 42 caracters
    <login>@grenoble:~$ coap get coap://[2001:660:5307:3100::9982]:5683/test/hello?len=64 # print 64 caracters
    (2.05)	Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy
    <login>@grenoble:~$ coap get coap://[2001:660:5307:3100::9982]:5683/test/hello?len=80 # print 64 caracters 
    (2.05)	Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy

    The last output is 64 characters too, because the REST_MAX_CHUNK_SIZE, defined in the application’s project-conf.h, is 64 bytes.

  19. CoAP provides Observers support (publish/subscribe mechanism). They allow for a client to receive updates when a state changes. This reduces the need for constant polling but also introduces additional engineering overhead into the protocol when considering sleeping nodes and unreliable networks. Ther Erbium CoAP Server includes an example of PERIODIC resource, notifying each subscriber at a time interval (5 seconds) with the resource value (here a simple counter).
    <login>@grenoble:~$coap get -o coap://[2001:660:5307:3100::9982]:5683/test/push
    (2.05)  VERY LONG EVENT 235
    (2.05)  VERY LONG EVENT 236
    (2.05)  VERY LONG EVENT 237

    Note : Regarding the counter value, you will understand that the server starts the periodic resource on the node at the starting of the server even if you don’t have subscribers.

  20. The server also provides the support for EVENT resource. To illustrate this feature we handle an event when an input has been received from the serial port of the node and we send a CoAP response with the data input.
    • This resource is disabled by default, so you need to uncomment the line 159 in er-example-server.c
      rest_activate_resource(&res_event, "test/serial");
    • Compile and flash this new firmware
      <login>@grenoble:~/iot-lab/parts/contiki/examples/iotlab/04-er-rest-example$ make TARGET=iotlab-m3 && iotlab-node --update -l grenoble,m3,2
    • Observe this resource
      <login>@grenoble:~$ coap get -o coap://[2001:660:5307:3100::9982]:5683/test/serial
    • Each time a string is sended into the serial port, a notification is sended by the CoAP server
      <login>@grenoble:~$ nc m3-2 20000
      coap event # write this string and press enter
      <login>@grenoble:~$ coap get -o coap://[2001:660:5307:3100::9982]:5683/test/serial
      (2.05)  coap event