Hacking Mynewt in Eclipse

Do you want to hack Apache Mynewt but do not know which IDE to use? Here is a short tutorial on how to configure Eclipse for working with Mynewt.

Using this setup you will have nicely working code indexer, integrated debugger and some other tools. Actually you will probably not need to use console anymore except for project configuration 🙂

Before you start, make sure you have Mynewt environment set properly and Eclipse CDT installed. This tutorial was created with Eclipse 4.21 (2021-09), but previous versions should work as well.

And final important note: it was tested on develop branch only.

Create project

First, you need to create new project in Eclipse:

Now you should see your project in Project Explorer window.

I recommend to change default build configuration name to one matching target name in your Newt project. This makes working with multiple targets easier later in the process, but you can skip this if you e.g. work with only one target. In this case remember to adjust configuration accordingly (I mention this in the description where applicable). Build configurations name can be changed by going to Project → Propertes → C/C++ Build → Manage Configurations...:

Build and index

Now we can setup new project to build and index properly:

${ConfigName} will be replaced with the name of current build configuration so this will only work if you named build configurations as I suggested at the beginning. If you decided not to do this, simply replace ${ConfigName} with any valid target of your Newt project.

The -l debug option in the build command is important as it makes newt print debug logs during build process. These logs also include a complete command line for each command invoked. This is then used by build output parser to figure out build options for each file in the project so indexer can index file properly. The build output parser needs to be configured before it can understand debug logs from Newt:

This step is necessary only if you decided to use multiple targets, as it fixes some issues with indexing when more then one target exist in your project:

Finally, you may also tune some indexer settings to make sure only files included in the current build are indexed:

And that's all. You can build and clean (Project → Clean...) your project as any other project in Eclipse. If everything was configured properly, you should see that .c files included in the build have custom settings captured from the build output parser and this means project should be nicely indexed:

No more errors due to unresolved stuff in code 🙂

Debug

Once you can write and build your code, it is time to debug. Start with creating new debug configuration for your project:

Before starting debug session in Eclipse you need to run GDB Server for selected target in shell console. This can be done in two ways:

Note the -n parameter in both cases – this will stop Newt from running GDB in shell console.

Click Debug now and you will be switched to debug session. You may now want to reset your device to start debugging from beginning. To do this use Debugger Console window and execute interrupt, monitor reset and then continue (or just suspend from UI, execute monitor reset and then continue from UI).

To make things even easier, it is possible to launch both newt run and debug session with a single click in Eclipse – this way you do not need to switch to shell console every time you want to start debugging. Start by creating launcher for newt run:

Now you just need to define launch group which runs both newt run external tool and debug configuration:

Your final setup should look as on image below:

Now just use this launch group instead of plain debug configuration and you will not need to open shell when debugging Mynewt anymore 🙂

How to use Mynewt's blehci with drag and drop bootloader on nRF52840-Donlge

Mynewt has a possibility of using drag and drop bootloader, which allows to flash images to the device with simply copying them via USB. This post shows how to configure blehci application with drag and drop flashing feature for nRF52840-Dongle.

Bootloader target configuration

Start with creating new bootloader target in your Newt project:

~/dev/mynewt$ newt target create nordic_pca10059_boot

Target targets/nordic_pca10059_boot successfully created

~/dev/mynewt$ newt target set nordic_pca10059_boot bsp=@apache-mynewt-core/hw/bsp/nordic_pca10059

Target targets/nordic_pca10059_boot successfully set target.bsp to @apache-mynewt-core/hw/bsp/nordic_pca10059

~/dev/mynewt$ newt target set nordic_pca10059_boot app=@mcuboot/boot/mynewt

Target targets/nordic_pca10059_boot successfully set target.app to @mcuboot/boot/mynewt

~/dev/mynewt$ newt target set nordic_pca10059_boot build_profile=optimized

Target targets/nordic_pca10059_boot successfully set target.build_profile to optimized

This is going to be target for drag and drop bootloader for nRF52840-Dongle. Now you have to configure your target. To do so go into it's directory. In this example target location is:

~/dev/mynewt/targets/nordic_pca10059-boot

You'll have to modify pkg.yml and syscfg.yml files.

pkg.yml should contain:

pkg.name: targets/nordic_pca10059-boot
pkg.type: target
pkg.description: 
pkg.author: 
pkg.homepage: 

pkg.deps:
    - "@apache-mynewt-core/hw/usb/tinyusb/msc_fat_view"

Drag and drop bootloader uses tinyusb package, so it has to be added to dependencies.

In syscfg.yml file you should configure settings related to USB descriptor and msc_fat_view package:

syscfg.vals:
    #Use standard USB descriptor generated by Mynewt
    USBD_STD_DESCRIPTORS: 1
    #Set usb descriptor values
    USBD_VID: 0xC0CA
    USBD_PID: 0xC01B
    USBD_VENDOR_STRING: '"Codecoup"'
    USBD_PRODUCT_STRING: '"Mynewt dongle"'

    #GPIO pin to check during boot for DFU activation.
    MSC_FAT_BOOT_PIN: BUTTON_1
    #GPIO pin value required for DFU activation.
    MSC_FAT_BOOT_PIN_VALUE: 0
    #Set to 1 if boot pin needs internal pull-up resistor.
    #Set to 2 if boot pin needs internal pull-down resistor.
    MSC_FAT_BOOT_PIN_PULL: 1
    #FAT volume name.
    MSC_FAT_VIEW_VOLUME_NAME: '"MYNEWT_BOOT"'
    #Add 'MYNEWT.HTM' file that will redirect to mynewt web page.
    MSC_FAT_VIEW_MYNEWT_SHORTCUT: 1
    #Add git hashes into README.TXT.
    MSC_FAT_VIEW_DEFAULT_README_INCLUDE_HASHES: 1
    #Simulated disk size in kB (Only FAT16 is supported!).
    MSC_FAT_VIEW_DISK_SIZE: 4000
    #Simulated disk sectors per cluster (Only FAT16 is supported!).
    MSC_FAT_VIEW_SECTORS_PER_CLUSTER: 1
    #Add 'Drop image here' file.
    MSC_FAT_VIEW_DROP_IMAGE_HERE: 1
    #Show image from slot 0 as a file 'FIRMWARE.IMG'.
    MSC_FAT_VIEW_SLOT0_IMAGE: 1
    #Enable DFU.
    BOOT_PREBOOT: 1

Editing project.yml

To make drag and drop bootloader work, you'll have to change two things in your project.yml file. You can find this file in your main Newt project directory (in this tutorial it is "~/dev/mynewt/").

First you'll have to add tinyusb repository to your project:

repository.apache-mynewt-core:
    type: github
    vers: 0-dev
    user: apache
    repo: mynewt-core

repository.tinyusb:
    type: github
    vers: 0.0.0
    user: hathach
    repo: tinyusb

Second step is to change apache-mynewt-core repository version to master branch:

repository.apache-mynewt-core:
    type: github
    vers: 0-dev
    user: apache
    repo: mynewt-core

This is needed, because the changes in source code required for drag and drop bootloader to work are currently only on the master branch. This will be changed in the future.

After applying this two changes you can run newt upgrade command. It might take a while to download quite big tinyusb repository.

Now you can build bootloader with newt build nordic_pca10059_boot command.

Flashing and working with drag and drop bootloader

To flash new bootloader to nRF52840-Dongle you have to connect it to a programmer via Tag-Connect cable.

RF52840-Dongle connected to the programmer via Tag-Connect cable. Jumper wires are connected to the J-Link programmer.

After connecting the board to the programmer you can load bootloader with newt load nordic_pca10059_boot command.

When loading bootloader is finished it will be safe to unplug the dongle from your computer. Now if you want to flash new app, using drag and drop functionality you just have keep the user button pressed while plugging the device into your computer's USB port. Then the device should be recognized as MSD. Now you can copy and paste the application image you want to flash on the device. After copying it the device will be automatically rebooted and new app will be running on it. If you set the appropriate config in syscfg.yml (MSC_FAT_VIEW_SLOT0_IMAGE), you will see a currently loaded image when you plug in the device with user button pressed. Thanks to this you can backup your previous image, before replacing it with another one.

Mynewt's blehci application configuration

Create new target for blehci app:

~/dev/mynewt$ newt target set blehci bsp=@apache-mynewt-core/hw/bsp/nordic_pca10059


Target targets/blehci successfully set target.bsp to @apache-mynewt-core/hw/bsp/nordic_pca10059


~/dev/mynewt$ newt target set blehci app=@apache-mynewt-nimble/apps/blehci


Target targets/blehci successfully set target.app to @apache-mynewt-nimble/apps/blehci


~/dev/mynewt$ newt target set blehci build_profile=optimized


Target targets/blehci successfully set target.build_profile to optimized

Application target also has to be configured. Go into it's directory (in this tutorial it's "~/dev/mynewt/targets/blehci") and edit syscfg.yml and pkg.yml files.

In pkg.yml file you just have to add tinyusb package dependencies:

pkg.deps:
- "@apache-mynewt-core/hw/usb/tinyusb"
- "@apache-mynewt-core/hw/usb/tinyusb/std_descriptors"

File syscfg.yml can be configured like this:

syscfg.vals:
    USBD_VID: 0xC0CA
    USBD_PID: 0xC01A
    USBD_VENDOR_STRING: '"Codecoup"'
    USBD_PRODUCT_STRING: '"NimBLE 1.5"'
    USBD_BTH_DESCRIPTOR_STRING: '"NimBLE 1.5"'
    USBD_BTH: 1

    BLE_TRANSPORT_HS: usb

    #Enable reset button
    GPIO_AS_PIN_RESET: 1

    CONSOLE_MODE: stub

    #Fake dual mode to make BLE-only device work on Windows
    BLE_LL_HBD_FAKE_DUAL_MODE: 0

syscfg.vals.BLE_LL_HBD_FAKE_DUAL_MODE:
    BLE_TRANSPORT_EVT_SIZE: 257
    BLE_LL_PUBLIC_DEV_ADDR: 0xC0CAC01A1983
    USBD_PRODUCT_STRING: '"NimBLE 1.5 (Fake dual)"'
    USBD_BTH_DESCRIPTOR_STRING: '"NimBLE 1.5 (Fake dual)"'

MS Windows requires connected Bluetooth device to support Bluetooth Classic, so you will have to configure fake dual mode if you are using Windows. Configs below the line syscfg.vals.BLE_LL_HBD_FAKE_DUAL_MODE: will only be included if BLE_LL_HBD_FAKE_DUAL_MODE is set to 1. These are additional configs required for the fake dual mode.

When everything is configured you can finally build your blehci app image with newt create-image blehci 1.0.0 command. Now you can connect nRF52-Dongle to your USB port while keeping user button pressed. When the device will be recognized as MSD, you can simply drag and drop your application image to the device. After doing so the device should no longer be seen as MSD, but should work as Bluetooth dongle from now on. However if you want to flash new image on the board you can do it with unplugging it and plugging it again with the user button pressed. If the user button won't be pressed while plugging in the device, it should be detected as Bluetooth controller dongle.

Support for btmon in Mynewt

Btmon is very useful tool for HCI messaging monitoring on Linux systems. It helps to understand how Bluetooth host talks to controller, debug issues, implement new features in the host etc. When we have started work with Mynewt we knew that we need tool like this. Of course Mynewt has a way to print all the HCI logs in hex, but decoding it on fly is not the best thing to do. So here it is, Mynewt can be configured in the way that btmon can be used. Detailed information you can find here. Below we show an example how to use it.

For the demo purpose we will use btshell application running on nRF52840 PDK. We will configure it to most convenient option, which is: keep bi-directional console on UART and configure Mynewt to send HCI over RTT to btmon. Let’s start from creating target:

newt target create btshell
newt target set btshell app=@apache-mynewt-core/apps/btshell bsp=@apache-mynewt-core/hw/bsp/nordic_pca10056 build_profile=optimized

We should not forget about boot image:

newt target create nrf52_boot 
newt target set nrf52_boot app=@apache-mynewt-core/apps/boot bsp=@apache-mynewt-core/hw/bsp/nordic_pca10056 build_profile=optimized

Now we need to add additional syscfg.yml file into target/btshell/ folder in order to enable HCI over RTT. That file should look like this:

cat targets/btshell/syscfg.yml 
syscfg.vals:
    BLE_MONITOR_RTT: 1

Once configuration is done, let’s build btshell and flash it onto nRF52840pdk

newt build nrf52_boot
newt load nrf52_boot
newt build btshell
newt create-image btshell 1
newt load btshell

Board is ready to play with. Shell is available under /dev/ttyACMx . Test it by typing help

Now we came to most interesting part, HCI tracing. Since btmon can only read data from tty, we need small tool to redirect RTT data to PTY. It is called rtt2pty and is ready for download from our GitHub here. It is delivered as an Eclipse project, so just import it, build and run. Here is how the outcome should look like:

> ./rtt2pty -b btmonitor
Connected to:
  J-Link OB-SAM3U128-V2-NordicSemi compiled Jun  9 2017 14:57:23
  S/N: 683958770
Searching for RTT control block...
Found 3 up-buffers.
Using buffer #1 (size=256)
PTY name is /dev/pts/3

Run btmon:

btmon --tty=/dev/pts/3

And that is it. Now for test let us try to scan for devices around with btshell (don’t forget to set address of device for btshell) e.g.

btshell> set addr=11:11:11:11:11:11
btshell> scan

Happy tracing!

Łukasz Rymanowski

Automated Bluetooth testing and qualification of Mynewt NimBLE with auto-pts

We are happy to announce that auto-pts now supports Mynewt NimBLE stack!

To test and qualify your Bluetooth product you have to use a tool called Profile Tuning Suite (PTS) from Bluetooth SIG organization. It is a Windows program that you can use to manually run test cases using a graphical user interface. The process of testing manually requires a tester to operate both the device and the PTS program. This is a tedious job and can take one man-month. We described this process in one of our blog posts before. There is a tool that can speed that up to a few hours by fully automating the testing process.

auto-pts is a Bluetooth PTS automation framework that coordinates test execution between PTS and the Implementation Under Test (IUT). It automates over 400 test cases from GAP, GATT, L2CAP, SM, and MESH profiles. Auto-pts supports already BlueZ and Zephyr and it is supporting Mynewt NimBLE now!

