Skip to content

OpenThread Border Router configurable through LwM2M server#

In this tutorial, we will configure OpenThread Border Router with Svetovid which is a LwM2M Client for Linux-based devices based on Anjay. With the help of Svetovid, we will be able to manage the Border Router remotely, through the LwM2M server. Within this guide, we will use the Coiote IoT Device Management platform as the server.


  • The nRF52840 DK or the nRF52840 Dongle.
  • A Linux-based machine (in this tutorial we will use Raspberry Pi 3 model B with Raspbian) with AMD64, ARMv7 or ARM64 architecture.
  • Installed Docker Engine.
  • Installed nrfjprog from Nordic Semiconductor page (for nRF52840 DK)
  • Installed nrfutil from Nordic Semiconductor page (for nRF52840 Dongle)
  • A user with access to the Coiote IoT Device Management platform.
  • For some commands you will need sudo privileges.

Flash Radio Co-Processor#

Our Border Router will run on an RCP design, which means that the core of the OpenThread stack will run on the host side and communicate via Spinel protocol with another device with a Thread radio.

Now we will build and flash image for Radio Co-Processor.

  1. Connect your nRF board to your computer. In case of nRF52840 DK you should choose MCU USB port.

  2. Clone the OpenThread repository:

        git clone --recursive

  3. Enter new directory:

        cd ot-nrf528xx

  4. Install required dependencies:


  5. Build the image:

        script/build nrf52840 USB_trans
        script/build nrf52840 USB_trans -DOT_BOOTLOADER=USB


    If you have built an image before, don't forget to remove the build directory before the next compilation:

        rm -rf build

  6. Convert the image to the .hex format:

        arm-none-eabi-objcopy -O ihex build/bin/ot-rcp build/bin/ot-rcp.hex

  7. Flash the RCP:

        nrfjprog -f nrf52  --verify --chiperase --program build/bin/ot-rcp.hex --reset
    After flashing, you must switch the physical USB port called MCU USB to the nRF USB port in order to communicate with the Border Router (although, if you would like to avoid this switching, you can disable the Mass Storage feature on the MCU USB port using J-Link Commander, so that it does not interfere with the core RCP functionalities, but then you will need to change selected transport to UART_trans in the build command). Afterward, set the nRF power source to USB by proper switch on the board.

    Install nrf5sdk-tools:

        nrfutil install nrf5sdk-tools

    Generate the RCP firmware package:

        nrfutil pkg generate --hw-version 52 --sd-req=0x00 --application build/bin/ot-rcp.hex --application-version 1 build/bin/

    Press the reset button to enter the bootloader mode, the onboard LED should start pulsing red.

    Check the dongle path:

        ls -l /dev/ttyACM*

    Flash the dongle (assuming that the dongle path is /dev/ttyACM0):

        nrfutil dfu usb-serial -pkg build/bin/ -p /dev/ttyACM0

Connecting to the LwM2M Server#

To connect to Coiote IoT Device Management platform, please register at

To connect the device:

  1. Log in to Coiote IoT DM and from the left side menu, select Device Inventory.
  2. In Device Inventory, click Add device.
  3. Select the Connect your LwM2M device directly via the Management server tile. Add via Mgmt
  4. In the Device credentials step:
    • In the Device ID field, type your board endpoint name, e.g. test_device.
    • In the Security mode section, select the PSK (Pre-Shared Key) mode.
    • In the Key identity field, type the same name as in the Endpoint name field.
    • In the Key field, type the shared secret used in the device-server authentication. Device credentials step
  5. Click the Add device button and Confirm in the confirmation pop-up.
  6. In the Connect your device step, follow the next sections to run the client and connect it to the server.

Switch to the target device#

If you haven't worked on your target device thus far, it's time to switch to it, in our case it is the Raspberry Pi 3B. Connect the RCP to the target device and continue this tutorial while working on the target device.

Downloading Docker image#

Download the newest version of svetovid-with-otbr docker image:

    docker pull avsystemcom/svetovid-with-otbr

Shell variables#

To make it easier to run the docker container, we will set a bunch of shell variables (note that the variables in the below manner are set for current shell session only, which means that when a new session is opened, the previous variables will not be restored).

At first let's check the RCP path:

    ls -l /dev/ttyACM*

And set RCP_PATH variable, for example /dev/ttyACM0:


Now we will set variables related to LwM2M server and credentials.

  1. Server URI (e.g.


  2. Endpoint name (it will also be used as an DTLS Identity, this is the Key identity field on the server):

        ENDPOINT_NAME='<your endpoint name>'

  3. Pre-shared key:

        PSK='<your PSK>'

Run docker container#

Before you run docker container you need to add ip6table_filter module to Linux Kernel:

    sudo modprobe ip6table_filter

After that you can run your image in a new container:

    docker run --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" -p 8080:80 -p 8081:8081 --dns= -it --volume $RCP_PATH:$RCP_PATH --privileged -e DNS64_ONLY=1 -e EP=$ENDPOINT_NAME -e PSK=$PSK -e SERVER_HOST=$SERVER_URI avsystemcom/svetovid-with-otbr --radio-url spinel+hdlc+uart://$RCP_PATH

Configure your Border Router through Coiote IoT DM#

After a while (about 10 minutes) you should see that your Border Router successfully connected to server. Now you can click Next, then Go to Summary, then Finish. You will see your Device Center view. Registered device

Now you can switch to Data model tab. Here you can find objects related to OpenThread Border Router:

  • /33630 - OTBR Configuration - by using this object you can configure and form a Thread network

  • /33633 - OpenThread Neighbor List - each instance of this object shall correspond to an entry in the local Thread node's neighbor table

  • /33634 - OpenThread Commissioner Joiner Table - each instance of this object shall correspond to a single entry in the commissioner's joiner table

  • /33639 - OpenThread Neighbor Networks - each instance of this object shall correspond to one of the neighboring networks

  • /33640 - OpenThread Join Existing Network - by using this object you can join existing Thread network

Form a Thread network#

Use the OTBR Configuration object to form a Thread network. Replace all default values from the Network Name, Network Extended PAN ID, PAN ID, Commissioner Credential and Network Key resources to ensure a secure Thread network. Specify the On_Mesh Prefix (e.g. fd11:22::/64), select the desired Channel and execute the Form resource to form your Thread network.

Last update: December 27, 2023