Linux & Wireless LANs | IrDA | Papers | Main page |
Download | Information | Brainboxes | BT Stacks | Pcmcia card | OpenBT | BlueZ 1.2 |
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.
If you are using BlueZ :
BlueZ Linux BlueTooth stack :
OpenBT Linux BlueTooth stack :
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 :
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.
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 :
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 921600After that, you should be able to configure your BlueTooth stack to use 921600 bauds.
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.
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
The whole installation procedure looks like :
mknod /dev/ttyUB0 c 216 0
/* 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 */
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).
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.
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.
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).
To enable BlueZ, you will need to do the following operations :
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).
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
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 naThen, on the client side :
> rfcommd -f rfcommd.conf na 50:C2:00:03:C4:DCTo close the connection, you need to kill the rfcomm instance on one side.
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).
To enable BlueZ, you will need to do the following operations :
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
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
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
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.
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 :
> 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 :
|