On the IUT side, you will need to use the bttester app. It communicates with the auto-pts via UART. Bluetooth Testing Protocol (BTP) is used as a communication protocol. You can find the specification in the auto-pts repository. Check out the README on how to configure and run the auto-pts tool.

Happy testing! 🙂

Developing Apache Mynewt in Clion with quick and accurate indexing

It is not always possible to use a modern IDE for embedded software development. Sometimes your project uses a custom build system or a workflow that is hard to integrate with your favorite IDE. Apache Mynewt project has a modular design with features split into packages, dependencies and configuration files. It simplifies the architecture of the whole system and gives a lot of power to the user but also complicates the build process. To manage all of that a Newt tool was created. It is a smart build and package management system, that can handle multiple source repositories, decide what to include in a build and manage dependencies between components of the system. And one of it’s newer features is an integration with CMake.

Clion is a powerful cross-platform IDE for C and C++. It is easy to use, very responsive and supports tons of integrations. And it comes with vi emulation too! Most importantly, it uses CMake as a build system.

So now you can use Clion to develop Apache Mynewt applications!

We already described in this blog how to configure and use Eclipse with Mynewt. It is possible but requires some configuration. On the other hand, working on Mynewt in Clion requires almost no configuration.

How to work on Mynewt project in Clion

newt target cmake <target> command generates a CMakeLists.txt file for a specific target inside project root directory. This file contains all the CMake configuration options and a list of files to include in a build. You can then open the project inside Clion and the IDE should load the file correctly. Indexing in Clion is lightning fast! It takes just a few seconds and you are ready to start working on your project. You almost don’t notice it. If you need to change the target you are using, just run the command again with the new target and Newt will overwrite the CMakeLists.txt file. Clion will detect a change in this file and reindex your project. Just like that!

Indexing of a Mynewt project in Eclipse takes over a minute! So this is a huge improvement to your workflow. Another very important factor is the quality of indexing. Clion recognizes all the definitions and detects which files are included in the build and even which parts of the file are excluded. So you can jump to definitions, search by file or by symbol, refactor code, find usage and much more.

Building your project in Clion also works but you will still need to build and flash using Newt tool since both build processes are not yet equivalent.

Debugging Mynewt in Clion

You can also debug Mynewt in Clion but it requires a bit more configuration. You will need to create a GDB Remote Debug configuration inside Run/Debug Configurations window. Set the following fields:

Unfortunately, you will need to create a separate configuration for each target you want to debug.

Inside terminal run newt debug <target> -n – this will run gdb in server mode and will wait for the client to connect. Then in Clion select your debug configuration and click Debug button. That’s it!

Now you can develop your Apache Mynewt project inside a modern, powerful IDE with fast and accurate indexing.

How to do software update of a Bluetooth Mesh device running Apache Mynewt

As you might know, there is not yet specified way for a software update over the Bluetooth Mesh. This is high demand feature and for sure it will come. However, if this feature is needed just right now and your product uses Apache Mynewt, there is a way to mitigate the issue.

Apache Mynewt supports Bluetooth 5 features and in particular the one called Advertising Extensions. It gives a way to support multi advertising and this gives an idea to have advertising instance dedicated to Mesh operations and in the same time an instance which will allow to connect for the software update purpose.

This tutorial will guide you through configuration and simple update of firmware over BLE on Mynewt of Mesh node supporting Generic On/Off model.

This example scenario use:

Configuration for targets

Device A system configuration modification:

Device B system configuration modification:

Additional packages requirement by Device B

Since Device B will be updated via BLE it requires some additional packages.

Packages required:

Building images

Both devices running Mynewt have to be flashed with bootloader first as presented below.

Example configuration:

$ newt target show nrf52840pdk_boot
targets/nrf52840pdk_boot
    app=@apache-mynewt-core/apps/boot
    bsp=@apache-mynewt-core/hw/bsp/nordic_pca10056
    build_profile=optimized

Then devices have to be flashed with target application.

Example configuration (Dev B):

$ newt target show nrf52840pdk_btshell
targets/nrf52840pdk_btshell
    app=@apache-mynewt-core/apps/btshell
    bsp=@apache-mynewt-core/hw/bsp/nordic_pca10056
    build_profile=debug
    syscfg=BLE_EXT_ADV=1:BLE_MESH=1:BLE_MESH_CFG_CLI=1:BLE_MESH_GATT_PROXY=0:BLE_MESH_SHELL=1:BLE_MESH_SHELL_MODELS=1:BLE_MONITOR_RTT=1:BLE_MONITOR_RTT_BUFFER_SIZE=2048:BLE_MULTI_ADV_INSTANCES=2:BLE_PUBLIC_DEV_ADDR=((uint8_t[6]){0x02, 0x1b, 0xde, 0xc0, 0xde,0xc0}):BLE_SM=1:BLE_SM_SC=1:IMGMGR_COREDUMP=1:NEWTMGR_BLE_HOST=1:BLE_MESH_SHELL_MODELS:1

