Some Android ready devices do not ship with any wireless modules on board. The easiest way to upgrade them for Bluetooth or WiFi connectivity are USB dongles.

I tried myself using a Beagleboard xM (runnign Android ICS) and a Bluetooth USB dongle with a Broadcom BCM2045 chip. Unfortunately it is not just a matter of plug and play, especially not on the kernel that ships with the rowboat Android port.

Preparing the source

Board configuration

We need to modify the board configuration in <android_root>/device/ti/beagleboard/BoardConfig.mk and set:

BOARD_HAVE_BLUETOOTH := true

so the Android build system includes all Bluetooth components.

Kernel

We also want to add Bluetooth support and the Broadcom driver to the kernel. This is done by enabling following options in the <android_root>/kernel/.config

# BT components

CONFIG_BT=y
CONFIG_BT_L2CAP=y
CONFIG_BT_SCO=y
CONFIG_BT_RFCOMM=y
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=y
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=y

# Broadcom driver

CONFIG_BT_HCIBCM203X=y

Bluedroid workaround

Here comes the tricky part. Android uses a component named Bluedroid to power up/shut down the Bluetooth device through the rfkill interface. The problem is that Texas Instrument’s kernel does not support rfkill.

A workaround is to give the Android system the impression it is still in control without actually using rfkill. For that we remove the affected lines and always return 1 on check_bluetooth_power().

Another problem is that Bluedroid is starting or stopping the hciattach service on every call of bt_enable() and bt_disable(). hciattach is used to connect serial Bluetooth devices (e.g. connected through UART) to the Bluez stack. Since we are using USB instead, we don’t need this service any longer. So we can get rid of these lines too.

The full patch is in the download section.

After this we can start the build and grab a few coffees while the build system does it’s job.

Configuring the system

Once all files are on the SD card, there are only a few steps left.

init.rc

We need to start the Bluetooth service when booting up the system. So we add it to the init.rc:

service dbus /system/bin/dbus-daemon --system --nofork
 class main
 socket dbus stream 660 bluetooth bluetooth
 user bluetooth
 group bluetooth net_bt_admin

service bluetoothd /system/bin/bluetoothd -n
 class main
 socket bluetooth stream 660 bluetooth bluetooth
 socket dbus_bluetooth stream 660 bluetooth bluetooth
 # init.rc does not yet support applying capabilities, so run as root and
 # let bluetoothd drop uid to bluetooth with the right linux capabilities
 group bluetooth net_bt_admin misc
 disabled

Enable Bluetooth feature

Now everything is installed and set up properly and the Bluetooth adapter is ready for use. The system just doesn’t know it yet. We have to add the right tag in one of the files in /system/etc/permissions/. I created a new beagleboard_xm.xml file in that directory containing:

<permissions>
<feature name="android.hardware.bluetooth" />
</permissions>

And that’s it!

Bluetooth settings screen

Downloads

Bluedroid patch

Most instructions were taken from the Texas Instruments Android DevKit Porting Guide.