Showing posts with label Bluetooth. Show all posts
Showing posts with label Bluetooth. Show all posts

Sunday, March 6, 2011

Bug in hcidump

Try to run the following command:
  $ sudo hcidump -i aaa
Instead of giving an error that there is no device with a name "aaa", hcidump uses the "hci0" device. The first thing that comes to mind is maybe hcidump uses "hci0" device by default if the specified device not found, but when I try to run the following:
  $ sudo hcidump -i aaa123
It gives an error:
  Can't open device: No such device
So what is the reason of such behavior. To find out it, I review the argument parsing part of the source code (as hcidump is open source) and find out the following.
To download the source code of hcidump (version 1.42, used in Ubuntu 10.10) 
  $ git clone git://git.kernel.org/pub/scm/bluetooth/bluez-hcidump.git  # get the sources
  $ git checkout -b new 1.42                                    # get the version 1.42

The code of input arguments parsing is located in file "src/hcidump.c" starting at line 1002. The device name's parsing code is located between 1004 1010 lines:


As you can see the reason of the unusual behavior is in the following line:
    device = atoi(optarg + 3);
which didn't check the correctness of input (work for "hci[0-9]" like names only).

Thursday, March 3, 2011

How to build the latest hcidump.

In the previous article the "hcidump" was used for dumping bluetooth protocol packets. The binary package of "hcidump" is exists for Ubuntu and other widespread Linux distribution, but what about other distributions. For them we need to compile and install it from sources. So the following instructions will be useful:

1)Download the source code from the official site or checkout sources from repository. We will choose the second one, because it contains the latest patches and changes (sometime new bugs :( also ). "hcidump" uses Git source control system, so the git package is needed (Ubuntu: sudo apt-get install git). To check-out the sources run the following
$git clone git://git.kernel.org/pub/scm/bluetooth/bluez-hcidump.git

2)Enter "bluez-hcidump" directory. Now you need to configure the sources and then build them. It uses GNU build system, so we need to follow standard steps.
GNU build system(source: Wikipedia).
Before compiling ensure that you have the latest "BlueZ" library installed.
Steps: 
$ aclocal                                     # Generate "aclocal.m4" file
$ autoheader                              # Generate "config.h.in"
$ autoconf                                  # Generate "configre" file
$ automake --add-missing          # Generate "Makefile.in" file and add missing files
$ ./configure                               # Configure
$ make                                        # Build hcidump
$ make install                             # Install

Now you have the latest hcidump tool.

Monday, February 28, 2011

Bluetooth HCI

There are various protocols used in Bluetooth. One of them is the HCI(Host/Controller interface) protocol, which is used in the communication between the host stack(BlueZ or Affix) and the controller(Bluetooth chip). Today using the "scanner" program from the previous article and the "hcidump" tool we will see how the HCI protocol packets look like. The "hcidump" tool dumps HCI data coming from and going to a Bluetooth controller (Ubuntu users can install it by "sudo apt-get install bluez-hcidump"). To view dumped files we need the wireshark program also (Ubuntu users: sudo apt-get install wireshark).
Run hcidump in background mode and then run the "scanner"
$ sudo hcidump -i hci0 -w dump &
$ ./scanner

By the -i option Bluetooth device is specified and by the -w option the output file is specified.
When "scanner" finish, kill the background hcidump and then open "dump" file with wireshark program:
WireShark 
In the screenshot you can see two type of HCI packets: HCI_CMD -- computer sends commands to the controller and HCI_EVT -- the controller sends the result. The info column of HCI_CMD packets shows the command sent within a packed. Two type of commands shown in screenshot: "Inquiry" (op code: 0x0401) and "Remote Name Request" (op code: 0x0419). They are the commands sent when the "hci_inquiry" and the "hci_read_remote_name" functions where called(see the source code of "scanner").

The selected packet is a description of the device find by the scanner (as we can see from the fields "BD_ADDR" and "Class of Device" it is a Nokia mobile phone).

Sunday, February 27, 2011

Linux and Bluetooth

There are 2 widespread Bluetooth stack implementations in Linux: BlueZ and Affix. Today we will use the BlueZ library for writing a simple "nearby device finder" program. Before you start, make sure you have installed the necessary Bluetooth packages. Ubuntu users can install them by running:
    sudo apt-get install bluez libbluetooth-dev
At first we need to include the following BlueZ header files
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

To work with a Bluetooth device we need a device id, which can be retrieved by "hci_get_route"  function: if pass NULL argument to "hci_get_route", it will return the id of first available device, or -1 if there isn't any. Now we can use "hci_get_route" function, which search the nearby Bluetooth devices and return basic information about them in a "inquiry_info" structure:
typedef struct {
  bdaddr_t  bdaddr;
  uint8_t   pscan_rep_mode;
  uint8_t   pscan_period_mode;
  uint8_t   pscan_mode;
  uint8_t   dev_class[3];
  uint16_t  clock_offset;
} __attribute__ ((packed)) inquiry_info;

The "bdaddr" member contains the address of a device (it is like a MAC address of network devices, by the way they have the same syntax).
There are 2 functions to convert between strigns and "bdaddr_t" structures.
int str2ba( const char *str, bdaddr_t *ba );
int ba2str( const bdaddr_t *ba, char *str );
The address of remote Bluetooth device is enough to work with it, but the end users usually work with the device names. The "hci_read_remote_name" function retrieve the name of remote device using it's address. But "hci_open_dev" require an open socket. The "hci_open_dev" function opens an appropriate Bluetooth socket. And at last we can use "hci_open_dev" function to get the name and address of the local Bluetooth device.
See the source code for details: