Thursday, April 16, 2015

Linux RPL Router - improvements

In my previous post I wrote about an experimental Linux RPL router running on RaspberryPi using RPL code from Joao Pedro Taveira's linux-rpl. I encountered some problems with using the router, and I would like to share some advice on solving these problems.

Status of current 802.15.4 development

Linux 802.15.4/6LoWPAN support has been moved again. Currently the development is happening in bluetooth-next repository. The name might be a little confusing - repo contains 6LoWPAN code for both Bluetooth and 802.15.4. In general everything that has been done in old linux-wpan-next repo still works, which is a good thing :)

I pulled RPL code from linux-wpan-next repo to a clone of bluetooth-next repo - you can download it at GitHub, branch feature-rpl. All instructions for compilation and running RPL are still valid.

Also Alex Aring gave a speech about 802.15.4 in Linux on FOSDEM in Bruxelles. You can check the video here.

Problems with ifplugd

After recent changes wpan0 interface is created automatically during system startup. If you are using RaspberryPi with Raspbian this might lead to a problem with ifplugd daemon. This program always keeps wpan0 interface up and it will prevent you from changing some interface parameters like PAN ID. To solve the problem you need to modify /etc/default/ifplugd file to look more or less like that:
# This file may be changed either manually or by running dpkg-reconfigure.
#
# N.B.: dpkg-reconfigure deletes everything from this file except for
# the assignments to variables INTERFACES, HOTPLUG_INTERFACES, ARGS and
# SUSPEND_ACTION.  When run it uses the current values of those variables
# as their default values, thus preserving the administrator's changes.
#
# This file is sourced by both the init script /etc/init.d/ifplugd and
# the udev script /lib/udev/ifplugd.agent to give default values.
# The init script starts ifplugd for all interfaces listed in
# INTERFACES, and the udev script starts ifplugd for all interfaces
# listed in HOTPLUG_INTERFACES. The special value all starts one
# ifplugd for all interfaces being present.
INTERFACES="eth0"
HOTPLUG_INTERFACES="wlan0"
ARGS="-q -f -u0 -d10 -w -I"
SUSPEND_ACTION="stop"

Multihop problems with RPL router

I tested Linux RPL router with two Atmel AVR Raven nodes running recent Contiki OS. I noticed that when both nodes are connected directly to router everything worked fine. But when one Raven was connected to the router through the other Raven, the router wasn't able to ping the non-adjacent Raven. I expected that the problem was caused by missing support for RPL option for IPv6 Hop-by-Hop header in Linux RPL router. This option is critical - if receiving node doesn't understand the RPL option, it drops the entire packet. By default Contiki nodes insert RPL option to IPv6 Hop-by-Hop header to forwarded packets only - that explains why adjacent nodes could communicate.

Dummy RPL option handler

I decided to try adding dummy RPL option handler, and check if router starts accepting packets with RPL option for IPv6 Hop-by-Hop header. I added commit to my feature-rpl branch. I repeated tests with Contiki Raven nodes. This time I could ping nodes two hops away without problems. Yay!!!

Dummy RPL option handler is not a perfect solution - contents of RPL option are ignored, and it's not compliant with RFC6550. However for a simple operation as a DODAG root, dummy handler should be sufficient for testing purposes. DODAG root can't be a part of a routing loop in normal circumstances (it has no parrents), so skipping RPL option should be safe. Contiki nodes currently accept packets with no RPL option in IPv6 header.

Conclusions

The above paragraph presents a quick hack that overcomes the biggest limitation of current RPL Linux router - lack of multihop operation. There are other problems with implementation: rpl-ctl command doesn't produce useful output, and quantity of DIO packets sent is highly suspicious.

Sunday, November 16, 2014

Linux RPL router

Recently there have been huge developments in Linux 6LoWPAN support. Old linux-zigbee was renamed to more appropriate linux-wpan. Openlabs released an excellent tutorial on running 6LoWPAN on RaspberryPi. With it you can get running 6LoWPAN Border Router, even if you never compiled Linux kernel before. Openlabs also released 802.15.4 module for RaspberryPi - it is very reasonably priced, works as advertised, and is currently best choice to quickly start development. Delivery with USPS seems fast too (12 days to Poland, Europe in my case).

Following my previous experiments with Grinch Border Router, I decided to try to take it one step further, and run RPL routing protocol on top of RaspberryPi with 6LoWPAN. My results below.

Linux branch

