HCI is the protocol of the interaction between a device and its Bluetooth subsystem.
Other parts of the specification tell what is transmitted over the air. For example, the radio specification tells which frequencies to use, the baseband specification which packets to send to start an inquiry or for making a device entering a piconet, L2CAP and RFCOMM tell how to establish a channel for sending a file, etc.
HCI tells how the computer and the USB Bluetooth dongle interact.
computer <---> dongle <--------------------> mobile HCI radio specification baseband L2CAP RFCOMM OBEX ...
HCI is not about what is transmitted over the air between the computer and the mobile; this is covered by the other parts of the Bluetooth specification. HCI is about the communication between the computer and the dongle. More generally, it tells how a device and its Bluetooth subsytem interact. It does not give any additional constraint about what is transmitted over the air; therefore, a fully functional Bluetooth device can be realized even if such an interaction does not follow the HCI protocol.
Four kinds of packets are exchanged between the host (e.g., the computer) and the host controller (e.g., the USB Bluetooth dongle):
+--------+------+---------+---------+-----+---------+ | opcode | plen | param_1 | param_2 | ... | param_n | +--------+------+---------+---------+-----+---------+
Possible commands:
In case of error, the dongle answer with a 1-byte error code.
+------------+------+---------+---------+-----+---------+ | event code | plen | param_1 | param_2 | ... | param_n | +------------+------+---------+---------+-----+---------+
plen: overall size of parameters, in bytes
Possible events:
Each contains the handle of the connection (see below).
Each contains the handle of the connection, as for the ACL packets.
Each connection is identified by a 12-bit integer handle. The computer sends a create_connection command to the dongle, and if it is successful the handle is returned by a connection_complete event.
The Bluetooth specification tells not only how the HCI packets (events and commands) are structured, but also how to send and receive them over USB (or over UART, 3-wire, etc.) In the case of an USB Bluetooth dongle, the four types of HCI packets (HCI commands, HCI events, ACL and SCO packets) are distinguished by device endpoint:
Endpoint | Packet type |
---|---|
0x00 | HCI commands |
0x81 | HCI events |
0x02 | ACL outgoing packets |
0x82 | ACL incoming packets |
0x03 | SCO outgoing packets |
0x83 | SCO incoming packets |
In Linux, a program can directly interact with the HCI layer using sockets (the library functions described in the linux Bluetooth programming page offer a better solution). For example:
dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); sa.hci_family = AF_BLUETOOTH; sa.hci_dev = 0; // 0 for hci0 sa.hci_channel = HCI_CHANNEL_RAW; bind(dd, (struct sockaddr *) sa, sizeof(sa));
The four packet types are all read from or written to the socket dd using the standard functions read, write, etc. The first byte in the read or written buffer tells the type of the packet:
First byte | Packet type |
---|---|
0x01 | HCI command |
0x04 | HCI event |
0x02 | ACL packet |
0x03 | SCO packet |
Some useful Linux programs: