Several small-footprint devices are powered by the dual combination of a wireless technology and Linux. Bluetooth, Infrared, WiFi, and cellular networking are established wireless technologies that have healthy Linux support. Bluetooth eliminates cables, injects intelligence into dumb devices, and opens a flood gate of novel applications. Infrared is a low-cost, low-range, medium-rate, wireless technology that can network laptops, connect handhelds, or dispatch a document to a printer. WiFi is the wireless equivalent of an Ethernet LAN. Cellular networking using General Packet Radio Service (GPRS) or code division multiple access (CDMA) keeps you Internet-enabled on the go, as long as your wanderings are confined to service provider coverage area.
Because these wireless technologies are widely available in popular form factors, you are likely to end up, sooner rather than later, with a card that does not work on Linux right away. Before you start working on enabling an unsupported card, you need to know in detail how the kernel implements support for the corresponding technology. In this chapter, let's learn how Linux enables Bluetooth, Infrared, WiFi, and cellular networking.
Bluetooth, Infrared, WiFi, and GPRS serve different niches. The trade-offs can be gauged in terms of speed, range, cost, power consumption, ease of hardware/software co-design, and PCB real estate usage.
Table 16.1 gives you an idea of these parameters, but you will have to contend with several variables when you measure the numbers on the ground. The speeds listed are the theoretical maximums. The power consumptions indicated are relative, but in the real world they also depend on the vendor's implementation techniques, the technology subclass, and the operating mode. Cost economics depend on the chip form factor and whether the chip contains built-in microcode that implements some of the protocol layers. The board real estate consumed depends not just on the chipset, but also on transceivers, antennae, and whether you build using off-the-shelf (OTS) modules.
|Speed||Range||Power||Cost||Co-Design Effort||Board Real Estate|
|Bluetooth||720Kbps||10m to 100m||**||**||**||**|
|Infrared Data||4Mbps (Fast IR)||Up to 1 meter within a 30-degree cone||*||*||*||*|
|WiFi||54Mbps||150 meters (indoors)||****||***||***||***|
|GPRS||170Kbps||Service provider coverage||***||****||*||***|
|Note: The last four columns give relative measurement (depending on the number of * symbols) rather than absolute values.|
Some sections in this chapter focus more on "system programming" than device drivers. This is because the corresponding regions of the protocol stack (for example, Bluetooth RFCOMM and Infrared networking) are already present in the kernel and you are more likely to perform associated user mode customizations than develop protocol content or device drivers.
Bluetooth is a short-range cable-replacement technology that carries both data and voice. It supports speeds of up to 723Kbps (asymmetric) and 432Kbps (symmetric). Class 3 Bluetooth devices have a range of 10 meters, and Class 1 transmitters can communicate up to 100 meters.
Bluetooth is designed to do away with wires that constrict and clutter your environment. It can, for example, turn your wristwatch into a front-end for a bulky Global Positioning System (GPS) hidden inside your backpack. Or it can, for instance, let you navigate a presentation via your handheld. Again, Bluetooth can be the answer if you want your laptop to be a hub that can Internet-enable your Bluetooth-aware MP3 player. If your wristwatch, handheld, laptop, or MP3 player is running Linux, knowledge of the innards of the Linux Bluetooth stack will help you extract maximum mileage out of your device.
As per the Bluetooth specification, the protocol stack consists of the layers shown in Figure 16.1. The radio, link controller, and link manager roughly correspond to the physical, data link, and network layers in the OpenSystems Interconnect (OSI) standard reference model. The Host Control Interface (HCI) is the protocol that carries data to/from the hardware and, hence, maps to the transport layer. The Bluetooth Logical Link Control and Adaptation Protocol (L2CAP) falls in the session layer. Serial port emulation using Radio Frequency Communication (RFCOMM), Ethernet emulation using Bluetooth Network Encapsulation Protocol (BNEP), and the Service Discovery Protocol (SDP) are part of the feature-rich presentation layer. At the top of the stack reside various application environments called profiles. The radio, link controller, and link manager are usually part of Bluetooth hardware, so operating system support starts at the HCI layer.
A common method of interfacing Bluetooth hardware with a microcontroller is by connecting the chipset's data lines to the controller's UART pins. Figure 13.4 of Chapter 13, "Audio Drivers," shows a Bluetooth chip on an MP3 player communicating with the processor via a UART. USB is another oft-used vehicle for communicating with Bluetooth chipsets. Figure 11.2 of Chapter 11, "Universal Serial Bus," shows a Bluetooth chip on an embedded device interfacing with the processor over USB. Irrespective of whether you use UART or USB (we will look at both kinds of devices later), the packet format used to transport Bluetooth data is HCI.
The BlueZ Bluetooth implementation is part of the mainline kernel and is the official Linux Bluetooth stack. Figure 16.2 shows how BlueZ maps Bluetooth protocol layers to kernel modules, kernel threads, user space daemons, configuration tools, utilities, and libraries. The main BlueZ components are explained here:
To run serial port applications such as terminal emulators over Bluetooth, you need to emulate serial ports over L2CAP. This is accomplished by rfcomm.ko. RFCOMM also functions as the pillar that supports networking over PPP. To service incoming RFCOMM connections, rfcomm.ko spawns a kernel thread called krfcommd. To set up and maintain connections to individual RFCOMM channels on target devices, use the rfcomm utility.
Audio is handled via the Synchronous Connection Oriented (SCO) layer implemented by sco.ko.
The Sharp Bluetooth Compact Flash card is built using a Silicon Wave chipset and uses a serial transport to carry HCI packets. There are three different ways by which HCI packets can be transported serially:
BlueCore Serial Protocol (BCSP), which is a proprietary protocol from Cambridge Silicon Radio (CSR) that supports error checking and retransmission. BCSP is used on non-USB devices based on CSR BlueCore chips including PCMCIA and CF cards. The BlueZ BCSP implementation lives in drivers/-bluetooth/hci_bcsp.c.
The read data path for the Sharp Bluetooth card is shown in Figure 16.3. The first point of contact between the card and the kernel is at the UART driver. As you saw in Figure 9.5 of Chapter 9, "PCMCIA and Compact Flash," the serial Card Services driver, drivers/serial/serial_cs.c, allows the rest of the operating system to see the Sharp card as if it were a serial device. The serial driver passes on the received HCI packets to BlueZ. BlueZ implements HCI processing in the form of a kernel line discipline. As you learned in Chapter 6, "Serial Drivers," line disciplines reside above the serial driver and shape its behavior. The HCI line discipline invokes associated protocol routines (H4 in this case) for assistance in data processing. From then on, L2CAP and higher BlueZ layers take charge.
Let's now look at a device that uses USB to transport HCI packets. The Belkin Bluetooth USB adapter is one such gadget. In this case, the Linux USB layer (drivers/usb/*), the HCI USB transport driver (drivers/bluetooth/hci_usb.c), and the BlueZ protocol stack (net/bluetooth/*) are the main players that get the data rolling. Let's see how these three kernel layers interact.
As you learned in Chapter 11, USB devices exchange data using one or more of four pipes. For Bluetooth USB devices, each pipe is responsible for carrying a particular type of data:
You also saw in Chapter 11 that when a USB device is plugged into a system, the host controller driver enumerates it using a control pipe and assigns endpoint addresses between 1 and 127. The configuration descriptor read by the USB subsystem during enumeration contains information about the device, such as its class, subclass, and protocol. The Bluetooth specification defines the (class, subclass, protocol) codes of Bluetooth USB devices as (0xE, 0x01, 0x01). The HCI USB transport driver (hci_usb) registers these values with the USB core during initialization. When the Belkin USB adapter is plugged in, the USB core reads the (class, subclass, protocol) information from the device configuration descriptor. Because this information matches the values registered by hci_usb, this driver gets attached to the Belkin USB adapter. hci_usb reads Bluetooth data from the four USB pipes described previously and passes it on to the BlueZ protocol stack. Linux applications now run seamlessly over this device, as shown in Figure 16.2.
To take an example, assume that you have a Bluetooth-aware pill dispenser. When you pop a pill out of the dispenser, it sends a message over a Bluetooth RFCOMM channel. A Linux cell phone, such as the one shown in Figure 6.5 of Chapter 6, reads this alert using a simple application that establishes an RFCOMM connection to the pill dispenser. The phone then dispatches this information to the health-care provider's server on the Internet via its GPRS interface.
A skeletal application on the Linux cell phone that reads data arriving from the pill dispenser using the BlueZ socket API is shown in Listing 16.1. The listing assumes that you are familiar with the basics of socket programming.
Trace down the code path from the telnet/ftp/ssh box in Figure 16.2 to see how networking is architected over BlueZ Bluetooth. As you can see, there are two different ways to network over Bluetooth:
By running TCP/IP over PPP over RFCOMM. This is called dialup networking (DUN).
The kernel implementation of Bluetooth networking is unlikely to interest the device driver writer and is not explored. Table 16.2 shows the steps required to network two laptops using PAN, however. Networking with DUN resembles this and is not examined. The laptops are respectively Bluetooth-enabled using the Sharp CF card and the Belkin USB adapter discussed earlier. You can slip the CF card into the first laptop's PCMCIA slot using a passive CF-to-PCMCIA adapter. Look at Figure 16.2 in tandem with Table 16.2 to understand the mappings to corresponding BlueZ components. Table 16.2 uses bash-sharp> and bash-belkin> as the respective shell prompts of the two laptops.
|On the laptop with the Sharp Bluetooth CF card|
|On the laptop with the Belkin USB Bluetooth adapter|
|If you now look at the ifconfig output on the two laptops, you will find that a new interface named bnep0 has made an appearance at both ends. Assign IP addresses to both interfaces and get ready to telnet and FTP!|
 A useful command-line option to pand is --persist, which automatically attempts to reconnect when a connection drops. Dig into the man pages for more invocation options.
