IPv6 over Bluetooth on the BeagleBone Black

This project shows how you can use IPv6 over Bluetooth Smart using 6LoWPAN.

Categories: Intermediate

When we remotely connect to a
BeagleBone Black
we generally SSH into them over a WiFi or wired network.  There are several drawbacks to using a WiFi or wired network connection with a
BeagleBone Black
especially with robotic projects.  In this post I will demonstrate how we can use 6LoWPAN over Bluetooth Smart to connect two
BeagleBone Blacks
together.  This will allow us to use standard Internet technologies like SSH or HTTP over a Bluetooth connection. 

6LoWPAN (IPv6 over Low Power Wireless Networks) for Bluetooth was introduced with the Bluetooth Smart 4.2 specifications.  It is defined by
RFC7668
. 6LoWPAN is a software specification that will work with most Bluetooth 4.0 adapters therefore we do not need a special Bluetooth 4.2 adapter to use it.  We also do not need any additional network infrastructure, beside the Bluetooth adapters, like we do with wired and WiFi networks.  Bluetooth smart technologies also use significantly less power as compared to USB WiFi adapters.

One thing to note is I am using two BeagleBone Blacks forthis post however these instructions will also work with Ubuntu 15 computers(or most other Linux based computers) if you are using a 4.4.X or newer kernel.  You can check your kernel version by issuingthe following command:

uname -r

In this post I will walk though installing a new kernel on the BeagleBone Black.  If you are using Ubuntu 15 and have an older kernel, you will need to upgrade it.  This
Google search
should return a number of sites that will walk you though the upgrade process.

For this post I am starting with the standard Debian 8.3image on a 16 gig SD card.  When Iattempted the steps described in this post with a 4 gig SD card I ran out ofroom so you will need to use at least an 8 gig SD card.  The first step will be installing a newkernel.

Installing a new kernel on your BeagleBone Black (pre-built 4.4.6-bone6 kernel)

If you attempt to use 6LoWPAN with the standard kernel thatcomes with Debian 8.3 the two devices appear to connect however the connectionwill drop after a few seconds.  Theproblem is fixed in the 4.4.X or newer kernels. The kernel that I am using is the pre-built 4.4.6-bone6 kernel.  Any of the 4.4.X or newer kernels should workbut I can confirm that the 4.4.6-bone6 kernel does work. 

When I first followed the steps define in this post I already had Swift installed on both of my BeagleBone Blacks as described in this
post
and the kernel installed correctly with the Bluetooth drivers.  After working with this a little bit, I had to reset one of my BeagleBone Blacks and I ended up installing the new kernel without installing Swift first.  When the installation of the new kernel was complete and my BeagleBone Black came back up, after the reboot, my Bluetooth adapters no longer worked.  In the logs I saw that there was an issue loading the Broadcom drivers for the adapter.  It took me two days of experimenting but I finally figured out that if I installed Swift first then after the new kernel was installed my Bluetooth adapters worked properly.  I believe it has to do with installing libicu-dev and clang-3.6 with Swift. 

If you have a problem with your adapter after upgrading thekernel you may want to start over and use the following steps to install libicu-dev and clang-3.6 prior to upgrading your kernel.

sudo apt-get install libicu-dev

sudo apt-get install clang-3.6

sudo update-alternatives --install /usr/bin/clang clang/usr/bin/clang-3.6 100

sudo update-alternatives --install/usr/bin/clang++ clang++ /usr/bin/clang++-3.6 100


When we install the 4.4.6-bone6 kernel we also need toinstall the headers.  The followingcommand will install both the kernel and the headers.

apt-getinstall linux-headers-4.4.6-bone6 linux-image-4.4.6-bone6

Once the new kernel is installed we will need to restart theBeagleBone Black.  Once it has restartedwe can begin configuring the 6LoWPAN connection on both the master and slavedevices.

Configure the 6LoWPAN Master

The 6LoWPAN Master is the device that listens for incoming connections.  Create a new file named
bluetoothMaster.sh
on the device you wish to use as the master and put the following code in it.

modprobe bluetooth_6lowpan

echo 1 >/sys/kernel/debug/bluetooth/6lowpan_enable

hciconfig hci0 leadv


In this script we begin by loading the
bluetooth_6lowpan
module.  We then echo a 1 into the
6lowpan_enable
file.  This will enable 6LoWPAN on the device.  Finally we use the
hciconfig hci0 leadv
command to begin advertising. 

We will also need another script that will setup the network once the client connects.  Let’s call this script
setNet.sh
but we will want to wait to add the code to this script until the first client connects.  This will make it easer to get the IP Address that we will define for our interface.

Configure the 6LoWPAN Slave

The 6LoWPAN Slave is the device that connects to the master.  Create a new file named
bluetoothSlave.sh
and put the following code in it.

modprobe bluetooth_6lowpan

echo 1 >/sys/kernel/debug/bluetooth/6lowpan_enable

hcitool lecc 98:58:8a:06:db:9b 

echo "connect 98:58:8a:06:db:9b 1" >/sys/kernel/debug/bluetooth/6lowpan_control


Note:  Change the 98:58:8a:06:db:9b in this script to the Bluetooth MAC address of the Bluetooth adapter on the master device.  To get the MAC address for a Bluetooth adapter you can use the
hcitool dev
command on the device that the Bluetooth adapter is connected to. 

In this script we begin by loading the
bluetooth_6lowpan
module and enabling 6lowpan as we did in the
bluetoothMaster.sh
script.  We then use the
hcitool
command with the
lecc
option to connect to the master.  The address in the hcitool command is the MAC address for the Bluetooth adapter on the master.   Finally we echo “
connect {MAC address} 1
” to the
6lowpan_control
file which will enable the 6LoWPAN connection between the master and slave devices.

