Nabto AppMyProduct using FreeRTOS Windows Simulator

Why choose FreeRTOS:

FreeRTOS is the market leading real time operating system and the de-facto standard solution for microcontrollers and small microprocessors. Few major Advantages of FreeRTOS are below

  • Provides methods for multiple threads or tasks, mutexes, semaphores and software
    timers. Thread priorities are supported.
  • Very small memory footprint, low overhead, and very fast execution.
  • A tick-less mode is provided for low power applications.

Nabto with FreeRTOS:

With Nabto AppMyProduct you can easily create a remote accessible device. You integrate a simple piece of software on the device firmware and now you are able to create an apps which can securely remote access and control your device even though the device resides behind your home firewall.

This blog demonstrates how Nabto application is built using the FreeRTOS Windows simulator. Windows simulator is used to evaluate the Nabto with FreeRTOS as proof of concept to ensure the software works as expected before porting to any particular hardware with Windows platform – however it should be noted that the simulator will not exhibit real time behaviour.

Nabto with FreeRTOS is a piece of C code, when integrated into an embedded networked
device, the device can be remotely accessed and controlled using a web based user interface or intelligent data acquisition system by using Nabto client APIs.

Every IoT (Internet of Things) device has a unique URL for automatic location over the Internet, and the technology allows secure, authenticated and extremely low bandwidth peer-to-peer connections to be established even when the device is deployed behind a NAT firewall. Nabto with FreeRTOS enabled IoT devices are even accessible over a local network in the absence of Internet connectivity.

The cloud infrastructure enables IoT devices to be accessed through a custom built user interface running in a smart phone app – the IoT device supplies the live data components of the interface (Example: Heatpump) by using a light weight UDP protocol.

 

RTOS-img1

About Nabto AppMyProduct:

AppMyProduct is an IoT application platform that helps you to
1. Quickly develop high-quality client side apps using the provided APIs
2. Customize the device side application using the provided demo application.
3. The uNabto framework and the client APIs can be downloaded using the below link.

https://www.nabto.com/downloads.html

uNabto Framework:

The drawing below gives a brief overview of how the Nabto platform actually work.
The Device represents the smart device and the uNabto server (uNabto SDK and Device specific Platform adapters) is running on the device. As soon as device connects to the Internet it identifies itself at the Nabto Basestation, using its unique ID which is already registered in AppMyProduct portal.

If a Client wants to connect to the device, a connect request with the device ID is sent to
the Basestation, and a direct connection to the device is established after verifying the identity of client. A client can be a native mobile app or an abstraction framework like our AMP Heat app used in this demo

nabto-platform-basics

Get more information on the AppMyProduct platform and the Client/Device SDKs
at appmyproduct.com.

The uNabto Platform Adapter:

The uNabto Platform Adapter is a small component that abstracts the Native Platforms
network and time functionality. The Platform Adapter is part of the uNabto server.
The uNabto server is divided into two layers:

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

unabto-platform-adapter

The device specific uNabto server is readily available in AppMyProduct portal to port it to the FreeRTOS Windows module.

Implementation:

Nabto with FreeRTOS application securely connects your embedded device while handling networking, routing and encryption tasks. While using Nabto with FreeRTOS cloud hosting service, an embedded developer need to:

  1. Provide a network driver to interface FreeRTOS+UDP to their hardware platform.
  2. Add the Nabto with FreeRTOS source files to their project.
  3. Set ipconfigFREERTOS_PLUS_NABTO to 1 in FreeRTOSIPConfig.h (the
    FreeRTOS+UDP configuration file).
  4. Provide a single event handling C function to handle pre-formatted Nabto queries.

Nabto Queries:

Unique identifiers are used to distinguish between query types while data is sent to and
requested from a remote networked device in a simple UDP query packet.

A query can contain zero or more request parameters based on the operation triggered by the client application. Request parameters are used to send data to the remote networked device. Nabto with FreeRTOS automatically passes request parameters into the event handling C function.

RTOS-img2

Some query types require the remote networked device to respond with data. The application developer has to pass the response parameters using the event handling C function. Queries can be sent from a web based user interface (AMP Heat app).

FreeRTOS Windows Port for Heatpump Device Stub:

Download the port library from https://github.com/nabtodaemon/FreeRTOS-Nabto and follow the below installation instructions.

This demo uses the Microsoft Visual Studio (MSVC) version of the FreeRTOS Windows
simulator. The project can be build and debugged with the free Express edition of MSVC.

Steps:

  1. Download the source code (Freertos-Nabto.zip) and extract it.
  2. Ensure Microsoft Visual Studio (MSVC) is installed.
  3. Open the MSVC solution called FreeRTOS_Plus_UDP_with_CLI.sln, which is
    located in the \FreeRTOS-Plus\
    Demo\FreeRTOS_Plus_UDP_and_CLI_Windows_Simulator directory.
  4. The demo uses WinPCap to create a virtual network connection by accessing raw Ethernet data on a real network connection

Introducing the unabto_config.h configuration file:

The Nabto source files contain several constants that affect its behavior. Default values for each constant are set in unabto_config_defaults.h. To modify a value from its default setting,re-define the value in unabto_config.h (do not edit unabto_config_defaults.h).

Network configuration:

This demo project is supplied with ipconfigUSE_DHCP set to 1 in FreeRTOSIPconfig.h. If
DHCP is not used a static IP address must be configured and ipconfigUSE_DHCP must be
set to 0.

Steps:

  1. The static IP address is set by the constants configIP_ADDR0 to configIP_ADDR3.
    Edit these constants to appropriate values for your network. The chosen address must be compatible with the network, and unique on the network (the IP address will be compatible if its first three octets match the first three octets of other IP addresses on the same network).  This step shall be skipped if DHCP is used.
  2. Most Windows computers have more than one physical network interface, so it is
    necessary to define which interface the stub will use. A mapping of interfaces to
    interface numbers is displayed when the tutorial application is executed (see Figure
    below). Set configNETWORK_INTERFACE_TO_USE to the number of the interface to
    use.

Network-Config

Device URL:

Every Nabto with FreeRTOS device on a network must have a unique URL. The URL is
obtained by calling an application defined callback function pcApplicationNabtoDeviceURL().Applications that use Nabto with FreeRTOS must provide an pcApplicationNabtoDeviceURL() implementation. pcApplicationNabtoDeviceURL() can be found in main.c.

const char *pcApplicationNabtoDeviceURL(void)
{ 
    /* Enter your device id here */ 
    static const char * pcURL = "abc.xyz.appmyproduct.com";

    /* Return the URL that will be used by the device.  The URL must be in 
    persistent memory (not declared on the stack of this function), and 
    unique on the network.
    A unique URL can be created by prefixing the main URL with the serial 
    number or MAC address of the device (or any other unique identifier).
    It is ok in this case to use a simple constant string, provided only one 
    instance of this project is connected to the network at any one time, and 
    that the default project configuration is not changed to allow remote 
    access. */ 

    return pcURL;
}

Device Key:

Every Nabto with FreeRTOS device on a network has got a key associated with it. The device key is encoded in the function xStartNabtoTask() found in nabto_task.c (folder: FreeRTOS+/Source/FreeRTOS+Nabto/platforms/freertos_net/nabto_task.c)

/* Set device key */ 
if (!unabto_read_psk_from_hex("<device-key>", nms->presharedKey, PRE_SHARED_KEY_SIZE)) 
{ 
    vOutputString("Invalid cryptographic key specified"); 
    return false; 
}

Local Vs Remote access:

Nabto with FreeRTOS can be configured to accept connections from local (non-internet)
addresses or accept connections from remote (internet) addresses, or accept connections
from both local and remote addresses simultaneously.

The unabto_config.h file supplied with this demo is configured to accept both local and remote connections.

Running the Heatpump stub:

Start the Heatpump demo by selecting “Start without Debugging” from the Visual Studio’s
Debug menu. A Windows console will open displaying the available network adapters and the network configuration.

RTOS-HP-stub1

The device will try to register with the Nabto Basestation. Once the device gets registered
with Basestation, you will see the message “State change from WAIT_GSP to ATTACHED”
as in the below figure.

RTOS-HP-stub2

Now, using the AMP Heat app (available on Google play store and Apple app store) connect your device and verify whether it works. When the AMP Heat app is started for the first time, you need to pair your client with the device. Then on, the paired device will be automatically discovered if it is online.