Let's take the example of an HBH-30 Sony Ericsson Bluetooth headset to understand Bluetooth SCO audio. Before the headset can start communicating with a Linux device, the Bluetooth link layer on the latter has to discover the former. For this, put the headset in discover mode by pressing the button earmarked for device discovery. In addition, you have to configure BlueZ with the headset's personal identification number (PIN) by adding it to /etc/bluetooth/pin. An application on the Linux device that uses BlueZ SCO APIs can now send audio data to the headset. The audio data should be in a format that the headset understands. The HBH-30 uses the A-law PCM (pulse code modulation) format. There are public domain utilities for converting audio into various PCM formats.
Bluetooth chipsets commonly have PCM interface pins in addition to the HCI transport interface. If a device supports, for instance, both Bluetooth and Global System for Mobile Communication (GSM), the PCM lines from the GSM chipset may be directly wired to the Bluetooth chip's PCM audio lines. You might then have to configure the Bluetooth chip to receive and send SCO audio packets over its HCI interface instead of its PCM interface.
bash> hcidump -i hci0 HCIDump - HCI packet analyzer ver 1.11 device: hci0 snap_len: 1028 filter: 0xffffffff HCI Command: Inquiry (0x01|0x0001) plen 5 HCI Event: Command Status (0x0f) plen 4 HCI Event: Inquiry Result (0x02) plen 15 ... HCI Event: Inquiry Complete (0x01) plen 1 < HCI Command: Remote Name Request (0x01|0x0019) plen 10 ...
The virtual HCI driver (hci_vhci.ko), as shown in Figure 16.2, emulates a Bluetooth interface if you do not have actual hardware.
Bluetooth applications fall under different profiles based on how they behave. For example, the cordless telephony profile specifies how a Bluetooth device can implement a cordless phone. We discussed profiles for PAN and serial access, but there are many more profiles out there such as fax profile, General Object Exchange Profile (GOEP) and SIM Access Profile (SAP). The bluez-utils package, downloadable from www.bluez.org, provides support for several Bluetooth profiles.
The official Bluetooth website is www.bluetooth.org. It contains Bluetooth specification documents and information about the Bluetooth Special Interest Group (SIG).
Affix is an alternate Bluetooth stack on Linux. You can download Affix from http://affix.sourceforge.net/.