5.8 KiB
IPv6-over-BLE: Connecting Linux with RIOT using BLE
This README contains information how to establish an IPv6-over-BLE connection between Linux and RIOT (using GNRC and NimBLE).
NOTE 1: IPv6-over-BLE between RIOT and Linux is highly experimental at the moment and does suffer stability issues!
NOTE 2: Currently, Linux does not support 6LoWPAN neighbor discovery (which
RIOT uses per default with BLE), so RIOT needs to be compiled to use stateless
address auto configuration (SLAAC) -> CFLAGS=-DCONFIG_GNRC_IPV6_NIB_SLAAC=1
.
Prerequisites
You need a BLE (NimBLE) capable RIOT board (currently only nrf52
-based boards
are supported), and a Linux host with at least Bluetooth 4.0 capabilities.
Any Linux distribution should do fine, however this guide was tested with the following:
- Mint 18.3
- Kernel 4.15.0
- bluez 5.37
- [optional] radvd 2.11
Preparing the RIOT node
First, you compile and flash the examples/gnrc_networking
application to your
RIOT device. When doing this, make sure to enable SLAAC
(CFLAGS=-DCONFIG_GNRC_IPV6_NIB_SLAAC=1
), see note above.
Once the firmware is running, you can verify it by typing
ble info
This should give you some information about your device's BLE address and status information about open connections. It should look similar to the following:
Own Address: UU:VV:WW:XX:YY:ZZ -> [FE80::UUVV:WWFF:FEXX:YYZZ]
Free slots: 3/3
Advertising: no
Contexts:
[ 0] state: 0x8000 - unused
[ 1] state: 0x8000 - unused
[ 2] state: 0x8000 - unused
Once this is working, you need to tell the node to accept incoming connections and start advertising itself:
ble adv
That's it, the node can now be seen and connected to from Linux.
Establishing a connection from Linux
Preparing Linux
First of all, the Linux kernel needs to be configured to use 6lowpan over BLE. This needs to be done only once per session and consists of the following steps:
# Log in as a root user (IMPORTANT, as the following steps will not work
# using explicit `sudo` for each step...)
sudo su
# Mount debugfs file system, already the case on many distributions
mount -t debugfs none /sys/kernel/debug
# Load 6LoWPAN module
modprobe bluetooth_6lowpan
# Enable the bluetooth 6lowpan module.
echo 1 > /sys/kernel/debug/bluetooth/6lowpan_enable
Next, we should verify that our Bluetooth device is configured properly:
# Look for available HCI devices.
hciconfig
This should show us some information about the available Bluetooth devices. If no device is listed here, something is wrong...
Connecting to the RIOT node
When connecting to the RIOT device, you need to know the BLE address of the device. There are two ways to find out:
a) use ble info
or ifconfig
on the RIOT device directly and copy the address
b) use bluetoothctl
on Linux to scan for the device. Once bluetoothctl
has
started, issue scan on
to start scanning. The default name for the RIOT
device is set to RIOT-GNRC
, so you should see it pop up.
c) use hcitool lescan
on the Linux host (older tool, predecessor of
bluetoothctl
...)
Once you have the address, you simply connect Linux to RIOT using the following command:
# Put your device address here...
# Note: the 2 after the address denotes a BLE public random address, default
# used by `nimble_netif`
echo "connect UU:VV:WW:XX:YY:ZZ 2" > /sys/kernel/debug/bluetooth/6lowpan_control
That's it, you now have a IPv6 connection to your RIOT node. You can verify this
using ifconfig
, where something like the following should be visible:
bt0 Link encap:UNSPEC HWaddr 00-19-86-00-16-CA-00-00-00-00-00-00-00-00-00-00
inet6 addr: fe80::19:86ff:fe00:16ca/64 Scope:Link
UP RUNNING MULTICAST MTU:1280 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:18 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:1624 (1.6 KB)
You should also be able to ping your RIOT node. The devices link local address
is also printed when running ble info
on your RIOT device.
# Substitute the actual device address,
ping fe80::uuvv:wwff:fexx:yyzz%bt0
Now everything should be fine :-)
[optional] Distributing a routeable Prefix
You can use the Router Advertisement Daemon (radvd
) in Linux to automatically
distribute prefixes in your BLE network. For the following, you need to make
sure that radvd
is installed on your Linux host.
As a first step, we need to enable IPv6 forwarding in Linux:
sudo sysctl -w net.ipv6.conf.all.forwarding=1
Next, we configure radvd
(etc/radvc.conf
) by using a configuration like
this:
interface bt0
{
AdvSendAdvert on;
prefix 2001:db8::/64
{
AdvOnLink off;
AdvAutonomous on;
AdvRouterAddr on;
};
abro 2001:db8::zzyy:xxff:feuu:vvww
{
AdvVersionLow 10;
AdvVersionHigh 2;
AdvValidLifeTime 2;
};
};
This will tell Linux to advertise the prefix 2001:db8::/64
. Do not forget to
substitute the suffix of global address given in the abro
section
with the one of the BLE device on your Linux host.
NOTE: The abro
section is needed as otherwise the RIOT node will discard
router advertisements, as it is in 6LN configuration
(see https://tools.ietf.org/html/rfc6775#section-4.3).
With this, simply (re-)start the daemon:
sudo service radvd restart
or
sudo systemctl restart radvd
Again, that's it. Your RIOT node should now have an address using the above
prefix assigned. Simply verify with ifconfig
on the RIOT node.
Also you should be able to ping the RIOT node from Linux:
# make sure to use the actual devices address here...
ping -I bt0 2001:db8::uuvv:wwff:fexx:yyzz