Following Openlabs advice, I decided to go with linux-wpan-next branch. I had one problem running this branch on RaspberryPi - Ethernet stopped working. I found solution on elinux.org - the bug was caused by missing USB config directives in kernel. Take extra care to enable both CONFIG_USB_DWC2_HOST and CONFIG_USB_DWC2_PLATFORM in your kernel config.

Fixing RPL implementation

After checking the Internet for existing Linux RPL implementations, I found three feasible candidates:

After preliminary testing, I decided to go with linux-rpl, as it is a kernelspace implementation. Repository for linux-rpl contains code in a form of huge patches for Linux kernel 3.10, 3.11 and 3.12. After a few unsuccessful atempts to merge them I ported the 3.12 patch into linux-wpan-next branch manually. I left out patches related to XBee. My patched branch is available on Github

To run RPL you should clone my branch and then basically follow Openlabs tutorial:

  1. Run make menuconfig and enable proper kernel options (remember to enable CONFIG_IPV6_RPL and CONFIG_IPV6_RPL_OF_OF0 and USB options mentioned above)
  2. Build patched kernel
  3. Patch the device tree to add AT86RF233 transceiver and rebuild .dtb file
  4. Build U-Boot
  5. Move kernel, device tree file and U-Boot to the SD card with new Raspbian installation
  6. Boot up Raspberry and log-in using SSH (or keyboard/screen)
  7. Build userspace lowpan tools
  8. Configure wpan0 and lowpan0 interfaces

The steps above should give you working RaspberryPi with eth0 and lowpan0 interfaces.

Running RPL

First thing to do is to compile RPL userspace tools. Then you can enable RPL on chosen interface: for example lowpan0. You can run your RPi as a non-root RPL router. It will then search for a DODAG to join. To do that issue command:

sudo rpl-ctl enable lowpan0

You can also use sysctl:

sudo sysctl -w net.ipv6.conf.lowpan0.rpl_enabled=1

In most cases you will want your RPi to be DODAG root (it is useful when you plan to use your RPi to be a border router). As a DODAG root, your RPi will distribute address prefix for other RPL routers. To do that issue commands:

sudo sysctl -w net.ipv6.conf.lowpan0.rpl_dodag_root=1

sudo sysctl -w net.ipv6.conf.lowpan0.rpl_enabled=1

After that your RaspberryPi is be ready to communicate with RPL nodes. If you want to use your RPi as a Border Router there are other steps to take: enabling IPv6 forwarding, configuring IP address on eth0 interface, running radvd on eth0 interface, etc.

Communication with Contiki nodes

To determine which links should be used as a first choice, RPL protocol uses objective function (OF). All RPL nodes in a DODAG must use the same OF. The most basic objective function is OF0, and it is the only OF supported currently by Linux. Contiki OS 2.7 uses MRHOF objective function by default, but it supports OF0 too. To achieve communication between RaspberryPi with RPL, and Contiki, you need to compile Contiki with RPL using OF0 function. To do that add following line in your platform contiki-conf.h file:

#define RPL_CONF_OF rpl_of0

Remove other OF definitions if present. With this modification, your Contiki nodes should join DODAG formed by RaspberryPi.

Possible issues

I haven't throughly tested this setup, so bugs can be expected. Few remarks:

  1. (Edit: 01 Feb 2015) Multihop doesn't work - probable cause is lack of hop-by-hop RPL option support
  2. RPL userspace tools info commands (for example rpl-ctl list-neighbors) usually return nothing, it might be a bug
  3. I noticed nodes are slow to rejoin DODAG after restart.

Further tests are necessary.

Conclusions

RPL for Linux is usable. Joao Pedro Taveira's implementation seems to work with Linux 3.17 and 6LoWPAN (after minimal patching). This is very surprising, that implementation is no longer developed. Linux box is a superior solution for Border Router than any embedded system. Open Source's inefficiency is sometimes amazing.

Thursday, September 4, 2014

txThings improvements and news

I updated my txThings library and made some improvements:

1. txThings is now a proper Python package. It is available on PyPI. You can install txThings on most Python environments using command:

easy_install txthings

or

pip install txthings

These commands should automatically install txThings dependencies too - currently it's only Twisted. On Linux you need root privileges (sudo). You can also specify txThings as a dependency for your own application.

2. I added an example for Resource Directory. Resource Directory is based on draft-ietf-core-resource-directory-01 (it's already outdated but changes shouldn't be dramatic).