Build and flash devices example. Start with bootloader:

$ newt clean nrf52840pdk_boot
$ newt build nrf52840pdk_boot
$ newt load nrf52840pdk_boot
$ newt clean nrf52840pdk_btshell

Then application (use 1.0.1 as version for second image of Dev B):

$ newt build nrf52840pdk_btshell
$ newt create-image nrf52840pdk_btshell 1.0.0
$ newt load nrf52840pdk_btshell

Afterwards, devices are ready to interact via shell.

Default serial setup for communication with boards

Configure simple Mesh network

As soon as devices are set up and terminal is connected, it’s time to configure mesh and make some data traffic.
Mynewt Mesh provides simple configuration client over shell which will be used to configure Generic On/Off client/server in our scenario.

Initialize mesh and application in mesh module

First we need to provision devices. Since Apache Mynewt does not support provisioner yet, let us use hardcored credentials. Run below commands on both devices changing <addr> to 0x0001 on Device A and 0x0002 on Device B.

btshell> select mesh
mesh> init
mesh> provision 0 <addr>

Configure Device A as a Client and Device B as a Server. Configuration will be done from Device A.

mesh> app-key-add 0 0 1
mesh> mod-app-bind 1 0 0x1001

Now we are ready to configure Device B to be a server. For this set destination address of Device B on Device A, then continue configuration on Device A of test applications.

mesh> dst 0x0002
mesh> app-key-add 0 0 1
mesh> mod-app-bind 2 0 0x1000

To verify mesh configuration is successfully, send some generic model operations e.g. set on/off from Device A

mesh> gen-onoff-set 5

If changing of value was successfully you will get indication on Device B.

Light state: onoff=5 lvl=0x0000

Prepare stack for firmware update over air of Device B

To update firmware over air, Device B has to configure advertising instance first. Pay attention on device name, since it is required by Newtmgr to connect.

Example setting:

mesh> select btshell
btshell> advertise-configure connectable=1 scannable=1 legacy=1 own_addr_type=random
btshell> advertise-set-adv-data name=deviceB
btshell> advertise-set-addr addr=ff:de:cb:11:22:33
btshell> security-set-data our_key_dist=7
btshell> security-set-data their_key_dist=7
btshell> advertise-start

PC (Newtmgr)

Configure connection and upload image to slot 2 on device via Bluetooth:
Note: To access Bluetooth controller on host, newtmgr may require to be run as root thus you may need to run all commands via sudo.

$ newtmgr conn add myble type=ble connstring="peer_name=deviceB"
$ newtmgr -c myble image upload deviceB2.img

Upload progress will be indicated with progress bar and current upload data to total data indicator. Successful upload of image will be indicated with “done” information on Newtmgr.

After successful upload a test of image is required. By test it means that image will be swapped to slot 0 after reboot and this image will be run. If something goes wrong with tested image, system will be rebooted automatically (program asserts, corrupted image). The Mynewt has also feature which backs up in case of wrong firmware – not confirmed image will be swapped back to slot 1 and previous image will be run from slot 0 after any system reboot.

Current status of device slots can be checked with command:

$ newtmgr -c myble image list
Images:
 slot=0
    version: 1.0.0
    bootable: true
    flags: active confirmed
    hash: a8e9fbba9c690da87faf714496e55453967fcfe05bb10f9863c983a5b4788cd0
 slot=1
    version: 1.0.1
    bootable: true
    flags:
    hash: 31c58b0a207ecf96d62bf6ea8acc9073375d92a8b0cf76fa29cb8f48c29b5250

Select image for testing after reboot of system

$ newtmgr -c myble image test 31c58b0a207ecf96d62bf6ea8acc9073375d92a8b0cf76fa29cb8f48c29b5250

And image will be marked with pending flag

$ newtmgr -c myble image list
Images:
 slot=0
    version: 1.0.0
    bootable: true
    flags: active confirmed
    hash: a8e9fbba9c690da87faf714496e55453967fcfe05bb10f9863c983a5b4788cd0
 slot=1
    version: 1.0.1
    bootable: true
    flags: pending
    hash: 31c58b0a207ecf96d62bf6ea8acc9073375d92a8b0cf76fa29cb8f48c29b5250

System can be easily rebooted with Newtmgr using reset command

newtmgr -c myble reset

After system reboot a new image should be run from slot 0 with active flag set

$ newtmgr -c myble image list
Images:
 slot=0
    version: 1.0.1
    bootable: true
    flags: active
    hash: 31c58b0a207ecf96d62bf6ea8acc9073375d92a8b0cf76fa29cb8f48c29b5250
 slot=1
    version: 1.0.0
    bootable: true
    flags: confirmed
    hash: a8e9fbba9c690da87faf714496e55453967fcfe05bb10f9863c983a5b4788cd0

Image can be confirmed to be permanently set as default running image after reboot

