Brainboxes BlueTooth + Linux Howto



Linux & Wireless LANs IrDA Papers Main page

Download Information Brainboxes BT Stacks Pcmcia card OpenBT BlueZ 1.2


Introduction

Part of my job at Hewlett Packard is to evaluate various kind of wireless technologies. Of course, BlueTooth could not escape this investigation.

I read my first BlueTooth specification in autumn 1997, when it was still called MC-Link and only 58 pages. Since then, I did like everybody else : attend the various conference, try to contribute to the workgroups, buy the expensive development kits and wait. But now, at least, I've got a few experiences to share with you ;-)

Note that BlueTooth support under Linux is constantly evolving, and BlueZ in particular has a lot of entropy. That's why I mention the exact version that worked for me. And remember the developers always expect you to only run the latest version.


Bits to download

If you are using the Brainboxes Pcmcia card :

If you are using BlueZ :


Links and more information

Brainboxes hardware :

BlueZ Linux BlueTooth stack :

OpenBT Linux BlueTooth stack :

OpenObex over BlueZ : Related information :


BlueTooth and Brainboxes

BlueTooth is a radio standard heavily influenced by IrDA and USB, and offers the functionality of a wireless USB and serial cable replacement (see BlueTooth for a more complete description). BlueTooth defines its own protocol stack as well, and offers the possibility to create long term binding between devices (attach wirelessly peripherals to a phone or a PDA). TCP/IP networking over BlueTooth can be done using PPP over RfComm.

Brainboxes was one of the first company to offer BlueTooth products which are available, relatively cheap (~$220) and compatible with Linux. At that time, most other products did fail on one of those 3 criteria, but today the situation has dramatically improved. You can contact them directly via e-mail to order. If you order the Pcmcia, CF or RS232 card, I would recommend H4 version (as opposed to BCSP), on the other hand for USB this subtelty doesn't exist.

I've personally tested the Pcmcia card (BL620) and USB dongle (BL554) with both OpenBT and BlueZ. The RS232 dongle would probably work without troubles, but at restricted speed (115200 bauds). The UART of the CF card (BL631) would require some investigation.

From my light testing, the Pcmcia card and the USB dongle gives you more or less the same throughput (limited by the radio channel or PPP framing overhead). However, the USB dongle has a lower latency and lower CPU usage than the Pcmcia card (USB uses DMA transfer and the UART uses PIO, which explains a lot). However, I still get much better results with 802.11 or IrDA ;-)

Other hardware I have tested

USB dongles are the best way to start with BlueTooth, as :

I personally have used the following USB dongles :


Linux BlueTooth stacks : OpenBT and BlueZ

There is two totally different BlueTooth stacks available for Linux, both of them Open Source. OpenBT is mostly a contribution of Axis, and BlueZ is originally a contribution of Qualcom.

The strength of OpenBT 0.8 are :

The strength of BlueZ 1.2 are :

The additional strength of BlueZ 2.4 are :

Of course, this list will probably evolve over time...

The main architectural difference between the stacks is their interfaces, both to drivers and applications. OpenBT uses a serial abstraction, and BlueZ uses a network abstraction. We'll come back to it later.


Brainboxes Pcmcia card and higher speeds

The Brainboxes Pcmcia card contains a real UART (16C950). This UART has some interesting features, such as higher speeds and deep fifos, enabling higher performance transfer to the CSR chip.

The standard Pcmcia drivers (in the Pcmcia package) will automatically recognise the UART and enable the Linux serial driver on it. Different PCs and different configurations will load the UART at different addresses. With kernel 2.4.X, the way to know which serial port on your PC is the Pcmcia card is to check the message log using dmesg or to use setserial to look for the UART identified as "16C950/954". Mine is loaded as /dev/ttyS2.

The kernel 2.2.X won't recognise this UART and won't enable the extended features (i.e. you will be stuck at 115200 bauds). The kernel 2.4.X recognise most of the features of the chip, but will enable you to reach only 460800 bauds.

To reach the maximum speed of the card (921600 bauds), you will need to do a bit of hacking :

  1. Download the kernel source (version 2.4.X - you may also get it from your distribution).
  2. Apply my serial driver patch to the kernel.
  3. Download the setserial utility.
  4. Apply my patch for setserial.
  5. Install the new kernel, its modules and the new setserial.

Then, after every time you reset the computer or insert the card, you just need to use this magic incantation :

> setserial /dev/ttyS2 wmsr 0x30
> setserial /dev/ttyS2 baud_base 921600
After that, you should be able to configure your BlueTooth stack to use 921600 bauds.


