Developing Secure Internet of Things Applications: Tutorial and Hackathon v2 - simonduq/contiki-ng GitHub Wiki
This tutorial is for the event "Developing Secure Internet of Things Applications".
Setup
This tutorial will get you started with Contiki-NG, both systems and networking aspects. As a development environment, you can use the virtual machine image we provide, or run everything natively on Linux (doc:toolchain-linux) or OSX (doc:toolchain-osx), or use the Docker image (doc:docker).
If you run natively or with Docker, you will need to clone the Contiki-NG branch we use for this tutorial. From the directory of your choice, e.g. your home directory:
$ git clone https://github.com/simonduq/contiki-ng.git
$ cd contiki-ng
$ git submodule update --init --recursive
$ git checkout tutorial/secure-iot-v2
Before starting, make sure to pull the latest version of the tutorial branch, with, from the contiki-ng
directory:
$ git pull
In this tutorial, we will be exploring different development tools:
- Real devices: you program use a Zolertia Firefly device. For convenience, set the following:
export TARGET=zoul
export BOARD=firefly-reva
- Native node: you will run Contiki-NG as a native Unix process, for simple testing of the network stack.
- Cooja simulation: you will use the Cooja network simulator to run networks without the need to program any physical device.
Tutorial
Getting Started
First, run the hello-world
example, on real devices, native node, and Cooja:
Contiki-NG Tools
We will now look into a number of tools provided by Contiki-NG.
From now on, you can either switch to the examples/libs/shell
example, or continue from the hello-world
example (in this case, remove the printf("Hello, world\n");
, as the messages will get in the way).
Exercise
- In
contiki-ng/os/contiki-default-conf.h
, look for the configuration parameter that defines the routing table and neighbor table size. Set their value to different values, and observe the effect on the firmware size. What happens if you set it to a large number, say, 100? - Using the shell, find out the IPv6 address of your neighbors. Can you ping them?
IPv6 Networking and Link-layer Security
We now turn our attention to the IPv6 stack:
- IPv6 ping (link-local)
- Connecting to a RPL network
- Connecting to a RPL network with link-layer security
Exercise
Ask a teammate to check their node's global IPv6 addresses, both link-local (starts in fe80
) and global.
Try pinging the node through both addresses.
Do you see any difference? Can you explain?
LWM2M/CoAP and Application-layer Security
Let's take a look at CoAP and LWM2M:
Hackathon
Timer and Events
Let's play with buttons and LEDs.
The Firefly has a user button (there are two buttons, one that resets the node marked with RESET
, the other one marked with USER
) and an RGB LED.
First try the existing examples examples/dev/button-hal
and examples/dev/leds
.
- From the two examples above, write your own that counts button presses, and sets the LED to the value in the counter.
- Extend your code such as whenever holding the button for 2s, the counter is reset.
NB: the documentation on Contiki-NG processes and events can come handy: doc:processes
UDP Communication
Let's now extend our button-LED counter example to now have the button trigger the LED on all neighbors in range. We will implement that over UDP. Take a look at the UDP API at doc:udp-communication. Our protocol is simple: we use UDP port 6060, and the payload is one byte. To create a multicast address that all IPv6 nodes already listen to, use:
static uip_ip6addr_t allnodes_ipaddr;
uip_create_linklocal_allnodes_mcast(&allnodes_ipaddr);
CoAP
Let's write our own CoAP resource, that returns the current button counter. Start from examples/coap/coap-example-server/resources
, add your own resource and implement it. Test it simply from your local machine.
Thunderboard Sense 2
The Thunderboard Sense 2 is a platform with lots of sensors and LEDs. The Contiki-NG port is not yet complete
but support pressure sensor BMP 280, LEDs, and buttons. To build for it use TARGET=efr32tb
and BOARD=sense2
.
There is one platform specific example that will read some air pressure sensor and blink the LEDs.
The example is at examples/platform-specific/efr32tb/
The example also provide some additional shell commands for reading out sensor data, and setting color of the RGB LEDs. Try to take a look into the efr-cmds.c file to see what the commands really do.
You can also run the LWM2M examples to read out data, but in that case you will need to register with a LWM2M server.
Since we have a NAT64 you can register with the global Leshan server at: http://leshan.eclipse.org
Use the following in the examples-ipso-object.c
#define LWM2M_SERVER_ADDRESS "coap://[64:ff9b::527:53ce]"
Suggested hackathon tasks
Add your own command to either the regular command list of the shell or to the EFR32 command list. Suggested commands: make an rgb led command to control some automatic dimming and re-coloring of the LEDS or extend the sensor command to also read out the UV sensor value of the light sensor.
Add another IPSO object to the LwM2M demo application - for example control of the RGB-leds or additional sensor (possibly the UV value). See examples/lwm2m-ipso-object/arch folder for platform specific IPSO objects.
Acknowledgements
This tutorial was partly sponsored by VINNOVA, Sweden's Innovation Agency.