AMP-stub1

AMP-stub2

FAQ:

Why I am unable to connect to the device?

The windows simulator creates a virtual network interface by reading and writing raw Ethernet data through a real network interface. Any connection issues encountered are likely to be related to the operation of the virtual interface, not the operation of the Nabto with FreeRTOS code.

Things to try if you are not able to connect to the device when it is running.

Ping
Try pinging the configured IP address. If ping replies are received then it is likely the problem is not related to the network configuration.

Wired Vs Wireless network interfaces
Using a wired network is preferred rather than a wireless network. If that is not possible try connecting to (or pinging) the project from a different computer on the same network.

Firewall
Often in corporate environments, they enforces a policy on windows machines that prevents a uni cast response to a broadcast request. The following URL provides information on how to check if uni cast responses are allowed on your machine: http://technet.microsoft.com/enus/library/cc742429.aspx

Try temporarily disabling any firewall or other network filtering software during your testing.

Hubs and Switches
Intelligent hubs and switches can shield network nodes from traffic. Try connecting through a dumb hub.

 

Jorjin Ameba Arduino Library

Today we will have a look at the Arduino-like Jorjin Ameba board with built in support for WiFi and NFC. Taking the pricetag of 25$ into account makes this an easy choice for your IoT projects!

For this post I created a Jorjin Ameba library which can be imported directly into the Arduino IDE seamlessly, thus making the classic blink example a breeze.

We will walk through the following steps

  • Specs of jorjin board and “special features”
  • How to run the example
  • Demo

The Jorjin board

board

Overview of the Jorjin Ameba WiFi board.

The Jorjin Ameba WiFi board has built-in WiFi and  NFC thus making it very much prepared for IoT.

As can be seen from the above image, the Ameba board has an Arduino-like form factor with a similar pinout. For the simple LED blink example, we will be using a digital pin.

Getting the example up and running

To run the example we need to install the Ameba board libraries and the Ameba specific uNabto files. We also need a device name and key, both of which can be created at developer.nabto.com

Furthermore an LED (and appropriate resistor) is needed.

Step 1: Download General Ameba Libraries install

Follow the steps laid out here to install the general Ameba libraries into the Arduino IDE OR read it right here:

Open up the Arduino IDE. Click File -> Preferences and then copy this

https://github.com/Ameba8195/Arduino/raw/master/release/package_realtek.com_ameba_index.json

into the Additional Boards Manager URLs input field. Click OK

Now click Tools –> Board: -> Boards Manager

Here we search for Ameba and click Install

The Jorjin Ameba board Arduino libraries are now installed

Step 2: uNabto libraries install

There are two ways of getting the uNabto libraries.

Using git

git clone --recursive https://github.com/nabto/unabto-jorjin-sdk

then change directory to the unabto-jorjin-sdk folder and run

bash Make.sh

OR download the release zip file unabto-jorjin-sdk.zip

No matter which way, we can now add the library to the Arduino IDE via Sketch -> Include Library -> Add .ZIP Library... and then browse to and add the unabto-jorjin-sdk folder that was just downloaded.

Run the example

We can now open the LightSwitch.ino example by going to File -> Examples -> Nabto-Ameba -> LightSwitch

Here we need to enter the SSID and password of the wireless network we want to attach to. Furthermore we need to input the device name and key we created at developer.nabto.com

Finally we need to remember to wire the LED and resistor up like so (try switching pins around if it does not work at first)

jorjin_wiring

Wiring of the LED. Image taken from the Ameba documentaion, available from here (signing up is required)

When the example is compiled and uploaded to the device we simply need to press the reset button (see the above image). The board should now reset, connect to the specified wifi network and run uNabto.

We can now control the LED by going to devicename.demo.nab.to in the Nabto client of your choice. (devicename is the unique name created at portal.nabto.com). Simply use the guest account for this demo. We can now control the LED by moving the slider.

Demo

As always, the full code can be found at Github. If you feel like experimenting with the many uses of the Nabto framework, please visit our developer portal where you can manage up to 10 devices for free !

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.

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

This post is outdated. Please have a look at the updated version incorporating our new AppMyProduct platform.

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