Also Christian Amsüss recently ported txThings to Python 3 and asyncio. Asyncio is a new Python 3 module, backed by Guido himself. It's an effort to partially unify many different Python asynchronous frameworks (make them run on a common event loop). I support this idea - it's Python's only chance against node.js. Twisted is actively being ported to Python 3 and is going to have bindings for asyncio, so one day it might be possible to just run the code and not worry about compatibility. Christian's library is called aiocoap. If you plan to develop apps for Python 3, you should strongly consider using aiocoap.

Saturday, March 8, 2014

Aneska - simple CoAP browser for Android

When I started working on txThings CoAP library I needed to create some GUI tools for testing - simple client and server. I checked the existing Python GUI libraries and I wasn't really satisfied with the results of my search. GUI programming in Python is very fragmented, there are over 40 libraries, and it's hard to make an informed choice. I've finally decided to try Kivy framework - its webpage seemed nice. Kivy is a modern framework, with strong focus on multiple platform and touch screen support. It has some nice features:
  • runs on Windows, Linux and Android (with Python for Android)
  • looks more or less the same on each platform
  • supports Twisted integration
  • supports many touchscreen features like swiping, scrolling etc.
At first I wanted to create a very simple tool for testing txThings library on Linux and Windows, but out of curiosity I tried packaging the app for Android . The tutorial was well written, and everything went very smooth - after around 4 hours I had first working Android app. I was really amazed by the simplicity of the process. I decided to work a bit more on it, and gradually I got a very basic CoAP browser. It was quite usable, but not very polished. Then I took a decision to finish the job, and release the simple CoAP browser to the Play store.

GUI development

Kivy is a very nice framework, but many parts of it are still quite immature. Kivy uses its own Kv language to describe the layout. It works fine with simple widgets like buttons and labels. But many complex widgets like treeviews, spinners etc. are in reality compounds of simpler widgets. It is sometimes hard to access the properties of these "inner" widgets using Kv language. Occasionally it's necessary to overload existing widgets to achieve desired effects. Many times I had to browse the source code of some widgets to get things done (luckily after two years of dealing with Contiki OS, reading Python source code is a piece of cake :) ). On the other hand, some complicated stuff was very easy to achieve using Kivy - like swipe-to-close browsing cards, and animated screen transitions.

After finishing the communications layer and the GUI I decided to implement also some simple parser for RFC 6690 CoRE Link Format. I used link_header library from Asplake. I also added simple bookmarks support. After that I added icon and splash screen, and started working on the visuals. I discovered that designing a decent GUI for a mobile app is not that easy :) - maybe using a combination of blue and orange wasn't the best choice ;).

Double-stack support

Big problem in making the browser was IPv4/IPv6 double stack operation. CoAP is meant to be used mostly with IPv6, but it's adoption is still not very wide. IPv4 support is simply a must. Linux (and Android) IPv6 UDP sockets can send and receive IPv4 packets, provided that the address is passed as IPv4-mapped IPv6 address (::ffff:X.X.X.X). That doesn't work on Windows (bug in Windows Python 2.7 code). Another thing was the DNS support. I had no idea how to tackle that problem, but at the end of 2013, new version 13.2 of Twisted framework was released, that supported RFC 6555 "Happy Eyeballs" algorithm. This algorithm was designed for TCP-based, human-operated client apps, however I managed to adapt it to work with UDP-based application. I had to change some parts of txThings blockwise code to allow for callbacks after every block (this can be useful later to implement progress bars for blockwise transfers). Currently the "Happy Eyeballs" works fine with normal and blockwise requests. I'm not entirely sure about observe requests - the algorithm will accept the first response and send RST to all subsequent responses, but if the response is NON it might not always cancel the observation. Proactive observe cancellation is being discussed by IETF right now, so maybe it will solve the problem.

Conclusions:

The resulting application is more proof of concept than a perfect solution. Unfortunately the application starts quite slow on Android (around 2 seconds on my SGS3), probably because of Python interpreter. The download is rather big, because it's bundled with Python and its extensions. However the app does its job, runs on Linux and Windows, and at the time of writing it's the only CoAP browser for Android so it might be useful for researchers and testers. I used it successfully with CoAP test servers:

  • TZI Universitat Bremen: coap://coap.me
  • ETH Zurich: coap://vs0.inf.ethz.ch

I am planning to setup my own test server based on txThings and twistd.

Link to the app below:

Sunday, October 13, 2013

Makers - how to win the IoT standards battle