OpenBT 0.8 setup

I did only limited testing with OpenBT 0.8, both with the Brainboxes Pcmcia card and the USB dongle.

OpenBT use a serial abstraction (TTY) to interface both to drivers and applications. OpenBT talk to the hardware either directly to the serial port (for example /dev/ttyS2) or to a pseudo serial port (for example /dev/ttyUB0 for the USB-serial converter). Applications talk to the OpenBT stack using one of OpenBT pseudo serial port, such as /dev/ttyBT0.

OpenBT and the Brainboxes Pcmcia card

The operation is already described in details in the BlueTooth Howto of Frank Kargl, so I won't repeat it all here.

A few caveats :

Starting OpenBT at 921600 bauds looks like this :

> setserial /dev/ttyS2 wmsr 0x30
> setserial /dev/ttyS2 baud_base 921600
> insmod .../openbt/linux/drivers/char/bluetooth/bt.o
> .../openbt/apps/bluetooth/experimental/bti -u /dev/ttyS2 -s 921600

OpenBT and the USB dongle

The operation is somewhat similar to the procedure described above. Instead of using a real serial port, you will need to use a BlueTooth USB-serial converter driver. Such a driver is included in kernel 2.4.X, and usually create a pseudo serial port as /dev/ttyUB0 (you may need to check your logs for confirmation).

The whole installation procedure looks like :

  1. Enable appropriate USB support in you kernel (UHCI/OHCI)
  2. Enable the BlueTooth USB-Serial converter in your kernel : the option is called USB Bluetooth support in the menu USB support.
  3. Create the pseudo serial device :
    mknod /dev/ttyUB0 c 216 0
    
  4. Compile OpenBT for USB support, by selecting the option CONFIG_BLUETOOTH_USBMODULE in .../openbt/linux/include/linux/bluetooth/btconfig.h.
     /* This sets current HW */
     #undef CONFIG_BLUETOOTH_NOINIT
     #undef CONFIG_BLUETOOTH_CSR
     #undef CONFIG_BLUETOOTH_DIGIANSWER
     #undef CONFIG_BLUETOOTH_ERICSSON
     #undef CONFIG_BLUETOOTH_INFINEON_BMI
     #undef CONFIG_BLUETOOTH_GENERIC
     #define CONFIG_BLUETOOTH_USBMODULE  /* Not implemented */
    
  5. Don't forget to comment out MODFLAGS and check INCLUDEDIR in .../openbt/linux/drivers/char/bluetooth/Makefile.

Now, to start OpenBT on the USB dongle, you just need to do :

> modprobe bluetooth
> insmod .../openbt/linux/drivers/char/bluetooth/bt.o
> .../openbt/apps/bluetooth/experimental/bti -u /dev/ttyUB0

From the mailing list, it seems that USB support in OpenBT is not totally stable (I didn't try much).

PPP over RfComm

One of the main application of BlueTooth is to network two host (although I would argue that 802.11 is better suited for that), which is currently done via PPP over RfComm (better alternatives are on the way).

First, you need to know what is the address of the other end of the link. One way is to check the other end, but that's cheating, the other way is to do an Inquiry :

> .../openbt/apps/bluetooth/experimental/btinq
BD 0: 50:c2:00:03:c4:dc
>

Then, you can connect to this device. With OpenBT, the RfComm server is always runnning, so you only need to start the client :

> .../openbt/apps/bluetooth/experimental/btcon -d /dev/ttyBT0 -a 50:c2:00:03:c4:dc -S 1

After that, you can check that PPP created a new interface (with ifconfig and route) and that you can ping the IP address on the other end of the tunnel.

Obex

Obex is the prefered way to communicate over BlueTooth for a wide variety of function (file transfer, vCal, vCard).

At this time, it doesn't seem that OpenObex and OpenBT work with each other, and it doesn't look like OpenBT has any OBEX support.


BlueZ 1.2 setup

I did only limited testing with BlueZ 1.2, both with the Brainboxes Pcmcia card and the USB dongle. This section only deals with version 1.2, the more recent version 2.2 is described below.

As opposed to OpenBT, BlueZ use a network abstraction to interface both to drivers and applications. BlueZ need special network driver for serial and USB devices, and BlueTooth devices will be referenced as hciX (most often hci0). Applications talk to the BlueZ stack using sockets (using the AF_BLUETOOTH family).

Common configuration

The BlueZ web site already contains an excellent Howto, so you may want to start by reading that...

To enable BlueZ, you will need to do the following operations :

  1. Get a fairly recent Linux kernel (I've used 2.4.12 and 2.4.14).
  2. Enable BlueZ and related options in your kernel, under the menu Bluetooth support.
  3. Download and install the BlueZ package. Don't pay attention to various errors when compiling the kernel part of the package.
  4. Download and install the hcidump package.
  5. Download and install the rfcomm package.

BlueZ and the USB dongle

BlueZ has strong support for USB dongles. As opposed to OpenBT, BlueZ doesn't use the BlueTooth USB to serial converter, but uses its own USB driver (and of course, you can't have both running at the same time).

To get your USB dongle working, you need to do :

> modprobe hci
> modprobe hci_usb
> modprobe l2cap
> hciconfig hci0 up

After that, you can setup RfComm links (see Howto).

BlueZ and the Brainboxes Pcmcia card

BlueZ support of serial devices is not as strong as OpenBT. For example, BlueZ doesn't support BCSP (that's why you need to order your cards in the H4 variety).

By default, BlueZ will only be able to run the CSR chip at 115200 bauds. I've made a patch to add support for the higher speeds of the CSR chip. This will enable you to run at 460800 bauds, and with a few more patches you will be able to do 921600 bauds.

With this patch, you need to configure the last section of /etc/hcid.conf in the following way :

# HCI devices with UART interface
uart {
	/dev/ttyS2 460800 flow csr;
	#/dev/ttyS2 921600 flow csr;
}

Then, you start the stack like this :

> modprobe hci
> modprobe hci_uart
> modprobe l2cap
> hcid

PPP over RfComm

BlueZ is a bit more complex when it comes to RfComm. I'll just give you a few pointers, see the Howto for actual details.

You still need to know the address of the other end of the link ; the inquiry is currently done like this :

> hciconfig hci0 inq
Inquiring ...
        50:C2:00:03:C4:DC       clock offset: 0x2454    class: 0x020300

Assuming the file rfcommd.conf is properly configured on both side, you first start rfcomm on the server side :

> rfcommd -f rfcommd.conf -s na
Then, on the client side :
> rfcommd -f rfcommd.conf na 50:C2:00:03:C4:DC
To close the connection, you need to kill the rfcomm instance on one side.


BlueZ 2.3 setup

Maksim and their friends are working too hard, and BlueZ has matured significantely since I last tested it, so it was time to revisit the issue. With version 2.2, the most interesting new feature is of course PAN/BNEP support. With version 2.3, we have the new RfCOMM support which is a big improvement.

So, I did again limited testing with BlueZ 2.2, both with the Brainboxes Pcmcia card and the USB dongle. I also did extensive testing of BlueZ 2.3 with the 3Com 3CREB96 USB dongle. A lot of the tools and procedure have changed with respect to BlueZ 1.2

As opposed to OpenBT, BlueZ use a network abstraction to interface both to drivers and applications. BlueZ need special network driver for serial and USB devices, and BlueTooth devices will be referenced as hciX (most often hci0). Applications talk to the BlueZ stack using sockets (using the AF_BLUETOOTH family).

Common configuration

The BlueZ web site already contains an excellent Howto, so you may want to start by reading that...

To enable BlueZ, you will need to do the following operations :

  1. Get a fairly recent Linux kernel, BlueZ 2.3 is included in kernel 2.4.21-pre3 and later.
  2. Enable BlueZ and related options in your kernel, under the menu Bluetooth support.
  3. Compile and reinstall your kernel.
  4. Download and install the BlueZ library package.
  5. Download and install the BlueZ utilities and BlueZ sdp package. Those will compile only if the library is fully installed.
  6. Optionally, download and install the hcidump package. It's a good debugging tool and necessary to do proper bug reports.
  7. Download and install the PAN package. This will compile only if both the utils and sdp packages are fully installed.
To get module auto-loading to work, you need to add in /etc/modules.conf the following :
alias net-pf-31 bluez
alias bt-proto-0 l2cap
alias bt-proto-2 sco
alias bt-proto-3 rfcomm
alias bt-proto-4 bnep

BlueZ and the USB dongle

BlueZ has strong support for USB dongles. As opposed to OpenBT, BlueZ doesn't use the BlueTooth USB to serial converter, but uses its own USB driver (and of course, you can't have both running at the same time).

First, you need to get the USB stack up and running. This depend on your USB controller (UHCI vs OHCI).

To get you USB dongle working, you then need to do :

> modprobe bluez
> modprobe hci_usb
> modprobe l2cap
> hciconfig hci0 up

BlueZ and the Brainboxes Pcmcia card

The version 1.6 of BlueZ has changed the way serial devices are initialised. Instead of using hcid, you will need to use hciattach.

My obsolete patchthat adds CSR chip support to hciattach has been included in BlueZ 2.0 (and improved), so it will work out of the box at 460800 bauds. With a few more patches you will be able to do 921600 bauds.

You start the stack like this :

> modprobe bluez
> modprobe hci_uart
> modprobe l2cap
> hciattach /dev/ttyS2 csr 460800
> hciconfig hci0 up

TCP/IP over PAN/BNEP

PAN and BNEP are the "official" way to do networking with BlueTooth. BNEP is a simple encapsulation of Ethernet frames in a L2CAP session. PAN is the BlueTooth profile using BNEP and defining how to do networking. It includes the definition of the SDP attributes and various node roles.

What are the node roles ? It's just something to make your life more complex. In a typical Ad-Hoc scenario, the server will have the role GN, and up to 7 clients with role PANU can be connected to it. An Access Point would take a NAP (yeah, boring).

The support of BNEP in BlueZ is quite new and and not yet documented in the Official Howto, but there is an alternate Unofficial Howto.

As usual, I'll go straight to a very simple example of setting up TCP/IP between two nodes. You can do more complex stuff by reading the Howto above.


First, you need to set up the server. The server will listen for incomming connections. In our example, it's not an Access Point, so we do :

> modprobe bnep
> pand --listen --role GN

On the client side, we first need to know the address of the server ; the inquiry is currently done like this :

> hcitool inq
Inquiring ...
        50:C2:00:03:C4:DC       clock offset: 0x2454    class: 0x020300

Now, you just need to connect to the other side :

> modprobe bnep
> pand --connect 50:C2:00:03:C4:DC

Unfortunately, pand can fail silently, so the way to check if this succeed is to see if a new device bnep0 has been created, either using cat /proc/net/dev or ifconfig bnep0. You may notice that the interface is down, that's perfectly normal at this point. In case of problem, you need to check the logs for details, in my case /var/log/daemon.log.

What's left ? BNEP is only a Ethernet emulation. We need to configure TCP/IP on the new interface. This is done with :

> ifconfig bnep0 10.10.10.1 broadcast 10.10.10.255 netmask 255.255.255.0

Just remember that you need to assign an different IP address on each node, otherwise it won't work. After that, you should be able to ping, telnet and all that jazz.

To terminate your connection on the client, just do :

> ifconfig bnep0 down
> pand --kill 50:C2:00:03:C4:DC

If you want to get more fancy, you can use HotPlug to automatically assign IP addresses to the bnep interfaces, and you can start playing with the SPD to know which node support PAN or not. And, if you want to build an Access Point, you will need to enable bridging. The HOWTO explains that in details.

OpenObex over RfCOMM

Obex is the prefered way to communicate over BlueTooth for a wide variety of profiles (file transfer, image push, vCal, vCard). Obex runs over RfCOMM.

The support of Obex over BlueTooth is not fully documented, and various application will implement it differently. It requires BlueZ 2.3 or later and OpenObex 1.0.0 or later.

Here is a very simple example of Obex over BlueTooth :

  1. Make sure you have BlueZ 2.3 and RfCOMM protocol support enabled in your kernel. However, you don't need RfCOMM TTY support.
  2. Download and install the OpenObex 1.0.0 package (this is the main Obex library).
  3. Download and install the OpenObex-apps 1.0.0 package (which contains the obex_test utility).
First, we start the test server :
> modprobe rfcomm
> obex_test -b
> > s

On the client side, we first need to know the address of the server :

> hcitool inq
Inquiring ...
        50:C2:00:03:C4:DC       clock offset: 0x2454    class: 0x020300

Now, you just need to connect to the other side using the default RfCOMM channel :

> modprobe rfcomm
> obex_test -b 50:C2:00:03:C4:DC 4
> > c
> > p
> > d

Obviously, this is only a basic test and is not very useful. However, some popular applications such as ObexFTP and Multisync already support Obex over RfCOMM. If you are interested in the programming side, my e-Squirt library shows a complete implementation of Obex over RfCOMM (including SDP).


Wireless LANs and IrDA - jt@hpl.hp.com
Created 9 November 01
Updated 5 June 03
    Project hosted and sponsored by :