Dartino + uNabto

The experimental open-source project Dartino enables you to write software for embedded systems using the modern Dart language and a set of libraries, that let you be highly productive. So why not add another powerful library? Thanks to  improvements to the FFI library in the latest Dartino SDK, we are now able to use the uNabto framework from within Dartino!

dartino-logo

Note: Due to remaining limitations of the Dartino FFI library this is currently only working on a local PC. Thanks to the Dartino team this might be resolved in the near future…stay tuned!

Why use uNabto in your Dartino solution?

Have you ever thought about connecting to your embedded system running Dartino from outside your local network without nerve-racking router and firewall configurations or heavy and intransparent cloud services? Running the uNabto server on your embedded system, you can establish a fast and secure Peer-to-Peer connection using only a static ID – from everywhere, no matter what is in between.

So how does Nabto do this? The drawing below gives a brief overview. Your embedded system represents the Device running the uNabto server. As soon as it connects to the internet it identifies itself at the Nabto Basestation, using its unique ID. If a Client wants to connect to the embedded system, a connect request with the ID is sent to the Basestation, and a direct connection to the device is established. A client can be a HTML page running in a desktop browser extension (IE, Firefox) or the Nabto Mobile App (iOS, Android), or a custom Nabto API Client. If you prefer Cordova also check out our recently released Nabto Cordova Plugin.

nabto-security

Get the sample application

We published a sample application including the uNabto Dartino library on GitHub. In order to set it up, follow the three steps below.

Step 1: Clone the repository

$ git clone --recursive https://github.com/nabto/unabto-dartino
$ cd unabto-dartino

Step 2: Download and unzip the latest Dartino SDK

Linux:
$ curl "https://storage.googleapis.com/dartino-archive/channels/dev/raw/0.4.0-dev.0.0/sdk/dartino-sdk-linux-x64-release.zip" -o "/tmp/dartino-sdk.zip"
$ unzip /tmp/dartino-sdk.zip

Mac OS:
$ curl "https://storage.googleapis.com/dartino-archive/channels/dev/raw/0.4.0-dev.0.0/sdk/dartino-sdk-macos-x64-release.zip" -o "/tmp/dartino-sdk.zip"
$ unzip /tmp/dartino-sdk.zip

Step 3: Build the C library

$ mkdir build
$ cd build
$ cmake ..
$ make
$ cd ..

Use the sample application

The sample application acts as an embedded device that controls a virtual living room light. To connect to the application we first need to assign a unique Device ID and a pre-shared encryption Key to it. You can get them from developer.nabto.com after adding a new Device. Both id and key are passed as strings to the constructor of the uNabto server:

main() {
  // Configure the uNabto server with a server ID and a pre-shared key obtained
  // from `developer.nabto.com`.
  var unabto = new UNabto("devicename.demo.nab.to", "35d0dca...");

You can now fire up the application on you local PC with the Dartino tool:

$ ./dartino-sdk/bin/dartino run src/app.dart

You should see a log printout similar to this:

15:18:54:118 unabto_common_main.c(127) Device id: 'devicename.demo.nab.to'
15:18:54:118 unabto_common_main.c(128) Program Release 123.456
15:18:54:118 unabto_app_adapter.c(698) Application event framework using SYNC model
15:18:54:118 unabto_context.c(55) SECURE ATTACH: 1, DATA: 1
15:18:54:118 unabto_context.c(63) NONCE_SIZE: 32, CLEAR_TEXT: 0
15:18:54:118 unabto_common_main.c(206) Nabto was successfully initialized
15:18:54:118 unabto_context.c(55) SECURE ATTACH: 1, DATA: 1
15:18:54:118 unabto_context.c(63) NONCE_SIZE: 32, CLEAR_TEXT: 0
15:18:54:118 unabto_attach.c(787) State change from IDLE to WAIT_DNS
15:18:54:118 unabto_attach.c(788) Resolving dns: devicename.demo.nab.to
uNabto version 123.456.
15:18:54:330 unabto_attach.c(809) State change from WAIT_DNS to WAIT_BS
15:18:54:353 unabto_attach.c(474) State change from WAIT_BS to WAIT_GSP
15:18:54:364 unabto_attach.c(266) ######## U_INVITE with LARGE nonce sent, version: - URL: -
15:18:54:375 unabto_attach.c(575) State change from WAIT_GSP to ATTACHED

The uNabto server is now ready and you can connect to it from any client. When entering you device ID into your browser or Nabto App, you can see the uNabto Demo client. Using the light switch you can now turn the virtual living room light on and off from everywhere!

dartino-firefox

Light 1 turned ON!
Light 1 turned OFF!

For demonstration purposes, the example application closes the server connection after ~10 seconds.

The sample application in detail

The sample application is quite straightforward since all complicated interfacing to the native C library is done in the uNabto library. We only need to include it with

import 'unabto.dart';

In the main() function we construct the uNabto server object by passing the Device ID and the pre-shared Key as parameters. However, the server is started later with the init() function. You also might want to check if there were any errors doing that.

  var unabto = new UNabto("devicename.demo.nab.to", "35d0dca...");

  // Get version information.
  print("uNabto version ${unabto.version}.");

  // Attempt to init and start the server.
  int result = unabto.init();
  if (result != 0) {
    print("Init error: $result.");
  } else {

To handle incoming events from the client we register handler functions for every query ID. We’ll come back to the handlers later on.

    // Register two event handlers for the `light_write.json` and
    // `light_read.json` queries.
    unabto.registerReceiver(1, onLightWrite);
    unabto.registerReceiver(2, onLightRead);

You can now do other stuff. The sample application just sleeps for 10 seconds to demonstrate how to close the uNabto server in the end.

    // This is where the main app code would usually run.
    // In this sample we just sleep a bit.
    sleep(10000);

    // Clean-up: Deallocate foreign memory and functions.
    unabto.close();

The following handler takes care of the query with ID #1. It reads the light’s ID and the light’s new state from the incoming readBuffer. The new state is applied to the virtual light. Afterwards, it returns the new state to the client by writing it to the outgoing writeBuffer.

void onLightWrite(UNabtoRequest appRequest, UNabtoReadBuffer readBuffer,
    UNabtoWriteBuffer writeBuffer) {
  // Read the request parameters.
  int lightId = readBuffer.readUint8();
  int lightOn = readBuffer.readUint8();

  // Set the light state.
  int lightState = setLight(lightId, lightOn);

  // Write the response parameter.
  writeBuffer.writeUint8(lightState);
}

The following handler takes care of the query with ID #2. It reads requested light’s ID from the incoming readBuffer, retrieves the state of the virtual light and returns the light’s state to the client by writing it to the outgoing writeBuffer.

void onLightRead(UNabtoRequest appRequest, UNabtoReadBuffer readBuffer,
    UNabtoWriteBuffer writeBuffer) {
  // Read the request parameters.
  int lightId = readBuffer.readUint8();
  int lightState = readLight(lightId);

  // Write the response parameter.
  writeBuffer.writeUint8(lightState);
}

Diving deeper

If you want to explore the whole available interface of the uNabto library have a look at it on GitHub. It also demonstrates how to use the Dartino FFI library to access a foreign library and work with its structures and byte arrays.

Finally, if you want to modify the underlying uNabto C library checkout the files in this directory. For example, In the unabto_config.h you can turn off the logging or disable remote connections.

Snappy Ubuntu Core + uNabto

Today we will have a look at Snappy Ubuntu Core, why it is nice, in principle, and why it still has some way to go before it will really be useful in reality.

Snappy Ubuntu Core, the basics

snappy

Their logo represents the blocks (snaps, kernels, daemons, etc.) that make up a full system.

Snappy Ubuntu Core is “a new, transactionally-updated Ubuntu for IoT devices, clouds and more”. In other words, it’s a new rendition of Ubuntu with some new features as well as a lot of features removed, which we will get back to. It should be noted that the system is also referred to as simply Ubuntu Core (not even the name is set in stone yet) so you will see both ways of writing it in this post.
The main selling point of this free product is that each app, hereafter denounced snaps, are independent blocks, ideally with no external dependencies. This has the huge advantage that a snap can be installed or removed without breaking anything else on the machine. The system can thus be seen as being build by legos, individually separated but put together into a full system.

Installing Ubuntu Core

Getting a copy of Ubuntu Core is fairly straightforward if you just follow the instructions laid out here. As you will quickly notice, Ubuntu Core is available for quite a number of devices although only the Raspberry Pi 2 is supported out of the Pi family at the moment. For IoT projects it does not make a whole lot of sense to run a virtual Ubuntu Core image on a desktop system, but for developing I used it extensively.

So either run a virtual machine using kvm or get your Pi 2 up and running if you feel like following along!

Installing a snap

Once we have Ubuntu Core up and running we can either SSH into it by issuing ssh -p 8022 ubuntu@localhost (virtual kvm) or ssh ubuntu@webdm.local (Pi2) both with the standard password: ubuntu.
Once in, let’s start by getting an overview of the stuff already installed on the machine. We do this by issuing

$ snappy list

The listed items can be either kernels, daemon services or executable binaries, basically everything that makes up our environment.

You should see something like
Name Date Version Developer
ubuntu-core 2016-01-28 7 ubuntu
webdm 2016-01-28 0.11 canonical
pi2 2016-01-28 0.16 canonical

First of,  version 7 of the ubuntu-core is quite old so we run

$ sudo snappy update

to update the system. If webdm is not installed already, then we also install it by issuing

$ sudo snappy install webdm

This service basically gives us a graphical user interface to the Snappy Store which we can access if we are on the Pi2 by opening a browser (on desktop machine) and going to webdm.local:4200.

webdm_store

The Snappy store

Here we basically see the graphical presentation of what we just saw in the command line. We can also see the available snaps for this architecture.
Going back to the command line we can also get a list of all the available snaps for the current architecture by issuing

$ snappy search '*'

At the time of writing this (10th of May 2016) there are exactly 100 snaps available for the Pi2 and 92 for amd64 so the framework is still in its infancy. To search for a specific app we try searching for the unabto snap

$ snappy search unabto

if successful we can install it as before, by issuing

$ sudo snappy install unabto

After it installs, we can try issuing

$ unabto.unabto

which will work perfectly on a 64 bit machine but on the Pi2 we will see this error

$ wiringPiSetup: Must be root. (Did you forget sudo?)

trying the same command with sudo will result in

$ wiringPiSetup: Unable to open /dev/mem: Operation not permitted

to find out why, we need to have a look at how snaps are created

Creating a snap

As mentioned, the number of available snaps to install is still fairly limited and so is the documentation for creating snaps. Through the iterations of the build tool and the Ubuntu Core itself, the specific commands and instructions have changed and there is thus no consensus on how to actually do essential things. Many of the examples given cannot compile with my version of their build tool, called snapcraft.
But still, we march on and we will begin with the way Ubuntu Core wants you to use it.
On my amd64 machine I installed snapcraft by following the instructions here

$ sudo add-apt-repository ppa:snappy-dev/tools
$ sudo apt-get update
$ sudo apt-get install snapcraft

To get a feel of how snapcraft “crafts” programs into snaps we issue

$ snapcraft help plugins

to see all the steps that snapcraft does behind the scenes. For future reference the version I used was 1.1.0 on Linux Mint 17.3 Cinnamon 64-bit.
The only thing we really need to get something going for us is a snapcraft.yaml file as well as an icon. snapcraft.yaml contain instructions for snapcraft so that it knows what to do. In our simple example we write (you can find this code on github as well)

# Notice! Name cannot contain underscore
name: unabto-test
version: 0.1
summary: some summary
description: some description
vendor: mt@nabto.com
icon: icon.png

# Needed packages. If not found on system, snapcraft will install them
build-packages: [openssl, cmake, git]

# To be able to call the binaries in our snap directly from the command line we define binaries
binaries:
  # note, the name to write for
  # executing the binary below it. These two names cannot
  # be the same !
  unabto:
    exec: bin/unabto_raspberrypi
    # We have to allow the bin/binary to open
    # sockets and the like. For this, we use set permissions using the plugs term
    plugs: [network-bind]

# The parts the snap will consist of
parts:
  unabto:
    plugin: cmake
    source: git://github.com/nabto/unabto.git

Note that the above example is NOT exactly how most of the examples found in the Ubuntu Core github  are made at the moment (most of them cannot compile with my version of snapcraft). I suspect this is due to differences between releases and will probably be resolved in time.
Having the snapcraft.yaml file and icon.png in the same folder, now comes the magic!
Simply issue

$ snapcraft

Which will go through the stages laid out in $ snapcraft help plugins. You will notice that the directory now contain
unabto, parts, stage and snap as well as what we are actually interested in, unabto_0.1_amd64.snap, which is our snap! So yeah, that was really all we needed to create a standalone snap, wow !

Now we would like to check out how it works. You will no doubt have noticed the _amd64 in the filename, meaning that this snap is for an Ubuntu Core 64 bit machine. The reason for this is that snapcraft does not support cross compiling (I could not get it to work, at least) and we will later see how to circumvent this.
For now, we transfer and install our newly created snap on our virtual machine by issuing

$ snappy-remote --url=ssh://localhost:8022 install unabto_0.1_amd64.snap

This should run without any problems. We can check if the snap was succesfully installed by sshing into the virtual machine and issue $ snappy list as before. unabto should now appear on the list and we can run the binary we specified in the snapcraft.yaml file by issuing

$ unabto-test.unabto -d id -s -k key

where id and key is created at developer.nabto.com
If everything went as it should you will see a few lines of output ending with

$ 00:04:32:160 unabto_attach.c(575) State change from WAIT_GSP to ATTACHED

which is a sign of success !
We can now access the id in a browser and thus remotely control whatever unabto is running on, great success !
To see some real life uses please check out The CoffeePi (Part 1 of 2)The CoffeePi (Part 2 of 2) and The SunPi control center

Creating a multi architecture snap and creating some actual value into it

Now, I already said snapcraft can’t do crosscompiling so we need to do something else. The easiest way is to create a binary the old fashioned way for each architecture. For this we simply need a compiler for that architecture, as the name suggest. I used this to compile for the raspberry pi. Simply download it and go to the unabto/apps/raspberry_pi folder. If you don’t already have a copy of the uNabto SDK, you can grab one here. In this folder we issue

$ export CC=path/to/raspi_gcc

before issuing the usual

$ cmake .

and

$ make

We can check if the resulting binary really was compiled for an arm board by issuing

$ file raspberry_binary

which should return something like

$ unabto: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=cbb7dfe8560ba3e63dfffa621cad56f301fff1e7, not stripped

Make sure your main snap folder contain a bin, lib and meta folder as can be seen in the uNabto Ubuntu Core github repository. In bin we create a folder for each architecture as well as an executable that makes sure which to choose depending on the device. You can check that out on github as well. In meta we need an icon, a readme.md and a file almost like before, but this time called package.yaml

name: unabto
vendor: Marcus Therkildsen
architecture: [amd64, armhf]
icon: meta/icon.png
version: 0.1

binaries:
- name: bin/unabto

This time we notice that we defined “architecture: [amd64, armhf]” which should list all the archs we plan on incorporating in our multisnap. Now we can simply issue

$ snappy build

which will create unabto_0.1_multi.snap. This snap can now be installed on all the architectures we compiled each package for. This is done in the same way as before using the snappy-remote command. Again we can run it by issuing

$ unabto.unabto -d id -s -k key

and voila, we now have a working multi arch snap.
Still, the snap doesn’t really do anything other than controlling a dummy switch in the unabto code

Adding functionality

So what if we wanted to use the gpio pins on the RPi2?
Well, all functionality that a snap should have should be contained in the snap itself. That is, after all, the main selling point of Ubuntu Snappy Core. If you had the audacity to try to do anything on Ubuntu Snappy Core anyway you would quickly realise that

curl
wget
apt-get
make
cmake

and many other commands we are used to from Linux is missing. Ubuntu Snappy Core is truly not made for creating anything ON but made for executing stuff made for it on a different, ordinary linux distro. This gets really frustrating fast until you accept that this is the premise of Ubuntu Snappy Core.

The library I usually use for controlling gpio pins on any Raspberry Pi is called wiringPi  so we are going to compile that for our Pi2 and add it as a library. I ended up busting out my old Pi1 to compile the wiringPi library, then transferred it to my 64 bit machine and put it into lib/arm-linux-gnueabihf, as can be seen here. For future reference, these binaries are wiringPi 2.29.
Again, I compiled using snappy build and got a nice multi arch snap which we install as before.

Back on the Pi2 we issue

$ unabto.unabto

and are met with

$ wiringPiSetup: Must be root. (Did you forget sudo?)

and with sudo

$ wiringPiSetup: Unable to open /dev/mem: Permission denied

which leaves us exactly back at where we started.
So I tried many things to get this working. Since the newest version of wiringPi has a workaround for running without sudo (which I actually got working on my Pi1 running Raspbian) I tried to do the same thing here.
This involved remounting the read-only filesystem to make it writable, move around some libraries, add some paths and so forth. This totally goes against the Ubuntu Snappy Core principles and ultimately did not work anyway.
Now, if we run snappy -h on our Pi2 we see there is a way of assigning a hardware device to a package. We try that by issuing

$ sudo snappy hw-assign unabto.nabto /dev/mem

but it still did not work.
Thus, we saw that we cannot add hardware support the way Ubuntu Snappy Core states at their website and we really should not be messing around with remounting the filesystem.

This leaves us with the compromise of creating a custom wrapper, setting the library paths and calling the correct executable. This is already in the package (run_unabto)  so what we ultimately have to do to finally get something working is this:
Just after sshing into you Pi2 Ubuntu Snappy Core, issue this

$ echo "alias run_unabto=/apps/unabto.nabto/current/bin/arm-linux-gnueabihf/run_unabto" >> .bashrc

and then reboot. After this, we are now able to write

$ run_unabto -d id -s -k key

where id and key are found at developer.nabto.com and unabto should finally be running, wopeeh! But what is perhaps even more interesting, is the fact that if we hook up an LED to wiringPi pin number 0 we actually control something now instead of just the dummy switch we saw earlier plus we are as close as can be to the philosophy of Ubuntu Snappy Core: snaps should be selfcontained.
If we decide to remove unabto by issuing

$ sudo snappy remove unabto

and

$ sudo snappy purge unabto

the only remnant of unabto will be the last line in our .bashrc file and I can live with that.

Whuu, that was a bit of a mouthfull!

As seen, it is definitely possible to create snaps for Ubuntu Snappy Core. With time, glitches like examples that won’t compile and outdated tutorials will hopefully be fixed.

If nothing else, it is now possible to run unabto on Ubuntu Snappy Core and actually do something useful with it !

To finish things of, you can publish your snap to the Ubuntu store very easily by following the instructions here. If you would like to check out the code we used for creating the uNabto snap, please check out the relevant github repository.
If you would like to see how to add some more funtionality into your own uNabto snap, please check out The CoffeePi (Part 1 of 2)The CoffeePi (Part 2 of 2) and The SunPi control center.

Nabto + FreeRTOS running on Cortex-M7 using the ST STM32F746G-DISCO Board

When working with STM32 ARM Cortex-M microcontrollers, the free embedded software STM32Cube from ST provides all necessary drivers and a collection of middleware components to reduce the initial development effort. One of the mentioned middleware components is the popular FreeRTOS real-time operating system Nabto is partnering with to create a powerful combined FreeRTOS+Nabto solution. This article explains the implementation of a demo project running Nabto + FreeRTOS on a STM32F746G-DISCO board.

nabto+stm32

STM32F74G-DISCO board running the demo

What you need

This demo is based and tested on the STM32F746G-DISCO board, but should be portable to similar STM32 boards. Same applies to your favorite IDE.

Why Nabto and how does it work?

Have you ever thought about connecting to your STM32 device from outside your local network without nerve-racking router and firewall configurations or heavy and intransparent cloud services? Running the uNabto server on your STM32 device, you can establish a fast and secure Peer-to-Peer connection using only a static ID – from everywhere, no matter what is in between.

So how does Nabto do this? The drawing below gives a brief overview. Your STM32 board represents the Device running the uNabto server. As soon as it connects to the internet it identifies itself at the Nabto Basestation, using its unique ID. If a Client wants to connect to the STM32 board, a connect request with the ID is sent to the Basestation, and a direct connection to the device is established. A client can be a HTML page running in a desktop browser extension (IE, Firefox) or the Nabto Mobile App (iOS, Android), or a custom Nabto API Client. If you prefer Cordova also check out our recently released Nabto Cordova Plugin.

Screen Shot 2016-02-29 at 13.23.22

Nabto in the STM32Cube Architecture

As mentioned before the STM32Cube provides a Hardware Abstraction Layer API and a selection of Middleware components. The uNabto server we want to implement builds on top of the STM32Cube middleware, as can be seen in the following diagram:

nabto+stm32cube-architecture.png

The uNabto server itself is divided into two layers:

  • The actual uNabto framework (uNabto SDK)
  • The uNabto Platform Adapter abstraction layer between the uNabto framework and the STM32Cube middleware

Hence, we only need to implement the uNabto Platform Adapter, in order to port the uNabto server to the STM32 platform.

Implementing the Platform Adapter

The Platform Adapter acts as link between the generic uNabto framework and the STM32Cube middleware layer, including the LwIP TCP/IP stack which will be used for networking. The LCD Log Utility is used to display the Nabto output on the screen.

The adapter is divided into single files, as suggested in the Nabto documentation (TEN023 Writing a uNabto device application, chapter 12):

  • unabto_config.h: Basic uNabto configuration
  • unabto_platform_types.h: Defines all necessary uNabto types
  • unabto_platform.h: Platform specific ad-hoc functions
  • network_adapter.c: Init, close, read and write functionality for network data
  • time_adapter.c: Time functions
  • dns_adapter.c: DNS resolving
  • random_adapter.c: Random generator
  • log_adapter.c: Logging

If you are interested in how the platform adapter is implemented in detail, check the adapter files in the Inc and Src directories of the demo on GitHub.

Implementing the Nabto Thread

After creating the Platform Adapter the uNabto Server is ready to use and the actual uNabto Device Application can be implemented. This is done in Src/nabto.c. Since the server will run in its own FreeRTOS thread, we first create the following thread method.

static void nabto_thread(void *argument)
{
  const char* nabtoId = "<DEVICE ID>";
  const char* presharedKey = "<KEY>";

  struct netif *netif = (struct netif *) argument;

  // Initialize Nabto
  nabto_main_setup* nms = unabto_init_context();
  nms->ipAddress = netif->ip_addr.addr;
  nms->id = nabtoId;
  nms->secureAttach = 1;
  nms->secureData = 1;
  nms->cryptoSuite = CRYPT_W_AES_CBC_HMAC_SHA256;

  const char *p;
  unsigned char *up;
  for (p = presharedKey, up = nms->presharedKey; *p; p += 2, ++up)
    *up = hctoi(p[0]) * 16 + hctoi(p[1]); // convert hex string to byte array

  unabto_init();

  for (;;) {
    osDelay(10);
    unabto_tick();
  }
}

It initializes the server among others with your unique Nabto ID and the pre-shared encryption key from developer.nabto.com (insert in highlighted lines). Then it starts an infinite loop calling the unabto_tick() method. This triggers the framework to check for new UDP packets and send responses. The time between ticks should be around 10 milliseconds, which is achieved by a hard OS delay.
To start the Nabto thread we provide a nabto_init() method. It is called by the main program after initializing the TCP/IP stack and either setting a static IP address or obtaining a dynamic IP address from a DHCP server.

void nabto_init(struct netif *netif)
{
  sys_thread_new("Nabto", nabto_thread, netif, DEFAULT_THREAD_STACKSIZE, NABTO_THREAD_PRIO);
}

The actual handling of received Nabto messages from the client is implemented in the application_event() function. The handler uses the message format used in the default HTML Device Driver, provided in the Nabto portal. In this demo the LCD display can be switched on and off by the client. For more information on how to create your own HTML DD, please refer to TEN024 Writing a uNabto HTML client.

application_event_result application_event(application_request* appreq,
                                           unabto_query_request* r_b,
                                           unabto_query_response* w_b)
{
  switch (appreq->queryId) {
  case 1: {
    // <query name="light_write.json" description="Turn light on and off" id="1">
    // <request>
    // <parameter name="light_id" type="uint8"/>
    // <parameter name="light_on" type="uint8"/>
    // </request>
    // <response>
    // <parameter name="light_state" type="uint8"/>
    // </response>
    // </query>

    uint8_t light_id;
    uint8_t light_on;

    // Read parameters in request
    if (!unabto_query_read_uint8(r_b, &light_id))
      return AER_REQ_TOO_SMALL;
    if (!unabto_query_read_uint8(r_b, &light_on))
      return AER_REQ_TOO_SMALL;

    // Set display according to request
    display_state = light_on;
    if (display_state)
      BSP_LCD_DisplayOn();
    else
      BSP_LCD_DisplayOff();

    // Write back display state
    if (!unabto_query_write_uint8(w_b, display_state))
      return AER_REQ_RSP_TOO_LARGE;

    return AER_REQ_RESPONSE_READY;
  }
  case 2: {
    // <query name="light_read.json" description="Read light status" id="2">
    // <request>
    // <parameter name="light_id" type="uint8"/>
    // </request>
    // <response>
    // <parameter name="light_state" type="uint8"/>
    // </response>
    // </query>

    uint8_t light_id;

    // Read parameters in request
    if (!unabto_query_read_uint8(r_b, &light_id))
      return AER_REQ_TOO_SMALL;

    // Write back led state
    if (!unabto_query_write_uint8(w_b, display_state))
      return AER_REQ_RSP_TOO_LARGE;

    return AER_REQ_RESPONSE_READY;
  }
  }
  return AER_REQ_INV_QUERY_ID;
}

Hands-On!

Enough theory. Let’s try out the demo! It is available as System Workbench for STM32 (SW4STM32) project here on GitHub. Simply follow the instructions in the README.

The board should now print out the Nabto log on the LCD screen, like on the picture in the beginning of the article.

When entering you device ID into your browser or Nabto App, you can see the uNabto Demo client. Using the light switch you can now turn the LCD Display on and off from everywhere!

stm32-demo-screenshot

ESP8266 WiFi Module + Nabto

The ESP8266 is a low-cost WiFi module that can be programmed directly like a microcontroller. Already thinking of your next Internet of Things project?

While an available Arduino library allows a quick start, there is still one problem to overcome: How to access your ESP8266 from outside your home network without nerve-racking router and firewall configurations or heavy and intransparent cloud services? Running the uNabto server on your ESP8266, you can establish a fast and secure Peer-to-Peer connection using only a static ID – from everywhere, no matter what is in between.

What hardware you’ll need

IMG_20160303_153803

Adafruit HUZZAH ESP8266 Breakout

IMG_20160303_153830

USB to TTL Serial Cable

This project is tested on an Adafruit ESP8266 board. It’s not the cheapest you can get, but very prototyping friendly. You can put it on a breadboard and it has a 3.3V voltage regulator onboard. Of course, you can also use a different ESP8266 module. Wikipedia provides an extensive list of available modules.

Regarding the USB to TTL Serial Cable (get it e.g. here), there are no special requirements when using the Adafruit module. If you use a different module, make sure the voltage levels match, since most boards only accept 3.3V.

Solder the pin header to your ESP8266 board and connect it to your USB to TTL adapter using 4 wires:

wiring

What software you’ll need

This project is tested on Ubuntu 15.10 but should work on any OS supported by the Arduino IDE.

We want to program the ESP8266 directly, instead of using any higher level interpreters available for the module. Adafruit provides a nice tutorial on how to setup your  Arduino IDE accordingly.

If everything is running, you should be able to compile the following simple sketch and upload it to your ESP8266. This will make the onboard LED blink every second.

const int led = BUILTIN_LED;

void setup() {
  pinMode(led, OUTPUT);
}

void loop() {
  digitalWrite(led, HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
}

How the Nabto platform works

So far, so good. But how does the Nabto platform actually work? The drawing below gives a brief overview. Your ESP8266 module represents the Device running the uNabto server. As soon as it connects to the internet it identifies itself at the Nabto Basestation, using its unique ID. If a Client wants to connect to the ESP8266, a connect request with the ID is sent to the Basestation, and a direct connection to the device is established. A client can be an HTML page running in a desktop browser extension (IE, Firefox) or the Nabto Mobile App (iOS, Android), or a custom Nabto API Client.

nabto-platform-basics

Get more information on the Nabto platform and the Client/Device SDKs on developer.nabto.com.

The uNabto Platform Adapter

The uNabto server is divided into two layers:

  • The actual uNabto framework (uNabto SDK)
  • The uNabto Platform Adapter abstraction layer between the framework and the Native Platform

unabto-platform-adapter

Hence, we only need to implement the uNabto Platform Adapter, in order to port the uNabto server to the ESP8266 module.

Implementing the Platform Adapter

The Platform Adapter acts as link between the generic uNabto framework and the Arduino platform, including the ESP8266 WiFi library. The adapter is divided into single files, as suggested in the Nabto documentation (TEN023 Writing a uNabto device application, chapter 12):

  • unabto_config.h: Basic uNabto configuration
  • unabto_platform_types.h: Define all necessary uNabto types
  • unabto_platform.h: Platform specific ad-hoc functions
  • network_adapter.cpp: Init, close, read and write functionality for network data
  • time_adapter.cpp: Time functions
  • dns_adapter.cpp: DNS resolving
  • random_adapter.cpp: Random generator
  • log.cpp: Logging

If you are interested in how the platform adapter is implemented in detail, check the adapter files in the src directory of the library on GitHub.

Using the Library

Get the Nabto ESP8266 Arduino library from https://github.com/nabto/unabto-esp8266-sdk and place it in your Arduino library directory. If you don’t know where your library directory is located, see the guide on manual installation of Arduino libraries.

After restarting your IDE the library is installed. An example sketch can be found in

File -> Examples -> Nabto-ESP8266 -> LightSwitch

The sample sketch includes the Nabto class, which encapsulates the Nabto setup. First, some settings are made. This includes the WiFi SSID and password, followed by the unique Nabto ID and preshared key of the device, as well as the pin of the onboard LED to be controlled.

#include <Nabto.h>

// Enter ssid and password of your WiFi network
const char* ssid = "...";
const char* password = "...";

// Enter device id and preshared key from developer.nabto.com
const char* nabtoId = "...";
const char* presharedKey = "...";

// Specify LED pin
const int led1_pin = BUILTIN_LED;

The setup function is used to init the LED pin and the Serial module. In line 42 you can see how the Nabto module is initialised. The begin(..) function is blocking, therefore, the following printout of the Nabto version number only takes place, if the WiFi connection was established.

void setup() {
  // Initialize built-in led
  pinMode(led1_pin, OUTPUT);
  digitalWrite(led1_pin, 1);

  // Initialize Serial
  Serial.begin(115200);

  // Initialize Nabto
  Serial.println("Init...");
  Nabto.begin(ssid, password, nabtoId, presharedKey);

  // Optionally get nabto firmware version
  char versionString[10];
  Nabto.version(versionString);
  Serial.print("Nabto v");
  Serial.print(versionString);
  Serial.println(" running...");
}

The only thing that needs to be done in the loop function is to call the tick() method of the Nabto class. This triggers the framework to check for new UDP packets and send responses. The time between ticks should be around 10 milliseconds. This is achieved by a hard delay, but you can also use the time to do application related stuff.

void loop() {
  // Check for new nabto udp packets and send response. Non-blocking
  Nabto.tick();

  // We have chosen to sleep 10 milliseconds between tics
  delay(10);
}

The following two functions provide a convenient way to set and read the LEDs, although we will only use one LED in this example.

// Set LED and return state.
// Only using ID #1 in this simple example
uint8_t setLed(uint8_t led_id, uint8_t led_on) {
  if (led_id == 1) {
    // inverted
    digitalWrite(led1_pin, !led_on);
    return !digitalRead(led1_pin);
  }
  else {
    return 0;
  }
}

// Return LED state.
// Only using ID #1 in this simple example.
uint8_t readLed(uint8_t led_id) {
  if (led_id == 1) {
    // inverted
    return !digitalRead(led1_pin);
  }
  else {
    return 0;
  }
}

The actual handling of received Nabto messages from the client is implemented in the application_event(..) function. The handler uses the message format used in the default HTML Device Driver, provided in the Nabto portal. For more information on how to create your own HTML DD, please refer to TEN024 Writing a uNabto HTML client.

application_event_result application_event(application_request* appreq, unabto_query_request* r_b, unabto_query_response* w_b) {
  switch(appreq->queryId) {
  case 1:
    {
      //  <query name="light_write.json" description="Turn light on and off" id="1">
      //    <request>
      //      <parameter name="light_id" type="uint8"/>
      //      <parameter name="light_on" type="uint8"/>
      //    </request>
      //    <response>
      //      <parameter name="light_state" type="uint8"/>
      //    </response>
      //  </query>

      uint8_t light_id;
      uint8_t light_on;
      uint8_t light_state;

      // Read parameters in request
      if (!unabto_query_read_uint8(r_b, &light_id)) return AER_REQ_TOO_SMALL;
      if (!unabto_query_read_uint8(r_b, &light_on)) return AER_REQ_TOO_SMALL;

      // Set light according to request
      light_state = setLed(light_id, light_on);

      // Write back led state
      if (!unabto_query_write_uint8(w_b, light_state)) return AER_REQ_RSP_TOO_LARGE;

      return AER_REQ_RESPONSE_READY;
    }
  case 2:
    {
      //  <query name="light_read.json" description="Read light status" id="2">
      //    <request>
      //      <parameter name="light_id" type="uint8"/>
      //    </request>
      //    <response>
      //      <parameter name="light_state" type="uint8"/>
      //    </response>
      //  </query>

      uint8_t light_id;
      uint8_t light_state;

      // Read parameters in request
      if (!unabto_query_read_uint8(r_b, &light_id)) return AER_REQ_TOO_SMALL;

      // Read light state
      light_state = readLed(light_id);

      // Write back led state
      if (!unabto_query_write_uint8(w_b, light_state)) return AER_REQ_RSP_TOO_LARGE;

      return AER_REQ_RESPONSE_READY;

    default:
      return AER_REQ_INV_QUERY_ID;
    }
  }
}

Test your device

After compiling and uploading your LightSwitch sketch to the ESP8266, it establishes a connection to your WiFi network and starts the uNabto server. In your serial monitor you should see the following printout:

Init...
Device id: 'mydeviceid.demo.nab.to'
Program Release 2.21889
Application event framework using SYNC model
SECURE ATTACH: 1, DATA: 1
NONCE_SIZE: 32, CLEAR_TEXT: 0
Nabto was successfully initialized
Nabto v2.21889 running...
SECURE ATTACH: 1, DATA: 1
NONCE_SIZE: 32, CLEAR_TEXT: 0
State change from IDLE to WAIT_DNS
Resolving dns: mydeviceid.demo.nab.to
State change from WAIT_DNS to WAIT_BS
State change from WAIT_BS to WAIT_GSP
######## U_INVITE with LARGE nonce sent, version: - URL: -
State change from WAIT_GSP to ATTACHED

When entering you device ID into your browser or Nabto App, you can see the uNabto Demo client. Using the light switch you can now turn the built-in LED on and off from everywhere!

Screenshot_2016-03-05-14-50-37

Future improvements

Currently, the WiFi SSID and password, as well as the device ID and the preshared key are stored in the ESP8266’s flash memory. This requires an update of the source code and a firmware upload on every change of these parameters. A possible solution to this problem could be a very small web server running on the ESP8266, which is accessible through a parallel running WiFi access point. The parameters entered through the web interface could then be persistently stored in the EEPROM.

Raspberry Pi 3 IoT, perfect for Nabto

A few days ago (29/2-2016) the new Raspberry Pi 3 was announced. Of course we were all excited here at the Nabto headquarters and quickly bought a few.

Since they are reviewed as the perfect platform for IoT we wanted to check out if it is perfect for Nabto as well. Spoiler alert: it is !

Setting up the Pi 3

The fastest way to get wifi and Nabto up and running on your Pi 3 is to burn an image to your sd card (for this post we are using Raspbian Jessie Lite). After doing that, hook up your Pi3 by wire to your local network. You can now access the Pi, either directly by HDMI and a keyboard or over SSH.

One of the main features of the new Pi3 is the onboard wifi module so the first thing to do is to search for available networks and make the Pi autoconnect to the one we want. This is most easily done by issuing the following commands one line at a time

wpa_cli
scan
scan_results
add_network
set_network 0 ssid "ssid_name"
set_network 0 psk "password_stuff"
enable_network 0
save_config
quit

Where you should, of course, replace ssid_name and password_stuff with the SSID and password of the network you are trying to connect to.
After that you can reboot the Pi and remove the wire and you have a Raspberry Pi 3 ready for IoT!

Setting up Nabto

Setting up Nabto is as easy as setting up the wifi. First of we need to get the necessary tools for getting the uNabto files and compiling for the Raspberry Pi. This is done by issuing the following commands one line at a time

sudo apt-get install git
sudo apt-get install cmake
git clone https://github.com/nabto/unabto.git
cd unabto/apps/raspberry_pi
cmake .
make

We now have Nabto compiled on our Pi!
All that is left to do is to create a new device at portal.nabto.com. Simply Add Device and copy the newly created Key 

We now return to the Raspberry Pi and issue the following command for initiating the Nabto software

sudo ./unabto_raspberrypi -d "id".demo.nab.to -s -k "key"

You should see a couple of lines of output ending with

13:40:47:548 unabto_attach.c(575) State change from WAIT_GSP to ATTACHED

Which means Nabto is successfully up and running!

Trying out Nabto

Now that everything is up and running the final thing to do is to access id.demo.nab.to in your browser. You will be met with a log in page, simply click Guest, followed by an image like this

html_dd

The uNabto demo is up and running!

Sliding the switch to either side will now trigger the onboard activity light on your Raspberry Pi, check it out!

For a more in depth introduction on how to write your own functionality into the Nabto framework, please refer to this blog post The SunPi control center.