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 for
this 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 issuing
the 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.3
image on a 16 gig SD card. When I
attempted the steps described in this post with a 4 gig SD card I ran out of
room so you will need to use at least an 8 gig SD card. The first step will be installing a new
kernel.
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 that
comes with Debian 8.3 the two devices appear to connect however the connection
will drop after a few seconds. The
problem 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 work
but 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 the
kernel 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 to
install the headers. The following
command will install both the kernel and the headers.
apt-get
install linux-headers-4.4.6-bone6 linux-image-4.4.6-bone6
Once the new kernel is installed we will need to restart the
BeagleBone Black. Once it has restarted
we can begin configuring the 6LoWPAN connection on both the master and slave
devices.
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 two
devices we can test the connection by attempting to ping one device from the
other. The first thing we need to do is
to get the IPv6 addresses assigned to each device. We can do this by running
the following command on each device.
ifconfig bt0
You should see something like this:
bt0
Link encap:UNSPEC HWaddr
98-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 the
slave 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 however
addresses with the fe80 prefix are link-local address that really isn’t that
useful except for testing the connection.
Lets see how we could generate a non link-local address and assign it to
the bt0 interface.
Generating and setting an IPv6 address
Before we generate our own IPv6 address, lets look at how
the OS generated the link-local address. In the example above the address generate when
the 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 the
IPv6 address assigned to the bt0 adapter and the MAC address of the Bluetooth
adapter?
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 bt0
interface we will use the 2001:db8
prefix that is reserved for documentation.
This will give us the following address: 2001:db8::9a58:8aff:fe06:db9b. Since the OS generates the link-local
address, rather than going through these calculation steps we could simply take
the 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 add
2001:db8::9a58:8aff:fe06:db9b/64
Remember to replace 2001:db8::9a58:8aff:fe06:db9b with the
address 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 add
2001:db8::5ef3:70ff:fe75:b1d6/64
Remember to replace the 2001:db8::5ef3:70ff:fe75:b1d6
address 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 add
2001:db8::9a58:8aff:fe06:db9b/64
Remember to replace the IPv6 address in this script with the
correct 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 add
2001: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 your
Master 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.
No comments:
Post a Comment