$ newtmgr -c myble image confirm 31c58b0a207ecf96d62bf6ea8acc9073375d92a8b0cf76fa29cb8f48c29b5250
$ newtmgr -c myble image list
Images:
 slot=0
    version: 1.0.1
    bootable: true
    flags: active confirmed
    hash: 31c58b0a207ecf96d62bf6ea8acc9073375d92a8b0cf76fa29cb8f48c29b5250
 slot=1
    version: 1.0.0
    bootable: true
    flags:
    hash: a8e9fbba9c690da87faf714496e55453967fcfe05bb10f9863c983a5b4788cd0

Not confirmed but active image after reboot will be swapped back to slot 1 and confirmed image will be default again.

Swap back to confirmed image prevents system from being deadlocked on bad image.

Uploaded image verification

btshell> select mesh
mesh> init
mesh> provision 0 <addr> (suggested address on A = 0x0001, B = 0x0002)
mesh> dst 0x0002

Final mesh verification

To check if everything goes right it’s recommended to do verification of  some data exchange. Data exchange operation and mesh setup was previously described in “Initialize mesh and application in mesh module” part.

Grzegorz Kołodziejczyk

Bluetooth Mesh on Apache Mynewt

Bluetooth Mesh implementation is the latest addition to Apache Mynewt Nimble stack. This tutorial will should you how to use it. If you want to learn more about Bluetooth Mesh visit this site.

This tutorial will provide you with a simple yet fully functional mesh structure.

For this demo, we will use Bluetooth Mesh by Silicon Labs application for Android, which will act as a provisioner.  You can download it for Android using Google Play. Furthermore, we need to use the blemesh application running on multiple nRF52840 PDK devices acting as nodes.

Bluetooth Mesh provides two bearers in form of GATT and advertising. Unfortunately, Silicon Labs application only supports PB-GATT (GATT Provisioning Bearer), so we have to enable PB-GATT for all nodes – this can be done by setting BLE_MESH_PB_GATT configuration option. One of our targets should also contain GATT Proxy Service so it can relay messages between application and other nodes which do not use GATT bearer. This is done by setting BLE_MESH_GATT_PROXY flag.

Building targets

Let’s start by creating target for a proxy device:

$ newt target create blemesh
$ newt target set blemesh app=@apache-mynewt-core/apps/blemesh
$ newt target set blemesh bsp=@apache-mynewt-core/hw/bsp/nordic_pca10056
$ newt target set blemesh build_profile=optimized
$ newt target set blemesh syscfg=BLE_MESH_PB_GATT=1: \
> BLE_MESH_DEV_UUID='(uint8_t[16]){0x22, 0x20, 0}'

Note that we do not set device public address since Bluetooth Mesh implementation uses non-resolvable private address (NRPA) as they are not really important in mesh. What is important though is a device UUID as set above.

We also need target for bootloader:

$ newt target create nrf52840_boot
$ newt target set nrf52840_boot app=@apache-mynewt-core/apps/boot
$ newt target set nrf52840_boot bsp=@apache-mynewt-core/hw/bsp/nordic_pca10056
$ newt target set nrf52840_boot build_profile=optimized

Now you can build and flash bootloader and application onto device:

$ newt build nrf52840_boot
$ newt load nrf52840_boot
$ newt build blemesh
$ newt create-image blemesh 0
$ newt load blemesh

Afterwards, our devices is all set and ready for action. But one device is not enough to form an interesting mesh network, therefore we will prepare more.  This process is pretty similar to the previous one, so you can just amend your previous target or create another one. The only significant difference is that each other device should get different device UUID. Also they should only have GATT Provisioning Service enabled (i.e. no GATT Proxy Service):

$ newt target set blemesh syscfg=BLE_MESH_PB_GATT=1: \
> BLE_MESH_DEV_UUID='(uint8_t[16]){0x22, 0x21, 0}'

Now you can flash bootloader and application onto other device(s).

Configuring Bluetooth Mesh Silicon Labs application

As soon as your devices are ready, it is time to create your own mesh network using the Android app. We’ve recorded a video that should help you with the whole process:

Note that you also need some serial terminal program to monitor the output of every device, as they will show the authorization code that is required to provision your device.

Then, if you follow the rest of the instructions from the video, everything should work just fine.

Happy meshing!

Szymon Czapracki

Interoperability testing is important!

As we all know, each Bluetooth product shall work according to Bluetooth specification. It is fairly big specification, and that’s why before releasing your Bluetooth product it is very important that it can talk to other Bluetooth devices. Basically, we should check if we understand specification in the same way as others. That is why UnPlugFest (UPF) is organized 3 times per year by Bluetooth SIG, so developers can test their solutions with other products to verify they work together. Codecoup understands that and encourages its customers to be there. Speaking of which, we just came back from UPF56 in Atlanta where we had two teams testing two different IoT platforms.

Łukasz Rymanowski

Bluetooth device qualification

