WiFi hotspot and DHCP from a BeagleBone
Last updated: Jan. 28, 2012, 8:55 p.m.
The BigTrak project had to be mobile, and that meant having a WiFi card attached. This looked simple on the face of it, a USB host socket on the board and a modern 32bit Linux kernel, however it became more complicated partly due to the lack of sources for the embedded system and partly because of my ambitions.
I was using a Ralink RT2770F based 802.11n adapter. I actually pulled this out of my O2 Joggler as I knew the Wi-Fi adapter in it, despite being internal plugged into a normal USB-A host socket. That made identifying the chip a lot easier as I could actually see it! To get it working on the BeagleBone in a basic fashion I had to first install the modules which are available in an extra tar file called modules-3.1.0+....tgz from the official BeagleBone Angstrom downloads page. To install just un-tar the file in the root directory. I also needed the firmware for the card, this was included in my desktop Ubuntu install in /lib/firmware
so I just copied it (rt2870.bin in my case) to the same folder on the BeagleBone (using scp). I also installed wireless tools (opkg install wireless-tools
) which let me scan for access points. After a bit of fiddling with wpa_supplicant I got it to work in client mode. However after taking it to the Hackspace and being totally unable to access the web server on it via wireless I had to do something a bit more drastic.
Installing hostapd
To set up a WiFi access point I installed hostapd, I was hoping it would be in the repository for the BeagleBone but sadly it needed compiling from source. Unfortunately that is complicated somewhat by it's dependency on an ancient version of libnl
, a low level net-link library. To get it to build then, you need to first compile the netlink library of the appropriate version.
wget http://www.infradead.org/~tgr/libnl/files/libnl-1.1.tar.gz
tar xvzf libnl-1.1.tar.gz
cd libnl-1.1/
There's a bug in this version of the library which will stop it from compiling on the BeagleBone, you need to open include/netlink-local.h
and add (on or around line 29)
#include <limits.h>
Once that's done it should be plain sailing to get that installed:
./configure
make
make install
Because it installs the library in /usr/local/lib you'll need to add this to /etc/ld.so.conf (should be blank on the BeagleBone) just add /usr/local/lib
on a new line and save the file. On the command line type ldconfig and wait a moment while it updates the library cache.
Now you should be able to compile the actual hostapd software.
wget http://w1.fi/releases/hostapd-0.7.3.tar.gz
tar zxvf hostapd-0.7.3.tar.gz
cd hostapd-0.7.3/hostapd
cp defconfig .config
You need to edit the .config file (yes it really does have a . at the start, and no, I have no idea why either) for my chipset (and a lot of others around) you'll need to use the NL80211 driver. To build this you need to uncomment line 23 (CONFIG_DRIVER_NL80211=y
) and because of where we installed libnl to you need to add a line
CFLAGS += -I/usr/local/include
somewhere around there.
Build and install it, don't forget to make the bin directory for it, for some reason the Makefile can't do this.
make
mkdir /usr/local/bin
make install
DHCP server
If you're providing the WiFi most devices will expect you to provide IP addresses to go with it. Fortunately the BeagleBone comes pre-configured with a DHCP server, well, almost. There's a USB ethernet device emulator mode which allows it to pretend to be a USB to ethernet adapter when plugged into a host PC via the USB port on the board, this is meant to allow "one cable development". However, I didn't want that particularly so I commented it out in /etc/network/interfaces and editted the DHCP server to work over WiFi instead. The DHCP server is the busybox one and configured in a file called /etc/udhcpd.conf
, I only changed the interface name:
start 192.168.7.1
end 192.168.7.1
interface wlan0
max_leases 1
option subnet 255.255.255.252
There seems to be a bug in the filesystem though, if you try and run udhcpd on the command line it will instantly and silently fail. After some rummaging it seems that you have to make sure the leases file exists for it before running it, and for some reason it doesn't on the BeagleBone. To get it working just run:
touch /var/lib/misc/udhcpd.leases
Making it Autostart
This turned out to be nearly as hard as getting the access point to work in the first place. The BeagleBone uses systemd which is a superbly fast start up solution well suited to the embedded platform. Unfortunately I'm no expert and getting the right configuration to make the startup of hostapd wait until after the USB WiFi card had sorted itself out with the kernel was somewhat troublesome. I've got two ".service" declarations which start the python web server and the WiFi access point and DHCP. They follow a fairly obvious structure based on the "bone101.service" file that started up the slideshow sever in the original firmware:
/etc/systemd/system/multi-user.target.wants/ap.service
[Unit]
Description=logo server
ConditionPathExists=|/home/root/webtrak
[Service]
WorkingDirectory=/home/root/webtrak
ExecStart=/usr/bin/python serv.py
[Install]
WantedBy=multi-user.target
/etc/systemd/system/multi-user.target.wants/ap2.service
[Unit]
Description=WiFi AP
ConditionPathExists=|/home/root/
[Service]
WorkingDirectory=/home/root
ExecStart=/bin/bash startap.sh
[Install]
WantedBy=multi-user.target
The startap.sh is a basic shell script that brings the WiFi up, starts the DHCP server and finally starts the access point with some debugging messages that will appear in /var/log/messages
to keep an eye on what it's doing. The 15 second delay at the start was the only way I could find to give the WiFi card time to get started before trying to bring it up.
startap.sh
echo APD wait a few seconds for the USB to be ready
sleep 15
echo APD ifconfig
ifconfig wlan0 192.168.7.2
echo APD starting dhcp server
udhcpd
echo APD start wifi AP
hostapd hostapd-minimal.conf
Comments
wifi python and stuff
29 Mar 2012 - 20:20 dave eaton
Thanks for this. I fiddled a little with trying to get my usb wifi adapter to work, but had no idea which way to go when it just sat there. I appreciate you wading in and finding the crocodiles so those less familiar with Linux can follow along.
Posting comments is not currently possible. If you want to discuss this article you can reach me on twitter or via email.
A Question?
20 Mar 2012 - 08:33 enienws
You have said that:
" I also needed the firmware for the card, this was included in my desktop Ubuntu install in /lib/firmware so I just copied it (rt2870.bin in my case) to the same folder on the BeagleBone (using scp)."
There is a point that was not so clear for me. I think, a binary rt2870.bin from your native architecture (your desktop ubuntu) should not work with your embedded architecture. they should have different machine languages. How is this possible? Could explain?
Best wishes.
Wifi Firmware
03 Apr 2012 - 14:51 nathan
Actually because the firmware is to be run on the device (i.e. in this case the microcontroller embeded in the wireless chip) it doesn't matter what the host system is, the code is only for the peripheral processor.