Testing the 6LoWPAN connection

Now that we have a 6LoWPAN connection between our twodevices we can test the connection by attempting to ping one device from theother.  The first thing we need to do isto get the IPv6 addresses assigned to each device. We can do this by runningthe following command on each device.

ifconfig bt0

You should see something like this:

bt0      Link encap:UNSPEC  HWaddr98-58-8A-FF-FE-06-DB-9B-00-00-00-00-00-00-00-00 

         inet6 addr: fe80::9a58:8aff:fe06:db9b/64 Scope:Link

         UP POINTOPOINT RUNNING MULTICAST MTU:1280  Metric:1

         RX packets:13 errors:0 dropped:0 overruns:0 frame:0

         TX packets:9 errors:0 dropped:0 overruns:0 carrier:0

         collisions:0 txqueuelen:1 

          RX bytes:527(527.0 B)  TX bytes:321 (321.0 B)


If this were the bt0 address on my master device then on theslave device I would run the following command:

ping6 –I bt0 fe80::9a58:8aff:fe06:db9b

If the ping works then our connection is correctly setup howeveraddresses with the fe80 prefix are link-local address that really isn’t thatuseful except for testing the connection. Lets see how we could generate a non link-local address and assign it tothe bt0 interface.

Generating and setting an IPv6 address

Before we generate our own IPv6 address, lets look at howthe OS generated the link-local address.  In the example above the address generate whenthe interface came up is: fe80::9a58:8aff:fe06:db9b . The Bluetooth MAC address for the adapter is: 98:58:8a:06:db:9b.  Do you notice anything similar between theIPv6 address assigned to the bt0 adapter and the MAC address of the Bluetoothadapter?

As you probably saw, the OS uses the Bluetooth MAC address to generate the IPv6 address.  Lets look at how the IPv6 address was generated.  We start off with the MAC address and add an 0xFF and 0xFE between the third and forth octet to give us 98:58:8a:
ff:fe
:06:db:9b.  We then OR 0x02 to the first octet to give us
9a
:58:8a:ff:fe:06:db:9b.  We can now covert this to standard IPv6 notation where we group four hexadecimal digits together and separate the groups by a colon.  This will give us  9a58:8aff:fe06:db9b.   Finally we need to add a prefix.  The OS used the fe80 prefix that is reserved for link-local connections which gave us the fe80::9a58:8aff:fe06:db9b .   

For the IPv6 address that we will assign to the bt0interface we will use the 2001:db8prefix that is reserved for documentation. This will give us the following address: 2001:db8::9a58:8aff:fe06:db9b.  Since the OS generates the link-localaddress, rather than going through these calculation steps we could simply takethe link-local address and remove the fe80 prefix and add the prefix we wish to use.

Now that we have an address we will want to assign it to the bt0 interface.  To do this we will add the following line to the
setNet.sh
script on the master:

ifconfig bt0 inet6 add2001:db8::9a58:8aff:fe06:db9b/64

Remember to replace 2001:db8::9a58:8aff:fe06:db9b with theaddress for your device. 

We will also want to add the following two lines to the end of the
bluetoothSlave.sh
file on the slave device:

sleep 2 //pause to make sure the bt0 interface is up

ifconfig bt0 inet6 add2001:db8::5ef3:70ff:fe75:b1d6/64


Remember to replace the 2001:db8::5ef3:70ff:fe75:b1d6address with the one for your slave.

The final scripts

Before we test everything lets look at the final versions of our scripts.  On the master we have two scripts.  These are named
bluetoothMaster.sh
and
setNet.sh
.  The
bluetoothMaster.sh
should contain the following code:

modprobe bluetooth_6lowpan

echo 1 >/sys/kernel/debug/bluetooth/6lowpan_enable

hciconfig hci0 leadv


The
setNet.sh
should contain the following code:

ifconfig bt0 inet6 add2001:db8::9a58:8aff:fe06:db9b/64

Remember to replace the IPv6 address in this script with thecorrect address for your device.

The slave should contain one script named
bluetoothSlave.sh
which should contain the following code.

modprobe bluetooth_6lowpan

echo 1 >/sys/kernel/debug/bluetooth/6lowpan_enable

hcitool lecc 98:58:8a:06:db:9b 

echo "connect 98:58:8a:06:db:9b 1" >/sys/kernel/debug/bluetooth/6lowpan_control

sleep 2 //pause to make sure the bt0 interface is up

ifconfig bt0 inet6 add2001:db8::5ef3:70ff:fe75:b1d6/64


In this script your will want to replace the  98:58:8a:06:db:9b with the Bluetooth MAC address of yourMaster device and replace the 2001:db8::5ef3:70ff:fe75:b1d6  with the IPv6 address for your slave device.

Putting it all together

Now that we have our scripts lets test everything and see how it works.  Go ahead and reboot both devices to clear everything.  When the master device comes up run the
bluetoothMaster.sh
script.  After the
bluetoothMaster.sh
finishes, run the
bluetoothSlave.sh
script on the slave device.  After the
bluetoothSlave.sh
finishes run the
setNet.sh
script on the master.  

After all three scripts complete the 6LoWPAN connection should be up.  We can test this with the
ifconfig bt0
command.  If all is well we should see that the
bt0
interface is up on both devices with both the link-local IPv6 address and the IPv6 address that you assigned it.  We can now test the connection by using ssh to remotely connect to one device from the other.

Comments are not currently available for this post.