Whenever you create a Bluetooth product you have to go through a process of qualification in order to get Bluetooth SIG stamp 🙂 This process is usually painful for developers and testers, especially when you are doing it for the first time. Fortunately, some of the Open Source stacks provide instructions on how to do this, which makes things bit easier. In this post, we will show you how to start a Bluetooth device qualification testing using an nRF52 board running Mynewt OS.

Mynewt is a Real-time operating system build with IoT in mind and provides open source networking stack including Bluetooth Low Energy. More details can be found on their website.

Mynewt allows to develop and run apps that perform specific tasks. bletiny is one of such applications. It allows controlling the Bluetooth stack from the command line. The application includes a simple shell functionality and allows e.g. start advertising or discovery.

A tutorial describing the necessary steps to run the application is available on their documentation website. To communicate with the application we will need to set up a serial connection. There is a tutorial for that too. To check if everything works properly you can run b help command, which lists all available commands in the bletiny app.

[12:08:39:333] b help
[12:08:39:336]
[12:08:39:336] 831277:Available commands:
[12:08:39:345] 831277: adv
[12:08:39:345] 831278: conn
[12:08:39:345] 831278: chrup
[12:08:39:345] 831278: datalen
[12:08:39:355] 831279: disc
[12:08:39:355] 831279: find
[12:08:39:355] 831280: help
[12:08:39:364] 831280: l2cap
[12:08:39:364] 831280: mtu
[12:08:39:364] 831281: passkey
[12:08:39:374] 831281: read
[12:08:39:374] 831281: rssi
[12:08:39:374] 831282: scan
[12:08:39:374] 831282: show
[12:08:39:374] 831282: sec
[12:08:39:382] 831283: set
[12:08:39:382] 831283: store
[12:08:39:390] 831283: term
[12:08:39:390] 831284: update
[12:08:39:390] 831284: tx
[12:08:39:400] 831285: wl
[12:08:39:400] 831285: write
[12:08:39:400] 831285: svcchg

The instructions for the tests can be found in the net/nimble/host/pts directory in the apache-mynewt-core project tree.

tree net/nimble/host/pts/

net/nimble/host/pts/
├── pts-gap.txt
├── pts-gatt.txt
├── pts-l2cap.txt
├── pts-sm.txt
├── README.txt
└── tpg
    ├── 90359-20161220-172100175.tpg
    └── 90359-20161220-172113981.pts

1 directory, 7 files

The contents of the directory are described in the README.txt file:

This folder contains qualification tests results against BT SIG Profile Test
Suite.

pts-FOO.txt files contain result for specific profiles or protocols. This
includes PTS version, test date, enabled tests, results etc.

In addition to tests results 'tpg' folder contains Test Plan Generator
configuration files that can be imported by PTS for tests configuration.

Fragment of the test instructions file:

PTS test results for GAP

PTS version: 7.0
Tested: 10-Jan-2017

Results:
PASS test passed
FAIL test failed
INC test is inconclusive
N/A test is disabled due to PICS setup

-------------------------------------------------------------------------------
Test Name Result Notes
-------------------------------------------------------------------------------
TC_MOD_NDIS_BV_01_C N/A
TC_MOD_LDIS_BV_01_C N/A
TC_MOD_LDIS_BV_02_C N/A
TC_MOD_LDIS_BV_03_C N/A
TC_MOD_GDIS_BV_01_C N/A
TC_MOD_GDIS_BV_02_C N/A
TC_MOD_NCON_BV_01_C N/A
TC_MOD_CON_BV_01_C N/A
-------------------------------------------------------------------------------

TC_BROB_BCST_BV_01_C PASS b adv conn=non
TC_BROB_BCST_BV_02_C PASS b adv conn=non
TC_BROB_BCST_BV_03_C PASS b set irk= e.g: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:11

........

This file contains a list of test descriptions. Each description consists of a test name, it’s result and list of instructions needed to execute the test.

After configuring the device, we can move on to setting up the PTS.

Prerequisites

Setting-up PTS environment

Install PTS drivers for the dongle

In device manager select the PTS dongle device, open Properties and update driver. Browse for driver in C:\Program Files (x86)\Bluetooth SIG\Bluetooth PTS\PTS Driver\win32 and select csrbc.sys. If you are using a 64-bit system, then change win32 to win64.

Create new workspace and search for device

Launch PTS and select Create new workspace. Set your device in advertising mode and search for it in PTS. It should appear in the device list. Select it, so that the device address field is filled and move to the next step.

Import Test Plan

Fill in the name and location of the workspace and import the Test Plan. The Test Plan can be found in the net/nimble/host/pts directory in the apache-mynewt-core project tree.

Select test suite(s)

Select the Test Suites you are interested in and move them to the list on the right.

Use Bluetooth Protocol Viewer

It’s a great debugging tool. It allows you to see exactly what was transmitted and received by the PTS in great detail. Each frame is formatted into a very readable tree-like structure, and the frames are categorized by the protocol.

Important definitions

Before we move on to the testing itself, some important definitions that are used in PTS:

For more definitions read Test Strategy and Terminology Overview document.

Example #1

As a fist example we will run test TC_BROB_BCST_BV_01_C. In the PTS right-click on the test in Workspace Tool Window and select Run from context menu. PTS starts the test and displays an information window saying, that a user action is required:

Following the instructions, we execute b adv conn=non in the bletiny app which starts the advertising procedure in non-connectable mode. Here is the output of the test execution in the PTS:

Test case : TC_BROB_BCST_BV_01_C started
- MTC: Successfully received HCI_LE_CLEAR_WHITE_LIST_COMPLETE_EVENT.
- MTC: Successfully received HCI_LE_ADD_DEVICE_TO_WHITE_LIST_COMPLETE_EVENT.
- MTC: Successfully received HCI_LE_SET_SCAN_PARAMETERS_COMPLETE_EVENT.
- MTC: Successfully received HCI_LE_SET_SCAN_ENABLE_COMPLETE_EVENT.
- MTC: Receive Advertising report successfully.
- MTC: Flags type is not present in any scan response data received.
- MTC: Successfully received HCI_LE_SET_SCAN_ENABLE_COMPLETE_EVENT.
- CM_EXIT
- CM_EXIT
- CM_EXIT
- CM_EXIT
- MTC: Test case ended
-Final Verdict: PASS
TC_BROB_BCST_BV_01_C finished

Example #2

The second example will be a little more complex. We will run TC_SEC_AUT_BV_13_C test. It verifies that the IUT properly rejects the service request where there is insufficient authentication and then completes service correctly with Lower Tester as a peripheral role.

The instruction for this test is a bit longer:

TC_SEC_AUT_BV_13_C PASS Note: in PTS confirm that IUT supports GATT Server
                        b set sm_data mitm_flag=1
                        b set sm_data io_capabilities=1
                        b conn peer_addr=
                        b disc svc conn=
                        Note: in PTS enter handle for characteristics
                        value which requires authenticated
                        pairing for read
                        b passkey conn= action=3 key=123456
                        Note: enter '123456' passkey in PTS

First, we run the test and confirm in the PTS that our device supports GATT Server. We then execute b set commands that set some Security Manager related data. Then PTS requires us to send a connection request to the PTS.

We send the request by executing b conn peer_addr= command, where is the address of the PTS dongle. Then we start service discovery by executing the `b disc svc conn=`, where is the connection handle. You can list connections with the b show conn command.

After that, the PTS requires us to enter the handle for characteristic value, which requires authentication for reading. You should check the GATT Server database for this value.

PTS then requires us to enter Secure-ID (aka passkey). Before we do that, we need to set a passkey in the bletiny app, so that the device knows what passkey to use, to respond to the PTS. To do that, we type in b passkey conn= action=3 key=123456. After that, we enter the same passkey in the PTS window.

After following these steps, the test should pass. The output of the test is shown below:

Test case : TC_SEC_AUT_BV_13_C started
- MTC: Successfully received HCI_LE_CLEAR_WHITE_LIST_COMPLETE_EVENT.
- MTC: Successfully received HCI_LE_ADD_DEVICE_TO_WHITE_LIST_COMPLETE_EVENT.
- MTC: Successfully received HCI_LE_SET_ADVERTISING_PARAMETERS_COMPLETE_EVENT.
- MTC: Successfully received HCI_LE_SET_ADVERTISING_DATA_COMPLETE_EVENT.
- MTC: Successfully received HCI_LE_SET_SCAN_RESPONSE_DATA_COMPLETE_EVENT.
- MTC: Successfully received HCI_LE_SET_ADVERTISE_ENABLE_COMMAND_COMPLETE_EVENT.
- MTC: ATT connection established successfully.
- MTC: SEC_LE_PAIRING_COMPLETE_IND received successfully.
- MTC: SEC_LE_ACCESS_CFM received successfully.
- MTC: IUT respond as requested.
- MTC: SEC_LE_PAIR_REQUEST_IND received successfully.
- MTC: SEC_LE_PAIR_REQUEST_IND received successfully.
- MTC: SEC_LE_PAIRING_COMPLETE_IND received successfully.
- MTC: SEC_LE_ACCESS_CFM received successfully.
- MTC: ATT_READ_CFM received successfully.
- MTC: ATT connection disconnected successfully.
- CM_EXIT
- CM_EXIT
- CM_EXIT
- CM_EXIT
- MTC: Test case ended
-Final Verdict: PASS
TC_SEC_AUT_BV_13_C finished

References

ELCE and OpenIoT Summit Europe 2016 videos are online

Video from Szymon’s presentation on OpenIoT is available now

There were a lot of interesting sessions this year on both Embedded Linux Conference Europe and OpenIoT Summit Europe. All videos are available here.