Internet of Things as a bussiness area is currently in a very interesting phase. There are multiple competing standards in both hardware and software. Last year it became obvious, that WiFi is going to be the most important hardware standard, complemented by more specialized standards in some areas (personally I would bet on Dash7 for ultra-low power and energy harvesting apps, and maybe BLE for smartphone apps). WiFi also secures IP domination in the network layer. However at transport layer and above the winner is not yet clear. There are standards like XMPP, MQTT and CoAP which are backed by serious industry players.

Meanwhile there are other interesting technological developments going on. One of the most interesting is the "Maker" culture - a community of programmers, engineers, hobbyists and professionals, who deploy new technologies in unique and inventive ways. Maker community is the rebranding of old DIY culture, but thanks to the Internet it is much more powerful.

I would like to propose a hypothesis: the Internet of Things standard widely accepted by "Arduino/RaspberryPi Maker Community" will become the leading IoT standard for the whole industry. My points:
1) IoT is often described as a solution waiting for a problem. Makers usually solve real-world problems, so it's a good test for a fledgling standard.
2) Maker community is a reservoir of creativity. Makers are developers of low-cost, or free solutions - an equivalent of an "app store for hardware".
3) Makers usually choose technologies which are well-supported, and easy but also powerful. With mass adoption, limits like bad documentation and technological weaknesses become obvious very fast.

It seems that big IoT players aren't doing much to attract Makers to their respective solutions. I think it is going to change in the next couple of months. First one who is able to convince Makers to their solution wins :)

Thursday, September 19, 2013

txThings - "Good enough" is good enough

Long time no see! Last update here was posted more than a year ago. There are multiple reasons for that, but the most important one is that I decided to pause embedded development for a while, and learn more about application layer, and user applications. For a start I decided to write a library for CoAP - new protocol for Internet of Things. I also decided to write it in Python, using Twisted framework. The development has been quite slow, but last month I accidentaly found pyvideo.org site with various Python related videos, and found a brilliant talk by Alex Martelli : "Good enough is good enough"



After watching the video, I decided to quickly finish the work on current features, and release the first version of library, with some features completed, and some missing. I hope to get some feedback from users, so that I can improve the library.

txThings - CoAP Python library

I've decided to call the library txThings - Twisted has a tradition of calling modules with plural nouns (also Coap LIbrary for Twisted gave really bad acronym ;) ).

txThings has the following features:
  • support for draft-ietf-core-coap-13 - including automatic piggyback/separate response handling. No caching support.
  • support for draft-ietf-core-block-12 (no support for server initiative though - waiting for the resolution)
  • limited support for RFC6690 (Core Link Format) - server only.
Other nice things:
  • txThings works nicely on RaspberryPi
  • txThings is compatible with Kivy - brilliant new Python GUI library (I'll post some examples soon).
  • txThings is fully asynchronous (thanks to twisted framework)

txThings installation HowTo

txThings is posted on Github. The easiest way to get it is to clone the repository to your local machine using the command below:

git clone git://github.com/mwasilak/txThings.git

Library contains CoAP code (inside "iot" directory) and three examples:
  • server.py - CoAP server that starts on localhost, port 5683 and hosts several resources
  • client_GET.py - example client which performs GET request to localhost, port 5683
  • client_PUT.py - example client which performs PUT request to localhost, port 5683
Client_GET and client_PUT both use port 61616 - to use them simultaneously change port number in one of the clients. Server will send blockwise responses for default settings. To use txThings you need Python 2.7 with Twisted installed (I suggest using the latest Twisted version, but older releases also work - tested with 11.1).

Current work

Next step is to add Observe and full Core Link Format support to txThings. I am also planning to continue investigating Kivy library.

If you are interested in using txThings and have any questions, don't hesitate to contact me.

Friday, May 25, 2012

World IPv6 Launch Day

June 6th, 2012 is World IPv6 Launch Day - a worldwide event for Internet providers, website owners and institutions. Every organisation is invited to participate - to join the event it needs to enable IPv6 for its products, websites and users.

The event is supposed to promote IPv6 transition, and hopefully, to start a chain reaction. I think that everything has been already said about IPv6 and its adoption process, but I'll repeat once more, that it has to be done. The sooner the better. There are many technologies waiting just around the corner, which can be developed only with larger address pool and end-to-end connectivity provided by IPv6.

The action has a very nice badge and catchphrase, but it doesn't describe the titanic amount of work that has to be done by network engineers, webmasters, programmers, and help-desk employees. The costs of this transition might be enormous. But still it has to be done.

WORLD IPV6 LAUNCH is 6 June 2012 – The Future is Forever