Version 20 (modified by 19 months ago) ( diff ) | ,
---|
- Goals
-
Bluetooth
- Bluetooth Versions
- Bluetooth Low Energy (BLE)
- Bluetooth Controller Hardware
- Gateworks BSP Support
- Software (Linux)
-
Bluetooth Profiles
- Serial Port Profile (SP)
- Headset Profile (HSP)
- Handsfree Profile (HFP)
- Human Interface Device Profile (HID)
- Personal Area Network Device Profile (PAN)
- Object Push Profile (OPP)
- File Transfer Profile (FTP)
- Advanced Audio Distribution Profile (A2DP)
- Generic Access Protocol GAP
- Generic Attribute Profile GATT
-
Common Commandline Tools and Operations
- Configuring Bluetooth Controller (hciconfig)
- UART based HCI configuration (hciattach)
- Discoverability (hciconfig)
- Scanning for Bluetooth devices available for pairing (hcitool)
- Pinging a device to test its connection (l2ping)
- Open A Connection (hcitool)
- Link Quality (hcitool)
- Bluetooth Service Discovery Protocol (SDP) (sdptool)
- Pairing and bonding (Setting up connections)
- Writing code supporting Bluetooth
- iBeacon
Goals
The main objective of this page is to describe Bluetooth from a Linux perspective and provide some general notes for specific applications such as reading a Bluetooth serial device or connecting to a Bluetooth HID.
Bluetooth
Bluetooth is a wireless protocol for short distances which encompasses the obvious benefit of low power. There is a concept of a Master device and a Slave device which is synonymous to infrastructure mode in 802.11a/b/g/n/ac (i.e. AP with several STA's). There can be a maximum of 7 active devices connected to the Master, but can have a total of 255 inactive connections. This Bluetooth network is called a Piconet. However, there are several options on how a Bluetooth network can be configured, several of which will be discussed below in the software section. There also exist several Bluetooth protocols which are defined by the Bluetooth SIG organization. This Wikipedia entry has a complete list of protocols. In order to fully appreciate the flexibility Bluetooth has to offer, the next few sections will be dedicated to these protocols and how to gain access to them.
All Bluetooth devices (both controllers and endpoints), like Ethernet devices, have a unique 6-byte MAC address.
Common Terminology:
- stack - Refers to the software that implements the Bluetooth protocols
- device - a Bluetooth end-point device
- controller - Refers to the host controller attached to the CPU that can talk to bluetooth devices
Bluetooth Versions
Which version is used is dependent on the Hardware used as well as software. Be sure to check the specifications of the radio / device being used.
- Bluetooth 4.0
- Added Bluetooth Low Energy (BLE) protocol
- Bluetooth 5.0
- 4x the range ov Bluetooth 4.x (with lower throughput)
- 2x the datarate of 4.x (1Mbps to 2Mbps)
- Advertising packets move to 255 bytes
- More advertising channels
Bluetooth Low Energy (BLE)
Also called Bluetooth LE, BLE, and Bluetooth Smart.
This is primarily used for data sensing, and not intended for continuous data-rate applications such as streaming audio or video. This enables new-use cases like beacons and sensors that have low-bandwidth periodic and sporodic data points. This also brings lower power to some use cases such as human interface devices (keyboard and mouse) input that is sporadic in nature, greatly increasing battery life for those devices.
Bluetooth Low Energy is much lower power than classic Bluetooth, possibly lasting months on a coincell. BLE is also cheaper for each peripheral devices.
BLE has many defined profiles, including specific profiles for the healthcare industry, sports and fitness and more. These are all based on the Generic Attribute Profile (GATT).
Bluetooth 4.x+ Devices will support Bluetooth Classic (aka BR/EDR) and/or Bluetooth Low Energy. Be away they may not support both and if you have a device that supports 'only' BLE it will not be able to use audio streaming such as the A2DP profile as support for BR/EDR is required for that.
Bluetooth Controller Hardware
Gateworks has used and tested the following USB based controllers.
USB based (btusb)
Their is a large variety of USB based Bluetooth controllers supported by the btusb
kernel driver. Here are some common ones that Gateworks has tested:
- Pluggable USB-BT4LE: USB ID 0a5c:21e8 Broadcom BCM20702A0
- CSR 4.0 (CSR8510 A10 Bluetooth USB host): USB ID 0a12:0001
- Available from various vendors for <$10
- Intel 7260HWM - MiniPCIe form-factor 802.11ac / Bluetooth 4.0:
- Firmware: ibt-hw-37.7.10-fw-1.80.2.3.d.bseq should be placed in /lib/firmware/intel/. For OpenWrt the driver/firmware is provided by the kmod-btusb kernel module package and the ibt-firmware package which are installed by default in our Ventana BSP since r621
- Main Ant is Wifi
- Aux Ant is Wifi + Bluetooth
- Canyon CN-BTU1: USB ID 0c10:0000
Laird Sterling onboard Bluetooth
- Find all Laird Sterling information on this dedicated wiki page: expansion/on-board-wireless
Gateworks BSP Support
Gateworks supports multiple Board Support Packages. The following table shows details on bluetooth support for each:
BSP | Product Families | Drivers | Stack |
---|---|---|---|
Yocto | Ventana | btusb/hciuart | bluez4 |
Android | Ventana | btusb | bluez5 |
OpenWrt | Ventana / Newport | btusb/hciuart/bnep/rfcomm | bluez5 |
ubuntu | Ventana | btusb/hciuart/bnep/rfcomm | bluez5 |
OpenWrt
Gateworks OpenWrt supports Bluetooth via BlueZ 5.x
The following packages are installed by default on Gateworks firmware images:
- btusb and bluetooth core kernel drivers
- bluez-utils (bluetooth daemon and utils)
- bluez-libs (bluetooth lib)
- kmod-bluetooth (hci_uart, btusb, rfcomm, bnep, bluetooth, hidp, ath3k)
By default dbus-daemon and bluetooth daemon (hcid) are running and the controller is powered up with ISCAN and PSCAN enabled (discovery enabled) and the name is configured as 'OpenWrt' (the system hostname).
The dbus-send
application is not installed by default (it is included in the dbus-util) package if you wish to install it, and no passkey agent is installed by default.
OpenWrt supports UCI configuration for the Bluetooth daemon storing its configs in /etc/config/bluetooth
. The default configuration provides:
- hcid: enabled by default (controller discoverable via 'iscan enable; pscan enable' in /etc/bluetooth/hcid.conf)
- hciattach: disabled by default
- rfcomm: disabled by default
- dund: disabled by default
- pand: disabled by default
The Gateworks OpenWrt BSP default firmware image provides support for the following:
- most common USB based based BT controllers (via btusb, ath3k, btintel drivers)
- HCI core protocol kernel support (HCI/L2CAP/SMP/SCO)
- RFCOMM/BNPEP/HIDP kernel support
- hciconfig/hcitool/sdptool/bluetoothd/rfcomm applications and daemones
- scan/pair/discovery of bluetooth devices
- Serial Port Profile (SP) via rfcomm app
- Personal Area Network (PAN) Profile via pand app
Yocto 1.8
Gateworks Yocto 1.8 BSP supports Bluetooth via BlueZ 4.101. Note that Yocto 1.3 also supported BlueZ 4 but the Yocto 1.6 and 1.7 BSP's do not have bluetooth enabled in the kernel.
The following packages are installed by default on Gateworks firmware images:
- btusb and bluetooth core kernel drivers
- bluez4 (bluetoothd daemon, libs, and utils)
- bluez4-testtools
- bluez-hcidump
- gstreamer1.0-plugins-bad-bluze
- libasound-module-bluez
The Gateworks Yocto 1.8 BSP default firmware images provides support for the following:
- most common USB based based BT controllers (via btusb, ath3k, btintel drivers)
- HCI core protocol kernel support (HCI/L2CAP/SMP/SCO)
- RFCOMM/BNPEP/HIDP kernel support
- hciconfig/hcitool/sdptool/bluetoothd/rfcomm applications and daemones
- scan/discovery of bluetooth devices
- Serial Port Profile (SP) via rfcomm app
- Human Interface Device (HID) Profile via hidd dbus-send
By default the Bluetooth daemon (bluetoothd) is not running as there is no default init script. The dbus-send
application exists and can be used for establishing HID connections. No passkey agent is installed by default for pairing (see how to install the pyton test tools for the bluez-simple-agent below).
To run bluetoothd:
bluetoothd
Installing Extra Bluetooth Packages
Depending on your needs, you may also need to install the test tools that are missing from the Yocto bluez package (and patch them to use the version of python-object installed on Yocto). This will add support for:
- Personal Area Network (PAN) Profile (test-nap & test-network)
- Simple Pairing agent (simple-agent)
mkdir -p /usr/local/bin for i in simple-agent simple-service test-adapter test-audio test-device test-discovery test-input test-manager test-nap test-network test-oob test-serial; do \ wget "http://git.kernel.org/cgit/bluetooth/bluez.git/plain/test/${i}?h=4.101" -O /usr/local/bin/bluez-${i}; \ sed -i 's/from gi.repository import GObject/import gobject/' /usr/local/bin/bluez-${i}; \ sed -i 's/mainloop = GObject.MainLoop/mainloop = gobject.MainLoop/' /usr/local/bin/bluez-${i}; \ chmod +x /usr/local/bin/bluez-${i}; \ done
- On Ubuntu for example, these are packaged in the 'bluez' package already
If you are interested in using OBEX/FTP/OPP for binary file transfers you may want to build and install the obexftp
and/or openobex
Yocto packages.
Ubuntu 14.04
Ubuntu 14.04 uses the BlueZ 4.x stack and provides the following packages related to bluetooth:
- bluez - core bluetooth daemon, utils and python test scripts (You will need to also install python-gobject and python-dbus if you wish to use the python test scripts)
- bluez-compat - pand, hidd, dund for backwards compatibility with BlueZ 3 instructions and methods
- bluez-btsco - Bluetooth SCO tool
- bluez-cups - Bluetooth printer driver for CUPS
- bluez-hcidump - Analyses Bluetooth HCI packets
- bluez-tools - An alternative set of tools to manage bluetooth devices for linux (not documented here)
- bluez-alsa - ALSA plugin for A2DP profile
- bluez-gstreamer - GStreamer plugin for A2DP profile
- pulseaudio-module-bluetooth - Bluetooth module for PulseAudio sound server (not documented here)
- obexfs - mount filesystem of devices supporting OBEX FTP profile
- obexftp - file transfer utility and daemon for devices supporting OBEX FTP profile
- obexpushd - program for receiving files via OBEX OPP profile
For example:
- to install all bluetooth related packages (174MB on top of a base Ubuntu system as described in ventana/ubuntu):
apt-get install bluez bluez-compat bluez-alsa bluez-gstreamer bluez-utils bluez-tools python-gobject python-dbus
- if you want the minimize you can just install bluez (which does depend on dbus, systemd, and python among some others) (14.9MB on top of a base Ubuntu system as described in ventana/ubuntu):
apt-get install bluez
With the bluetooth packages above installed this allows for the following support:
- most common USB based based BT controllers (via btusb, ath3k, btintel drivers)
- HCI core protocol kernel support (HCI/L2CAP/SMP/SCO)
- RFCOMM/BNPEP/HIDP kernel support
- hciconfig/hcitool/sdptool/bluetoothd/rfcomm applications and daemones
- scan/discovery of bluetooth devices
- Serial Port Profile (SP) via rfcomm app
- Human Interface Device (HID) Profile via hidd/dbus-send/bluez-test-input
- Personal Area Network (PAN) Profile via pand app
- File Transfer Protocol (FTP) Profile via obexftp and obxfs
- Object Push Profile (OOP) via obexpushd
- Advanced Audio Distribution Profile (A2DP) via bluez-alsa
Android
The Gateworks Android BSP replaces the standard Android Bluetooth 'bluedroid' stack with BlueZ. Please see Android Bluetooth for details on Android Bluetooth support.
Software (Linux)
A Bluetooth stack refers to the software that implements the protocol layers. This software can reside in the Linux kernel as well as userspace.
BlueZ (Standard Linux)
BlueZ is the Open Source Linux bluetooth protocol stack implemented in userspace using the Linux Bluetooth HCI core drivers. It also provides several tools for managing your Bluetooth connections, whether you're acting as a Slave (device) or Master (controller). BlueZ offers support for multiple Bluetooth devices, security, and several other features. It also provides several Protocols, or "Profiles", such as PAN, HID, and A2DP. The upcoming sections will discuss software generally compiled when building BlueZ
BlueZ general features:
- flexible, efficient, modular architecture
- support for multiple Bluetooth devices
- multithreaded
- hardware abstraction
- standard socket interface to all layers
BlueZ consists of:
- Linux kernel side:
- Bluetooth Core:
- HCI (Host Controller Interface) device and connection manager, schedule
- SCO (Synchronous Connection Oriented) audio links
- L2CAP (Logical Link Control and Adaptation Protocol)
- SMP (Security Manager Protocol) on LE (Low Energy) links
- HCI Device drivers (Interface to the hardware)
- USB (btusb)
- UART (hciuart)
- SDIO
- RFCOMM (RFCOMM Protocol for serial communication) Module (creates /dev/rfcomm serial devices)
- BNEP (Bluetooth Network Encapsulation Protocol) Module (creates /sys/class/net/bnep network interfaces)
- CMTP (CAPI Message Transport Protocol) Module
- HIDP (Human Interface Device Protocol) Module (creates /sys/class/input devices)
- Bluetooth Core:
- Userspace side:
- config and test utilities
Various linux distros will package BlueZ in a number of packages:
- bluez - Bluetooth tools and daemons
- bluez-alsa - Bluetooth ALSA support
- bluez-btsco - Bluez Bluetooth SCO tool
- bluez-cups - Bluetooth printder driver for CUPS
- bluez-gstreamer - Bluetooth GStreamer support
- bluez-hcidump - Analyze Bluetooth packets
- bluez-tools - manage Bluetooth devices
While Bluez5 is the current stable release many Linux distros including Ubuntu 14.04, Gateworks Yocto 1.8 BSP still use Bluez4. See above regarding which Gateworks BSP's have what version of BlueZ
Recent BlueZ Version history:
- BlueZ 5: Dec 2012
- use standard D-Bus Properties and ObjectManager interfaces
- different (and incompatible) D-Bus API (see the BlueZ 5 API porting-guide)
- introduction of interface versions
- simplification or removal of per-profile interfaces and the addition of a general org.bluez.Device1.Connect method
- removal of org.bluez.Service interface
- Dynamic device object creation during discovery
- Introduction of an AgentManager1 interface
- base path moved to "/org/bluez"
- bluez-4.0: Aug 2008:
- merged bluez-libs and bluez-utils together
- main daemon now called bluetoothd (instead of hcid)
- main config file is /etc/bluetoth/main.conf following an INI-style syntax
- GLib no longer optional (eglib support fully removed)
- old D-Bus API from 3.x series fully removed
Linux Kernel Drivers
The Linux Kernel defines a Bluetooth Host Controller Interface (HCI) for communication between hardware kernel drivers and userspace applications.
Several Linux kernel drivers implement a standard bluetooth HCI API in the form of a device node and ioctls. Each of these drivers implements support for a specific HCI presenting and a list of them can be found in /sys/class/bluetooth/hci*
The more standard HCI device drivers can be broken down into the following:
- USB based HCI's (typically added to a system by the user) - linux/drivers/bluetooth/btusb.c usually built as the btusb.ko kernel module
- UART based HCI's (typically embedded onto a board) - linux/drivers/bluetooth/btuart_cs.c usually build as the btuart.ko kernel module
- SDIO based HCI's (typically embedded onto a board) - drivers/bluetooth/btsdio.c usually built as the btsdio.ko kernel module
- addition drivers exist in drivers/bluetooth for specific hardware implmentaitons
While Gateworks does not currently have bluetooth HCI's directly on its boards, our customers often add USB based HCI's in the form of miniPCIe combo cards (see hardware section below) or USB form-factor peripherals.
You can see what Bluetooth controllers are registered with the kernel by looking at the /sys/class/bluetooth
directory:
# ls /sys/class/bluetooth
hci0
BlueZ 5.x
The Bluez5 bluetooth daemon (/usr/lib/bluez5/bluetooth/bluetoothd) runs in the background and the bluetoothctl
application provides a Command Line Interface (CLI) to the daemon to perform all device and controller management.
NOTE: Bluez5 is not properly configured in Gateworks OpenWrt 16.02.
A typical session may look like this:
- Use
list
to list available controllers, andselect <mac>
to select one - Turn the power on to a controller via
power on
(its off by default) - Enable device discovery mode for the selected controller with
scan on
(its off by default)- New devices will be presented as they are found
- Periodic messages will appear for each device found along with its signal strength (RSSI)
- You can list current devices with the
devices
command - Turn the pairing agent on with the
agent on
command - Pair a device via
pair <mac>
- If using a device without a PIN, you man need to manually trust the device before it can reconnect successfully. To do so use
trust <mac>
- If using a device without a PIN, you man need to manually trust the device before it can reconnect successfully. To do so use
- Establish a connection to the device via
connect <mac>
Note that while in the CLI:
- Tab completion works
- Periodic asynchonous/unsolicited messages will appear for devices being scanned while scanning is on
Examples:
- Pairing and connecting an HID keyboard:
bluetoothctl [NEW] Controller 00:06:C6:FF:AD:1A ventana-0 [default] [bluetooth]# list Controller 00:06:C6:FF:AD:1A ventana-0 [default] [bluetooth]# show 00:06:C6:FF:AD:1A Controller 00:06:C6:FF:AD:1A Name: BlueZ 5.28 Alias: ventana-0 Class: 0x000000 Powered: yes Discoverable: no Pairable: yes UUID: PnP Information (00001200-0000-1000-8000-00805f9b34fb) UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb) UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb) UUID: A/V Remote Control (0000110e-0000-1000-8000-00805f9b34fb) UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb) UUID: Handsfree (0000111e-0000-1000-8000-00805f9b34fb) Modalias: usb:v1D6Bp0246d051C Discovering: no [bluetooth]# select 00:06:C6:FF:AD:1A [bluetooth]# scan on Discovery started [CHG] Controller 00:06:C6:FF:AD:1A Discovering: yes [NEW] Device 54:46:6B:01:7B:2B 54-46-6B-01-7B-2B [CHG] Device 54:46:6B:01:7B:2B LegacyPairing: no [CHG] Device 54:46:6B:01:7B:2B Name: Bluetooth FAVI [CHG] Device 54:46:6B:01:7B:2B Alias: Bluetooth FAVI [bluetooth]# devices Device 54:46:6B:01:7B:2B Bluetooth FAVI [bluetooth]# pair 54:46:6B:01:7B:2B Attempting to pair with 54:46:6B:01:7B:2B Failed to pair: org.bluez.Error.ConnectionAttemptFailed [bluetooth]# pair 54:46:6B:01:7B:2B Attempting to pair with 54:46:6B:01:7B:2B [CHG] Device 54:46:6B:01:7B:2B Connected: yes [CHG] Device 54:46:6B:01:7B:2B Modalias: usb:v0A5Cp8502d011B [CHG] Device 54:46:6B:01:7B:2B UUIDs: 00001000-0000-1000-8000-00805f9b34fb 00001124-0000-1000-8000-00805f9b34fb 00001200-0000-1000-8000-00805f9b34fb [CHG] Device 54:46:6B:01:7B:2B Paired: yes Pairing successful [CHG] Device 54:46:6B:01:7B:2B Connected: no [bluetooth]# connect 54:46:6B:01:7B:2B Attempting to connect to 54:46:6B:01:7B:2B [ 2178.501028] Bluetooth: HIDP (Human Interface Emulation) ver 1.2 [ 2178.507023] Bluetooth: HIDP socket layer initialized [CHG] Device 54:46:6B:01:7B:2B Connected: yes Connection successful
- If using a device without a PIN you can manually trust the device in order to connect:
[bluetooth]# trust 54:46:6B:01:7B:2B
To bring up a bluetooth controller (HCI) on boot, you can use a udev rule such as:
- /etc/udev/rules.d/10-local.rules
# bring up bluetooth host controller ACTION=="add", KERNEL=="hci0", RUN+="/usr/bin/hciconfig hci0 up"
After a suspend/resume cycle you can use a systemd service to bring the controller back up:
- /etc/systemd/system/bluetooth-auto-power@.service
[Unit] Description=Bluetooth auto power on After=bluetooth.service sys-subsystem-bluetooth-devices-%i.device suspend.target [Service] Type=oneshot ExecStart=/usr/bin/hciconfig %i up [Install] WantedBy=suspend.target
Configuration:
- bluetooth daemon configuruation is in /etc/bluetooth/main.conf:
- AutoEnable=true in [Policy] section will bring up HCI on startup
- bluetooth dbus configuration is in /etc/dbus-1/system.d/bluetooth.conf (can specify group there, defaults to lp group)
Notes:
- must turn power on to controller by entering 'power on' (off by default) or by using hciconfig up
- enter device desovery mode with 'scan on'
- tab completion works in CLI
- to pair, the bluetooth device must be in pairing mode (consult devices documentation). Typically this involves pressing or holding a button for a few seconds and results in a blinking blue LED to indicate the device is in pairing mode. Pairing typically stops after a minute or so depending on the device
References:
BlueZ 4.x
BlueZ 4.x was released in Aug 2008 with the following major changes over BlueZ 3.x:
- Merged bluez-libs and bluez-utils together
- Main daemon now called bluetoothd (instead of hcid)
- Main config file is /etc/bluetooth/main.conf following an INI-style syntax
- GLib no longer optional (eglib support fully removed)
- Old D-Bus API from 3.x series fully removed
- New D-Bus API is defined in doc/network-api.txt
The standard userpsace tools are:
- bluetoothd - Bluetooth Daemon that manages all Bluetooth devices and configured via /etc/bluetooth/main.conf. Provides a number of services via D-Bus message bus system
- hcitool
- hciattach
- hciconfig
- l2ping
- l2test
- sdptool
some distros (ie Ubuntu) will provide a set of bluetooth compatibility binaries in a bluez-compat
package that provide the following tools which were removed from bluez4:
- Personal Area Network (PAN) networking daemon
- Dial-Up Networking daemon
- Bluetooth HID daemon
Configuration:
- /etc/init/bluetooth.conf - bluetooth daemon init
- /etc/bluetooth/main.conf - main bluetooth daemon config
- name of device (when discoverable)
- /etc/bluetooth/input.conf - configuration of the input service
- /etc/bluetooth/audio.conf - configuration of the audio service (SCO routing: PCM or HCI)
- /etc/bluetooth/network.conf - configuration of the network service (link encryption)
- /etc/bluetooth/rfcomm.conf - configuration of rfcomm layer
- /etc/bluetooth/serial.conf - configuration of serial (DUN tty, UID)
BlueZ 3.x
BlueZ 3.x has the following features:
- uses dbus and system.d configured via /etc/dbus-1/system.d/bluetooth.conf
- D-Bus API is defined in doc/network-api.txt
- bluetooth daemon (hidc)
- /etc/bluetooth/hcid.conf daemon configuration
The standard userspace tools are:
- hcid - Bluetooth Daemon that manages all Bluetooth devices and configured via /etc/bluetooth/hcid.conf. Provides a number of services via D-Bus message bus system
- hciconfig/hcitool/hciattach - HCI configuration tools
- l2ping - Layer2 ping utility
- sdptool - SDP browser
- hidd - Human Interface Devices (HID) daemon
- pand - Personal Area Network (PAN) networking daemon
- dund - Dial-up networking daemon
D-Bus Message Bus System
The BlueZ stack uses the D-Bus message bus system which is a simple way for applications to talk to one another.
BlueZ 4 D-Bus API
The BlueZ 4 D-Bus API is defined in doc/network-api.txt. Some example usage using dbus-send
:
- First you need to get the path to the bluetooth controller you wish to use. We will assign it to a shell env variable and export it for future use:
export BTADAPTER=`dbus-send --system --dest=org.bluez --print-reply / org.bluez.Manager.DefaultAdapter | tail -1 | sed 's/^.*"\(.*\)".*$/\1/'`
- To introspect with you can use something like:
# dbus-send --system --dest=org.bluez --print-reply $BTADAPTER org.freedesktop.DBus.Introspectable.Introspect
- To make your controller discoverable:
# dbus-send --system --dest=org.bluez --print-reply $BTADAPTER org.bluez.Adapter.SetProperty string:Discoverable variant:boolean:true
- To disable discovery:
# dbus-send --system --dest=org.bluez --print-reply $BTADAPTER org.bluez.Adapter.SetProperty string:Discoverable variant:boolean:false
- To list paired devices:
# dbus-send --system --dest=org.bluez --print-reply $BTADAPTER org.bluez.Adapter.ListDevices
- To trust a device:
dbus-send --system --dest=org.bluez --print-reply $BTADAPTER/dev_54_46_6B_01_7B_2B org.bluez.Device.SetProperty string:Trusted variant:boolean:true
- To connect to an HID device (must pair first and can see the path above):
# dbus-send --system --dest=org.bluez --print-reply $BTADAPTER/dev_54_46_6B_01_7B_2B org.bluez.Input.Connect [ 2710.946655] Bluetooth: HIDP (Human Interface Emulation) ver 1.2 [ 2710.952642] Bluetooth: HIDP socket layer initialized method return sender=:1.3 -> dest=:1.13 reply_serial=2 root@ventana:~# [ 2711.352289] hid-generic 0005:0A5C:8502.0001: unknown main item tag 0x0 [ 2711.359234] input: Bluetooth FAVI as /devices/soc0/soc.0/2100000.aips-bus/2184000.usb/ci_hdrc.0/usb1/1-1/1-1:1.0/bluetooth/hci0/hci0:42/0005:0A5C:8502.0001/input/input1 [ 2711.374829] hid-generic 0005:0A5C:8502.0001: input: BLUETOOTH HID v1.1b Keyboard [Bluetooth FAVI] on 00:15:83:3d:0a:57 evtest /dev/input/event1
BlueDroid (Android)
While Android used to use the standard Linux BlueZ stack, in 4.2.2 it switched to its own native stack called BlueDroid.
For Android Bluetooth details please see the Android wiki pages.
Bluetooth Profiles
In order to use Bluetooth a device must be compatible with a subset of Bluetooth profiles for specific services. These profiles sit on top of the Bluetooth Core specification and protocols.
The way a device uses Bluetooth technology depends on its profile capabilities. The profiles provide standards which manufacturers follow to allow devices to be compatible.
A full list of profiles can be found here however here are some common ones are described in detail in the sections below
Serial Port Profile (SP)
The Serial Port Profile is based on ETSI 07.10 and the RFCOMM protocol. It emulates a serial cable to provide a simple substitude for existing RS-232 including control signals. This is the basis for DUN, FAX, HSP and AVRCP profiles. SPP maximum payload capacity is 128 bytes.
An example of a device using this profile would be a Bluetooth GPS device.
The Linux kernel has an RFCOMM driver that ties into the bluetooth stack and registers /dev/rfcomm<n> device nodes when necessary.
Use the rfcomm
utility from the bluez package to listen for or connect so bluetooth connections. It is not necessary to be paired or trusted in this case.
For example, to create a serial link between two Linux systems:
- Machine1: SP server
# hciconfig hci0 piscan # make us discoverable # hciconfig hci0 -a hci0: Type: BR/EDR Bus: USB BD Address: 00:02:72:C9:56:47 ACL MTU: 1021:8 SCO MTU: 64:1 UP RUNNING PSCAN ISCAN RX bytes:7258 acl:121 sco:0 events:203 errors:0 TX bytes:4561 acl:119 sco:0 commands:91 errors:0 Features: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87 Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 Link policy: RSWITCH SNIFF Link mode: SLAVE ACCEPT Name: 'ventana-0' Class: 0x000100 Service Classes: Unspecified Device Class: Computer, Uncategorized HCI Version: 4.0 (0x6) Revision: 0x1000 LMP Version: 4.0 (0x6) Subversion: 0x220e Manufacturer: Broadcom Corporation (15) # sdptool add SP --channel=1 # advertise an SP service record for channel 1 # rfcomm listen hci0 1 # listen on hci0 for SP requests on channel 1 (cntl-C to exit) Waiting for connection on channel 1
- Machine2: SP client
# hciconfig hci0 up # hcitool scan Scanning ... 00:02:72:C9:56:47 ventana-0 # sdptool search SP Inquiring ... Searching for SP on 00:02:72:C9:56:47 ... Service Name: Serial Port Service Description: COM Port Service Provider: BlueZ Service RecHandle: 0x10000 Service Class ID List: "Serial Port" (0x1101) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 1 Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "Serial Port" (0x1101) Version: 0x0100 # rfcomm connect hci0 00:02:72:C9:56:47 1 Press CTRL-C for hangup
- once a connection is established the
rfcomm
processes on both the client and server will display 'Press CTRL-C for hangup' at which point they will create a/dev/rfcomm0
node that can be used with any terminal application. When you wish to close the connection kill the rfcomm process. - terminal characterists such as baudrate and line control have no effect on rfcomm devices
- once a connection is established the
You can configure the bluetooth daemon to bind to a device on startup via /etc/bluetooth/rfcomm.conf
. For example:
For example:
rfcomm0 { # Automatically bind the device at startup bind no; # Bluetooth address of the device device 00:11:22:33:44:55; # RFCOMM channel for the connection (check your GPS docs for details) channel 1; # Description of the connection comment "Bluetooth GPS"; }
Restart the Bluetooth daemon or services following this change:
# /etc/init.d/bluetoothd restart
You should now be able to bind the GPS to /dev/rfcomm0 like this:
# rfcomm bind 0
And you can confirm the connection:
# rfcomm rfcomm0: 00:11:22:33:44:55 channel 1 clean
Now you can use /dev/rfcomm0
like any other serial device (ie 'stty', 'screen', etc):
# stty -F /dev/rfcomm0 115200 # set baudrate # cat /dev/rfcomm0 $GPGGA,111748.000,5907.6964,N,01121.1787,E,1,06,1.2,57.7,M,40.1,M,,0000*6F $GPRMC,111748.000,A,5907.6964,N,01121.1787,E,0.00,94.94,160807,,,A*50 $GPVTG,94.94,T,,M,0.00,N,0.0,K,A*3D
References:
Headset Profile (HSP)
The Headset Profile (HSP) was encoropred in the initial Bluetooth specification for mono headsets. If a microphone is present on a stereo headphone device, it uses HSP for the audio channel. HSP uses a RFCOMM channel for control based on standard AT commands with bluetooth specific extensions for volume control and accept/reject buttons. The transport for audio is an SCO channel which allows a single (mono) 8kHz PCM encoded using Continuous Variable Slope Delta (CVSD) modulation amounting to 64kbps. This audio transferred over SCO can be provided to the HCI hardware driver (typical) or in highly embedded applications directly to an audio codec chip via a PCM back-channel depending on the bluetooth chipset.
Handsfree Profile (HFP)
The Handsfree profile (HFP) is a more advanced version of HSP but also designed for mono headsets. It adds support for additional remote functions such as dialing and later versions add optional support for better-quality mono audio using the SBC codec.
Human Interface Device Profile (HID)
The Human Interface Device Profile (HID) is implemented with a kernel module (hidp) that registers a Linux Input device upon request from the bluetooth daemon.
Configuration of HID depends upon the version of BlueZ (see BSP table above). In general the HID device must be paired with (or trusted) and the bluetooth daemon must register it for use with the hidp
kernel module which creates a Linux Input device that can be seen in /sys/class/input
.
Notes:
- BT HID devices (ie keyboard or mouse) and controllers (HCI) need to be paired once. See Pairing for more details.
- Once connected a
/dev/input/event<n>
device node will be registered and can be used for Linux Input events as long as the connection persists. - You can test the connection (if connected through a TTY session) by running a tool such as
evtest
orevent_test
which will show you events on Linux Input devices.
BlueZ 5:
- The
bluetoothctl
utility allows for HID's to connect to the Bluetooth adapter. This provides a Command Line Interface (CLI):# bluetoothctl [NEW] Controller 00:06:C6:FF:AD:1A ventana-0 [default] [bluetooth]# power on Changing power on succeeded [CHG] Controller 00:06:C6:FF:AD:1A Powered: yes [bluetooth]# scan on Discovery started [CHG] Controller 00:06:C6:FF:AD:1A Discovering: yes [NEW] Device 54:46:6B:01:7B:2B 54-46-6B-01-7B-2B [CHG] Device 54:46:6B:01:7B:2B LegacyPairing: no [CHG] Device 54:46:6B:01:7B:2B Name: Bluetooth FAVI [CHG] Device 54:46:6B:01:7B:2B Alias: Bluetooth FAVI [bluetooth]# devices Device 54:46:6B:01:7B:2B Bluetooth FAVI [bluetooth]# pair 54:46:6B:01:7B:2B Attempting to pair with 54:46:6B:01:7B:2B [CHG] Device 54:46:6B:01:7B:2B Connected: yes [CHG] Device 54:46:6B:01:7B:2B Modalias: usb:v0A5Cp8502d011B [CHG] Device 54:46:6B:01:7B:2B UUIDs: 00001000-0000-1000-8000-00805f9b34fb 00001124-0000-1000-8000-00805f9b34fb 00001200-0000-1000-8000-00805f9b34fb [CHG] Device 54:46:6B:01:7B:2B Paired: yes Pairing successful [CHG] Device 54:46:6B:01:7B:2B Connected: no [bluetooth]# connect 54:46:6B:01:7B:2B Attempting to connect to 54:46:6B:01:7B:2B [ 2178.501028] Bluetooth: HIDP (Human Interface Emulation) ver 1.2 [ 2178.507023] Bluetooth: HIDP socket layer initialized [CHG] Device 54:46:6B:01:7B:2B Connected: yes Connection successful [bluetooth]# exit
BlueZ 4:
- Using D-Bus via the
dbus-send
to interact withbluetoothd
(requires pairing):# hciconfig hci0 up # hcitool -i hci0 scan Scanning ... 54:46:6B:01:7B:2B Bluetooth FAVI # sdptool search HID # search for and show all discoverable devices advertising an HID service Inquiring ... Searching for HID on 54:46:6B:01:7B:2B ... Service Name: Broadcom Bluetooth Wireless Keyboard Service Description: Keyboard Service Provider: Broadcom Corp. Service RecHandle: 0x10000 Service Class ID List: "Human Interface Device" (0x1124) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 17 "HIDP" (0x0011) Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "Human Interface Device" (0x1124) Version: 0x0100 # bluez-simple-agent hci0 54:46:6B:01:7B:2B # request pairing (specify pin code when requested then enter this code followed by a Enter on the keyboard to pair) RequestPinCode (/org/bluez/471/hci0/dev_54_46_6B_01_7B_2B) Enter PIN Code: 0000 Release New device (/org/bluez/471/hci0/dev_54_46_6B_01_7B_2B) # export BTADAPTER=`dbus-send --system --dest=org.bluez --print-reply / org.bluez.Manager.DefaultAdapter | tail -1 | sed 's/^.*"\(.*\)".*$/\1/'` # get the adapter path # dbus-send --system --dest=org.bluez --print-reply $BTADAPTER org.bluez.Adapter.ListDevices # list paired adapters # dbus-send --system --dest=org.bluez --print-reply $BTADAPTER/dev_54_46_6B_01_7B_2B org.bluez.Input.Connect # connect to an adapter method return sender=:1.3 -> dest=:1.8 reply_serial=2 [ 2710.946655] Bluetooth: HIDP (Human Interface Emulation) ver 1.2 [ 2710.952642] Bluetooth: HIDP socket layer initialized [ 2711.352289] hid-generic 0005:0A5C:8502.0001: unknown main item tag 0x0 [ 2711.359234] input: Bluetooth FAVI as /devices/soc0/soc.0/2100000.aips-bus/2184000.usb/ci_hdrc.0/usb1/1-1/1-1:1.0/bluetooth/hci0/hci0:42/0005:0A5C:8502.0001/input/input1 [ 2711.374829] hid-generic 0005:0A5C:8502.0001: input: BLUETOOTH HID v1.1b Keyboard [Bluetooth FAVI] on 00:15:83:3d:0a:57 evtest /dev/input/event1
- Using D-Bus via
bluez-test-input
python script (requires pairing):# hciconfig hci0 up # hcitool -i hci0 scan Scanning ... 54:46:6B:01:7B:2B Bluetooth FAVI # bluez-simple-agent hci0 54:46:6B:01:7B:2B # request pairing (specify pin code when requested then enter this code followed by a Enter on the keyboard to pair) RequestPinCode (/org/bluez/471/hci0/dev_54_46_6B_01_7B_2B) Enter PIN Code: 0000 Release New device (/org/bluez/471/hci0/dev_54_46_6B_01_7B_2B) # bluez-test-input connect 54:46:6B:01:7B:2B [ 1654.853401] Bluetooth: HIDP (Human Interface Emulation) ver 1.2 [ 1654.859353] Bluetooth: HIDP socket layer initialized [ 1655.633452] hid-generic 0005:0A5C:8502.0001: unknown main item tag 0x0 [ 1655.640391] input: Bluetooth FAVI as /devices/soc0/soc.0/2100000.aips-bus/2184000.usb/ci_hdrc.0/usb1/1-1/1-1:1.0/bluetooth/hci0/hci0:12/0005:0A5C:8502.0001/input/input1 [ 1655.655952] hid-generic 0005:0A5C:8502.0001: input: BLUETOOTH HID v1.1b Keyboard [Bluetooth FAVI] on 00:02:72:c9:56:47
- Use
hidd
from thebluez-compat
package to connect (see below) - In all of the above cases the kernel has registered a new input device input1 (/sys/class/input/input1, /dev/input/event1)
BlueZ 3:
- Use
hidd
from thebluez
package to connect (does not require pairing, or more specifically performs automatic pairing for you):# hciconfig hci0 up # hcitool -i hci0 scan # show all discverable devices Scanning ... 54:46:6B:01:7B:2B Bluetooth FAVI # sdptool search HID # search for and show all discoverable devices advertising an HID service Inquiring ... Searching for HID on 54:46:6B:01:7B:2B ... Service Name: Broadcom Bluetooth Wireless Keyboard Service Description: Keyboard Service Provider: Broadcom Corp. Service RecHandle: 0x10000 Service Class ID List: "Human Interface Device" (0x1124) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 17 "HIDP" (0x0011) Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "Human Interface Device" (0x1124) Version: 0x0100 # hidd --connect 54:46:6B:01:7B:2B [28013.797391] Bluetooth: HIDP (Human Interface Emulation) ver 1.2 [28013.798954] Bluetooth: HIDP socket layer initialized [28018.300685] hid-generic 0005:0A5C:8502.0001: unknown main item tag 0x0 [28018.309052] input: Broadcom Bluetooth Wireless Keyboard as /devices/soc0/soc.0/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.0/bluetooth/hci0/hci0:40/0005:0A5C:8502.0001/input/input5 [28018.309767] hid-generic 0005:0A5C:8502.0001: input: BLUETOOTH HID v1.1b Keyboard [Broadcom Bluetooth Wireless Keyboard ] on 00:15:83:6b:e2:bd
- use
hidd unplug <bdaddr>
to disconnect the HID connection - use
hidd kill <bdaddr>
to kill the HID connection - use
hidd show
to show all HID connections - use
hidd search
to search for HID devices in range and automatically connect to them - use
-i <hciX|bdaddr>
to specify the bluetooth controller
- use
Personal Area Network Device Profile (PAN)
The Personal Area Network Device Profile (PAN) allows encapsulating IP over bluetooth using the Bluetooth Network Encapsulation Protocol (BNEP). The kernel bnep module (CONFIG_BT_BNEP) is responsible for registering a bnep<n> network interface when requested by the Bluetooth daemon. You do not need to use pairing for PAN connections. Once a PAN connection is active and you have a bnep<n> interface you can use standard networking tools to configure and/or bridge the interface.
There are three PAN roles:
- NAP - Network Access Point
- PANU - PAN User (client to a PAN NAP)
- GN - Group Network (adhoc based)
Configuration of PAN depends upon the version of BlueZ (see BSP table above).
BlueZ 5:
- Using D-Bus via a bt-pan python script and the
bluetoothctl
CLI (requires python, python-dbus):- Machine1: server / NAP
# bluetoothctl [NEW] Controller 00:02:72:C9:56:47 BlueZ 5.37 [default] [bluetooth]# power on Changing power on succeeded [CHG] Controller 00:02:72:C9:56:47 Powered: yes [bluetooth]# discoverable on Changing discoverable on succeeded [CHG] Controller 00:02:72:C9:56:47 Discoverable: yes [bluetooth]# agent on Agent registered [bluetooth]# default-agent Default agent request successful [NEW] Device 00:15:83:3D:0A:57 yocto18-0 Request PIN code [agent] Enter PIN code: 0000 [CHG] Device 00:15:83:3D:0A:57 Paired: yes [CHG] Device 00:15:83:3D:0A:57 Connected: no [bluetooth]# paired-devices Device 00:15:83:3D:0A:57 yocto18-0 [bluetooth]# trust 00:15:83:3D:0A:57 [CHG] Device 00:15:83:3D:0A:57 Trusted: yes Changing 00:15:83:3D:0A:57 trust succeeded [bluetooth]# exit Agent unregistered [DEL] Controller 00:02:72:C9:56:47 BlueZ 5.37 [default] # sdptool add NAP # advertise NAP service # brctl addbr br0 # wget https://raw.githubusercontent.com/mk-fg/fgtk/master/bt-pan # chmod +x bt-pan # ./bt-pan --debug server br0 & DEBUG:root:Using local device (addr: 00:02:72:C9:56:47): /org/bluez/hci0 DEBUG:root:Registered uuid 'nap' with bridge/dev: br0 / 00:02:72:C9:56:47 # ifconfig br0 br0 Link encap:Ethernet HWaddr 00:02:72:c9:56:47 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) # brctl show br0 bridge name bridge id STP enabled interfaces br0 8000.000272c95647 no bnep0
- first we used
bluetoothctl
to bring up the controller, make it discoverable, and pair with and trust the client. Next we created a bridge, fetched the bt-pan python script and used it to resiter a NAP server which registers a bnep0 network interface with Linux upon successful connection with a PANU client. The bnpeg0 network interface will be added to the bridge. Make sure you use standard networking tools to configure the bridge as desired.
- first we used
- Machine2: client / PANU
# bluetoothctl [NEW] Controller 00:02:72:C9:56:47 BlueZ 5.37 [default] [bluetooth]# power on Changing power on succeeded [bluetooth]# discoverable on Changing discoverable on succeeded [CHG] Controller 00:02:72:C9:56:47 Discoverable: yes [bluetooth]# agent on Agent registered [bluetooth]# default-agent Default agent request successful [NEW] Device 00:15:83:6B:E2:BD ventana-trusty-0 Request confirmation [agent] Confirm passkey 744563 (yes/no): yes [CHG] Device 00:15:83:6B:E2:BD UUIDs: 0000110c-0000-1000-8000-00805f9b34fb [CHG] Device 00:15:83:6B:E2:BD UUIDs: 0000110e-0000-1000-8000-00805f9b34fb [CHG] Device 00:15:83:6B:E2:BD UUIDs: 00001112-0000-1000-8000-00805f9b34fb [CHG] Device 00:15:83:6B:E2:BD UUIDs: 00001116-0000-1000-8000-00805f9b34fb [CHG] Device 00:15:83:6B:E2:BD UUIDs: 0000111e-0000-1000-8000-00805f9b34fb [CHG] Device 00:15:83:6B:E2:BD UUIDs: 0000111f-0000-1000-8000-00805f9b34fb [CHG] Device 00:15:83:6B:E2:BD UUIDs: 0000112d-0000-1000-8000-00805f9b34fb [CHG] Device 00:15:83:6B:E2:BD Paired: yes [CHG] Device 00:15:83:6B:E2:BD Connected: no [bluetooth]# trust 00:15:83:6B:E2:BD [CHG] Device 00:15:83:6B:E2:BD Trusted: yes Changing 00:15:83:6B:E2:BD trust succeeded [bluetooth]# exit Agent unregistered [DEL] Controller 00:02:72:C9:56:47 BlueZ 5.37 [default] root@xenial:~# bluetoothctl [NEW] Controller 00:02:72:C9:56:47 BlueZ 5.37 [default] [NEW] Device 00:15:83:6B:E2:BD ventana-trusty-0 [bluetooth]# paired-devices Device 00:15:83:6B:E2:BD ventana-trusty-0 [bluetooth]# exit [DEL] Controller 00:02:72:C9:56:47 BlueZ 5.37 [default] # sdptool search NAP Inquiring ... Searching for NAP on 00:15:83:6B:E2:BD ... Service Name: Network Access Point Service Description: BlueZ PAN Service Service Provider: BlueZ PAN Service RecHandle: 0x10006 Service Class ID List: "Network Access Point" (0x1116) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 15 "BNEP" (0x000f) Version: 0x0100 SEQ16: 800 806 Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "Network Access Point" (0x1116) Version: 0x0100 # wget https://raw.githubusercontent.com/mk-fg/fgtk/master/bt-pan # chmod +x bt-pan # ./bt-pan --debug client 00:15:83:6B:E2:BD DEBUG:root:Using local device (addr: 00:02:72:C9:56:47): /org/bluez/hci0 DEBUG:root:Using remote device (addr: 00:15:83:6B:E2:BD): /org/bluez/hci0/dev_00_15_83_6B_E2_BD DEBUG:root:Connected to network (dev_remote: /org/bluez/hci0/dev_00_15_83_6B_E2_BD, addr: 00:15:83:6B:E2:BD) uuid 'nap' with iface: bnep0 DEBUG:root:Finished root@xenial:~# ifconfig bnep0 bnep0 Link encap:Ethernet HWaddr 00:02:72:c9:56:47 inet6 addr: fe80::202:72ff:fec9:5647/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:4 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:16 (16.0 B) TX bytes:148 (148.0 B)
- first we used
bluetoothctl
to pair with and trust the client. Next we fetched the bt-pan python script and used it to connect to the client which registers a bnep0 network interface with Linux upon successful connection with a NAP server. Make sure you use standard networking tools to configure the bridge as desired.
- first we used
- Machine1: server / NAP
BlueZ 4:
- Using the
pand
tool from thebluez-compat
package (see below)- to use the
pand
application for BlueZ 4.x you must disable the internal network plugin in its bluetooth daemon. To do this add a 'DisablePlugins=network' to /etc/bluetooth/main.conf under the [General] section and restart the bluetooth daemon)
- to use the
- Using the
bt-network
application from thebluez-tools
package (requires pairing):- Machine1: server / NAP:
# hciconfig hci0 up # bring up controller # hciconfig hci0 piscan # make discoverable # brctl addbr br0 # add a bridge # bt-network --server nap br0 # run NAP service NAP server registered
- Machine2: client / PANU:
# hciconfig hci0 up # bring up controller # hciconfig hci0 piscan # make discoverable # sdptool search NAP # search for NAP service # bt-network --connect 00:02:72:C9:56:47 nap &
- Machine1: server / NAP:
BlueZ 3:
- Using the
pand
tool from thebluez
package:- to use the
pand
application for BlueZ 4.x you must disable the internal network plugin in its bluetooth daemon. To do this add a 'DisablePlugins=network' to /etc/bluetooth/main.conf under the [General] section and restart the bluetooth daemon) - Machine1: server / NAP:
# hciconfig hci0 up # bring up bluetooth controller # hciconfig hci0 piscan # make discoverable # pand --listen --role NAP --master
- Once connected to a PANU you will see a message such as
pand[872]: New connection from 00:15:83:3D:0A:57 at bnep0
- Once connected to a PANU you will see a message such as
- Machine2: client / PANU:
# hciconfig hci0 up # bring up bluetooth controller # hcitool -i hci0 scan # show all discoverable bluetooth devices Scanning ... 00:15:83:6B:E2:BD ventana-trusty-0 # sdptool search NAP # show all discoverable bluetooth devices advertising NAP service Inquiring ... Searching for NAP on 00:15:83:6B:E2:BD ... Service Name: Network Access Point Service Description: BlueZ PAN Service Service Provider: BlueZ PAN Service RecHandle: 0x10008 Service Class ID List: "Network Access Point" (0x1116) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 15 "BNEP" (0x000f) Version: 0x0100 SEQ16: 800 806 Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "Network Access Point" (0x1116) Version: 0x0100 # pand --connect 00:15:83:6B:E2:BD --service NAP --nodetach pand[717]: Bluetooth PAN daemon version 4.101 pand[717]: Connecting to 00:15:83:6B:E2:BD pand[717]: bnep0 connected
- You can remove the
--nodetach
to run as a daemon (in which case you won't see the pand messages on the console indicating the connection status) - You can use
pand --role PANU --search
to search for and auto-connect to the first NAP server found:# pand --role PANU --search --nodetach pand[723]: Bluetooth PAN daemon version 4.101 pand[723]: Inquiring pand[723]: Searching for NAP on 00:15:83:6B:E2:BD pand[723]: Connecting to 00:15:83:6B:E2:BD pand[723]: bnep0 connected
- to use the
- Using D-Bus messages via
dbus-send
:- Machine1: server / NAP:
export BTADAPTER=`dbus-send --system --dest=org.bluez --print-reply / org.bluez.Manager.DefaultAdapter | tail -1 | sed 's/^.*"\(.*\)".*$/\1/'` # get the adapter path dbus-send --system --dest=org.bluez --print-reply $BTADAPTER org.bluez.NetworkHub.SetProperty string:Enabled variant:boolean:true
- Machine1: server / NAP:
Object Push Profile (OPP)
The Object Push Profile (OPP) is used to send binary data objects. An OPP server is needed to receive files via OPP. OOP defines the roles of 'push server' and 'push client':
- Push Server - the device that provides an object exchange server.
- Push Client - the device that pushes and pulls objects to and from the Push Server.
You can use the obexpushd
tool to create an OPP Push Server and listen for incoming files. You can use the obexftp
tool as a Push Client to send files to a Push Server.
Devices do not need to be previously paired for the OPP profile. Note that the FTP profile is much more capable profile.
Android devices:
- Several Android applications can use OPP to push files to a device with an OPP Push Server. For example, Google photos and the Google Camera app use this when you select the 'share icon' when viewing an image followed by the 'Bluetooth' icon (at which point it will show you all bluetooth devices that provide an OPP Push server)
- There are several applications in the Google Play Store that provide the ability to push files to an 'OBEX OPP' server such as 'Bluetooth File Transfer' by Medieval Software: Note that by default this application enables an OOP and an FTP server without authentication (but pairing is required) while the app is running.
Examples:
- Discover devices providing a Push Server:
# sdptool search OPUSH
- Receive a file via
obexpushd
:# hciconfig hci0 piscan # make sure we are discoverable # obexpushd -B5 -o /tmp -n # start Push Server on bluetooth channel 9 using /tmp as a directory store obexpushd 0.11.2 Copyright (C) 2006-2010 Hendrik Sattler This software comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. Warning: local character set is not Unicode. Listening on bluetooth/[00:00:00:00:00:00]:5 Creating file "/tmp/0001.patch" ^C
- remove the
-n
to run in the background - above shows a file accepted called 00001.patch
- remove the
- Binary file transfer to a device providing an OBEX OPP Push server using
obexftp
:# sdptool search OPUSH Inquiring ... Searching for OPUSH on 00:15:83:6B:E2:BD ... Service Name: OBEX Object Push Service Description: a free OBEX server Service Provider: obexpushd Service RecHandle: 0x10006 Service Class ID List: "OBEX Object Push" (0x1105) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 5 "OBEX" (0x0008) Profile Descriptor List: "OBEX Object Push" (0x1105) Version: 0x0100 # obexftp --bluetooth 00:15:83:6B:E2:BDE --channel 5 --put file.pdf Connecting..\done Tried to connect for 129ms Sending "file.pdf".../done Disconnecting..-done
File Transfer Profile (FTP)
Provides the capability to browse, manipulate and transfer objects (files and folders) in an object store (file system) of another system. This uses GOEP as a basis.
You can use this with the obexftp
and obexfs
Linux tools when paired with the right service:
- obexftp - a file transfer protocol client using the OBEX FTP profile
- obexfs - a FUSE-based filesystem that uses the OBEX FTP profile to connect to an OBEX server
Devices need to be previously paired (see pairing).
Android devices:
- There are several applications in the Google Play Store that provide an 'OBEX FTP' server:
- 'Bluetooth File Transfer' by Medieval Software: Note that by default this application enables an OOP and an FTP server without authentication (but pairing is required) while the app is running.
Examples:
- Discover devices providing a FTP service:
# sdptool search FTP
- List available files on a device providing an OBEX FTP service using
obexftp
:# sdptool search FTP # search for devices advertising FTP profile Inquiring ... Searching for FTP on 98:E7:F5:A1:A1:EE ... Service Name: OBEX FTP Service RecHandle: 0x1000d Service Class ID List: UUID 128: 00001106-0000-1000-8000-00805f9b34fb Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 6 # obexftp --bluetooth 98:E7:F5:A1:A1:EE --channel 6 --list
- Delete a file from a device providing an OBEX FTP service using
obexftp
:# sdptool search FTP # search for devices advertising FTP profile Inquiring ... Searching for FTP on 98:E7:F5:A1:A1:EE ... Service Name: OBEX FTP Service RecHandle: 0x1000d Service Class ID List: UUID 128: 00001106-0000-1000-8000-00805f9b34fb Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 6 # obexftp --bluetooth 98:E7:F5:A1:A1:EE --channel 6 --delete
- Binary file transfer to a device providing an OBEX FTP service using
obexftp
:# sdptool search FTP # search for devices advertising FTP profile Inquiring ... Searching for FTP on 98:E7:F5:A1:A1:EE ... Service Name: OBEX FTP Service RecHandle: 0x1000d Service Class ID List: UUID 128: 00001106-0000-1000-8000-00805f9b34fb Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 6 # obexftp --bluetooth 98:E7:F5:A1:A1:EE --channel 6 --put file.pdf Connecting..\done Tried to connect for 129ms Sending "file.pdf".../done Disconnecting..-done
- Binary file transfer from a device providing an OBEX FTP service using
obexftp
:# sdptool search FTP # search for devices advertising FTP profile Inquiring ... Searching for FTP on 98:E7:F5:A1:A1:EE ... Service Name: OBEX FTP Service RecHandle: 0x1000d Service Class ID List: UUID 128: 00001106-0000-1000-8000-00805f9b34fb Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 6 # obexftp --bluetooth 98:E7:F5:A1:A1:EE --channel 6 --get file.pdf Connecting..\done Tried to connect for 60ms Receiving "file.pdf".../done Disconnecting..-done
- Run an OBEX FTP server using
obexftpd
:# hciconfig hci0 piscan # make us discoverable # cd /tmp # obexftpd -b5 # start OBEX FTP server via bluetooth channel 5
- Mount a filesystem from an 'OBEX FTP' service using
obexfs
:# sdptool search FTP # search for devices advertising FTP profile Inquiring ... Searching for FTP on 98:E7:F5:A1:A1:EE ... Service Name: OBEX FTP Service RecHandle: 0x1000d Service Class ID List: UUID 128: 00001106-0000-1000-8000-00805f9b34fb Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 6 # obexfs --bluetooth 98:E7:F5:A1:A1:EE --channel 6 /mnt # mount | grep obexfs obexfs on /mnt type fuse.obexfs (rw,nosuid,nodev) # ls /mnt Alarms LinkLocalStorage Notifications UnityAdsVideoCache file.pdf Android Logs Pictures camera-p.jpg games DCIM Movies Podcasts docs panoramas Download Music Ringtones foo
Note that the obexftp
application also supports pushing files to an OBEX OPP server (see above).
Advanced Audio Distribution Profile (A2DP)
The Advanced Audio Distribution Profile (A2DP) is a bluetooth profile that many devices support and is what is used for high fidelity headphone stereo audio. All stereo headphones support A2DP and AVRCP. The Logical Link Controller and Adaptation Protocol (L2CAP) is used in conjunction with the Audio/Video Distribution Transport Protocol (AVDTP) for control and streaming audio. This defines a binary protocol and binary streaming protocol based on RTP. A royalty free Subband-codec (SBC) is included i n the A2DP spec as a mandatory protocol but it is possible for BT devices to also optionally support MP3, AAC or other codecs.
The quality of audio sent to a wireless headphone is determined by the codec. After the audio source (ie phone) selects the appropriate profile it chooses a codec which the audio sink (ie headhpone) the decodes for playback. Although it is theoretically possible to send mp3's or any other digital format straight to the headphones over Bluetooth instead the A2DP profile specifies its own set of audio codecs:
- SBC (Subband Coding) - the mandatory default codec for A2DP supported by all Bluetooth stereo devices. It was deisgned to provide reasonably good audio quality over the limited bandwidth of Bluetooth without heavy processing requirements. SBC is capable of bitrates up to about 328kbps at 44.1kHz sampling which is not far off from the maximum for mp3 encoding though mp3 is superior to SBC in terms of audio quality given similar bitrates. SBC is also capable of mid and low quality streams which sound quite compressed to the ears and are unacceptable for music streaming and sound quality varies widly between different SBC implementations.
- aptX is a proprietary audio codec developed for demanding audio applications designed to encode CD-quality (16bit 44.1kHz) or better (up to 24bit 96kHz) without loss of quality using a slightly higher data rate but more efficient compared to SBC. The aptX codec is not required by A2DP and currently aptX is only supported by CSR chipsets typically used in high-end Android devices. Both the headphone and the source must support aptX and if not the default SBC codec will be used instead. Currently aptX support is limited to mostly high-end Android smartphones and Hi-Fi wireless devices.
- AAC (Advanced Audio Coding) is a popular codec in general designed to achieve better sound quality than mp3 at similar bit rates. Unlike aptX it is supported by iOS devices (Apple implements AAC over bluetooth at about 250kbps) which should compete in fidelity. Support for AAC is not common in bluetooth devices.
Requirements:
- userspace bluteooth-alsa libs (libasound_module_{pcm,ctl}_bluetooth.so) (Ubuntu: bluez-alsa, Yocto: libasound-module-bluez)
The process to connect Bluetooth A2DP devices differs based on the version of the BlueZ stack you are using as well as the audio back-end that you are using:
- ALSA: bluez-alsa (Ubuntu) / libasound-module-bluez (Yocto) package providing libasound_module_{pcm,ctl}_bluetooth.so
- GStreamer: bluez-gstreamer (Ubuntu) providing libgstbluetooth.so / gstreamer1.0-plugins-bad-bluez (Yocto) providing libgstbluez.so
- PulseAudio: pulseaudio-module-blueeooth (Ubuntu) providing module-bluetooth-{policy,device,discover,proximity}.so
BlueZ 4.x / ALSA:
- Using Bluetooth headphones to playback audio from Linux device (Linux device is an A2DP Source and connecting to an A2DP Sink)
- Identify (put headphones into pairing mode)
# hcitool scan Scanning ... A4:15:66:5B:B9:79 Motorola Buds # sdptool search A2SNK Inquiring ... Searching for A2SNK on A4:15:66:5B:B9:79 ... Service Provider: AVExtension_Device Service RecHandle: 0x10002 Service Class ID List: "Audio Sink" (0x110b) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 25 "AVDTP" (0x0019) uint16: 0x0100 Profile Descriptor List: "Advanced Audio" (0x110d) Version: 0x0100
- Pair
# bluez-simple-agent hci0 A4:15:66:5B:B9:79 RequestPinCode (/org/bluez/506/hci0/dev_A4_15_66_5B_B9_79) Enter PIN Code: 0000 Release New device (/org/bluez/391/hci0/dev_A4_15_66_5B_B9_79)
- refer to your headset documentation for the correct PIN (0000 shown above or 1234 is typical)
- Bluetooth audio configuration:
- Make sure you have 'Source' and 'Media' enabled under [General] in /etc/bluetooth/audio.conf:
# sed 's/#Disable=\(.*\)/Enable=Source,Sink,Headset,Gateway,Control,Socket,Media/' /etc/bluetooth/audio.conf -i # enable all modules
- Restart the bluetooth daemon
- Make sure you have 'Source' and 'Media' enabled under [General] in /etc/bluetooth/audio.conf:
- bluetooth-alsa configuration: Configure a 'btheadset' audio device:
# cat <<EOT >/etc/asound.conf pcm.btheadset { type plug slave { pcm { type bluetooth device A4:15:66:5B:B9:79 profile "auto" } } hint { show on description "BT Headset" } } ctl.btheadset { type bluetooth } EOT
- You should now be able to play audio to the paired headset via ALSA:
- For example with the
aplay
tool from thealsa-utils
package:# aplay -D btheadset /usr/share/sounds/alsa/Front_Center.wav # play
- or mplayer:
# mplayer -ao alsa:device=btheadset /usr/share/sounds/alsa/Front_Center.wav
- In order to get your headet's multimedia buttons (play,pause,next,previous) you need to create /etc/modules-load.d/uinput.conf containing uinput
- For PulseAudio you need to have PulseAudio installed (pulseaudio-module-blueeooth) and have the PulseAudio sound server started:
pulseaudio --start
and do not need to have /etc/asound.conf configured
- For example with the
References:
- https://www.kernel.org/doc/ols/2008/ols2008v1-pages-193-196.pdf
- http://theheadphonelist.com/wireless-fidelity-making-sense-bluetooth-headphone-technology/
Generic Access Protocol GAP
Protocol when devices are continuously advertising and there is no bonded connection. Example: temperature sensor advertising its value.
Two device roles:
- Central - device such as Gateworks SBC
- Peripheral - device such as a temperature sensor
Packets are 31 bytes.
Generic Attribute Profile GATT
Generic Attribute Profile (GATT) is used for Bluetooth Low Energy communication. This for a dedicated connection between two devices after GAP has already been completed. A BLE peripheral can only be connected to on central device at a time.
GATT has the following:
- Client - A device who initates a GATT command or request. Ex: Gateworks SBC
- Server - A device that receives GATT requests and then responds. Ex: Temperature Sensor
- Characteristic - A data value, such as a battery voltage
- Service - Collection of Characteristics
- Descriptor - Additional information for a characteristic.
- Identifiers - a UUID for services, descriptors, and characteristics.
- Notifications - Client can be notified when a characteristic changes on a server. Avoids the need for the client to poll the server
- Indication - The same as a notification, but the client must confirm to the server it received the message.
Using GATT with BlueZ 5.x with the gatttool
:
- Example: Controlling a MagicHue Bluetooth Smart Candle:
root@bionic-newport:~# timeout 5s hcitool lescan LE Scan ... 3C:A3:08:10:51:FE LEDBlue-081051FE root@bionic-newport:~# gatttool -i hci0 -b 3C:A3:08:10:51:FE --primary attr handle = 0x0001, end grp handle = 0x000b uuid: 00001800-0000-1000-8000-00805f9b34fb attr handle = 0x000c, end grp handle = 0x000f uuid: 00001801-0000-1000-8000-00805f9b34fb attr handle = 0x0010, end grp handle = 0x0022 uuid: 0000180a-0000-1000-8000-00805f9b34fb attr handle = 0x0023, end grp handle = 0x0033 uuid: 0000ffe5-0000-1000-8000-00805f9b34fb attr handle = 0x0034, end grp handle = 0x0044 uuid: 0000ffe0-0000-1000-8000-00805f9b34fb attr handle = 0x0045, end grp handle = 0xffff uuid: 0000fff0-0000-1000-8000-00805f9b34fb root@bionic-newport:~# gatttool -i hci0 -b 3C:A3:08:10:51:FE --characteristics handle = 0x0002, char properties = 0x02, char value handle = 0x0003, uuid = 00002a00-0000-1000-8000-00805f9b34fb handle = 0x0004, char properties = 0x02, char value handle = 0x0005, uuid = 00002a01-0000-1000-8000-00805f9b34fb handle = 0x0006, char properties = 0x0a, char value handle = 0x0007, uuid = 00002a02-0000-1000-8000-00805f9b34fb handle = 0x0008, char properties = 0x08, char value handle = 0x0009, uuid = 00002a03-0000-1000-8000-00805f9b34fb handle = 0x000a, char properties = 0x02, char value handle = 0x000b, uuid = 00002a04-0000-1000-8000-00805f9b34fb handle = 0x000d, char properties = 0x20, char value handle = 0x000e, uuid = 00002a05-0000-1000-8000-00805f9b34fb handle = 0x0011, char properties = 0x02, char value handle = 0x0012, uuid = 00002a23-0000-1000-8000-00805f9b34fb handle = 0x0013, char properties = 0x02, char value handle = 0x0014, uuid = 00002a24-0000-1000-8000-00805f9b34fb handle = 0x0015, char properties = 0x02, char value handle = 0x0016, uuid = 00002a25-0000-1000-8000-00805f9b34fb handle = 0x0017, char properties = 0x02, char value handle = 0x0018, uuid = 00002a26-0000-1000-8000-00805f9b34fb handle = 0x0019, char properties = 0x02, char value handle = 0x001a, uuid = 00002a27-0000-1000-8000-00805f9b34fb handle = 0x001b, char properties = 0x02, char value handle = 0x001c, uuid = 00002a28-0000-1000-8000-00805f9b34fb handle = 0x001d, char properties = 0x02, char value handle = 0x001e, uuid = 00002a29-0000-1000-8000-00805f9b34fb handle = 0x001f, char properties = 0x02, char value handle = 0x0020, uuid = 00002a2a-0000-1000-8000-00805f9b34fb handle = 0x0021, char properties = 0x02, char value handle = 0x0022, uuid = 00002a50-0000-1000-8000-00805f9b34fb handle = 0x0024, char properties = 0x0a, char value handle = 0x0025, uuid = 0000ffe6-0000-1000-8000-00805f9b34fb handle = 0x0027, char properties = 0x0a, char value handle = 0x0028, uuid = 0000ffe7-0000-1000-8000-00805f9b34fb handle = 0x002a, char properties = 0x0a, char value handle = 0x002b, uuid = 0000ffe8-0000-1000-8000-00805f9b34fb handle = 0x002d, char properties = 0x04, char value handle = 0x002e, uuid = 0000ffe9-0000-1000-8000-00805f9b34fb handle = 0x0030, char properties = 0x0a, char value handle = 0x0031, uuid = 0000ffea-0000-1000-8000-00805f9b34fb handle = 0x0035, char properties = 0x0a, char value handle = 0x0036, uuid = 0000ffe1-0000-1000-8000-00805f9b34fb handle = 0x0038, char properties = 0x02, char value handle = 0x0039, uuid = 0000ffe2-0000-1000-8000-00805f9b34fb handle = 0x003b, char properties = 0x08, char value handle = 0x003c, uuid = 0000ffe3-0000-1000-8000-00805f9b34fb handle = 0x003e, char properties = 0x10, char value handle = 0x003f, uuid = 0000ffe4-0000-1000-8000-00805f9b34fb handle = 0x0042, char properties = 0x02, char value handle = 0x0043, uuid = 0000ffeb-0000-1000-8000-00805f9b34fb handle = 0x0046, char properties = 0x0a, char value handle = 0x0047, uuid = 0000fff1-0000-1000-8000-00805f9b34fb handle = 0x0049, char properties = 0x02, char value handle = 0x004a, uuid = 0000fff2-0000-1000-8000-00805f9b34fb handle = 0x004c, char properties = 0x08, char value handle = 0x004d, uuid = 0000fff3-0000-1000-8000-00805f9b34fb handle = 0x004f, char properties = 0x10, char value handle = 0x0050, uuid = 0000fff4-0000-1000-8000-00805f9b34fb handle = 0x0053, char properties = 0x02, char value handle = 0x0054, uuid = 0000fff5-0000-1000-8000-00805f9b34fb root@bionic-newport:~# gatttool -i hci0 -b 3C:A3:08:10:51:FE --char-write-req -a 0x002e -n 56ff000000f0aa # red Characteristic value was written successfully gatttool -i hci0 -b 3C:A3:08:10:51:FE --char-write-req -a 0x002e -n 5600ff0000f0aa # green Characteristic value was written successfully gatttool -i hci0 -b 3C:A3:08:10:51:FE --char-write-req -a 0x002e -n 560000ff00f0aa # blue Characteristic value was written successfully
- The specific handle (denoting the GATT service and characteristic) and its values were determined by enabling HCI logging on an Android device while using the MagicHue Android app then viewing the log in Wireshark to see what values were being changed. This 'reverse engineering' technique is fairly common and widely described on the Internet.
Common Commandline Tools and Operations
Several command-line tools and operations are consistent among the various versions of the BlueZ stack.
Configuring Bluetooth Controller (hciconfig)
The hciconfig
tool will allow you to identify and configure Bluetooth controllers. It is very similar to ifconfig in that it shows Bluetooth devices, their TX/RX bytes, MAC and some other relevant information. A Bluetooth device generally shows up as hciX where X is a zero-based number. That is, if there is only one Bluetooth adapter on your system, it would usually show up as hci0.
You can see the available Bluetooth controllers on a Linux system by looking in the /sys/class/bluetooth
directory:
# ls /sys/class/bluetooth
hci0
Example uses:
- show configuration for all controllers:
# hciconfig hci0: Type: BR/EDR Bus: USB BD Address: 2C:3D:4F:04:12:55 ACL MTU: 339:6 SCO MTU: 180:1 DOWN RX bytes:488 acl:0 sco:0 events:20 errors:0 TX bytes:82 acl:0 sco:0 commands:20 errors:0
- The above shows a single controller named 'hci0' with unique MAC of 2C:3D:4F:04:12:55 currently in the power down state
- bring up controller (if you don't have a bluetooth daemon that automatically does this for you):
hciconfig hci0 up
- If this fails with an error like
Operation not possible due to RF-kill
then you need to unblock it via a hardware button/gpio or use therfkill
utility to unblock it:rfkill unblock all
- If this fails with an error like
The hciconfig
command will show you the state of controllers as well (UP/DOWN, RUNNING, PSCAN, ISCAN). The Inquiry Scan (ISCAN) and Page Scan (PSCAN) settings determine device discover-ability (see discovery below).
UART based HCI configuration (hciattach)
The hciattach
tool is used to attach serial devices via UART HCI to the BlueZ stack.
This is useful for on-board Bluetooth controllers that are connected directly to a processor UART. Gateworks does not use any such controllers.
Discoverability (hciconfig)
Every Bluetooth end-point device and controller has a unique MAC address (also known as a BDADDR) and a name.
A Bluetooth device needs to be in discovery mode to show up in a scan. Refer to the device documentation for details. Typically this involves holding a button down (often the power on button) for several seconds and results in a flashing blue LED indicating the device is in pairing or discovery mode.
The hciconfig
command can be used to configure the discover-ability and the name of a bluetooth controller. A Bluetooth controller may start off in hidden mode and needs to be in the 'Inquiry Scan' state to be discoverable.
Examples:
- show state of 'Inquiry Scan' and 'Page Scan':
# hciconfig hci0
- enable 'Inquiry Scan' state:
# hciconfig hci0 iscan
- enable 'Page Scan' state:
# hciconfig hci0 pscan
- enable both 'Page Scan' and 'Inquiry Scan' states:
# hciconfig hci0 piscan
- disable discovery mode (be hidden):
# hciconfig hci0 noscan
The name that is shown with the MAC address of discovered nearby devices is configurable. For Linux Bluetooth controllers the name
sub-command will configure the controllers name. You can also specify this in the Bluetooth daemon's configuration file.
Examples:
- show the name of a controller:
# hciconfig hci0 name hci0: Type: BR/EDR Bus: SDIO BD Address: 00:06:C6:FF:AD:1A ACL MTU: 1021:7 SCO MTU: 120:6 Name: 'ventana-0'
- use the name instead of the device name:
# hciconfig ventana-0 hci0: Type: BR/EDR Bus: SDIO BD Address: 00:06:C6:FF:AD:1A ACL MTU: 1021:7 SCO MTU: 120:6 UP RUNNING PSCAN RX bytes:18030 acl:121 sco:0 events:910 errors:0 TX bytes:7916 acl:76 sco:0 commands:448 errors:0
- Set the name:
# hciconfig hci0 name "MyUCI" # hciconfig hci0 name hci0: Type: BR/EDR Bus: SDIO BD Address: 00:06:C6:FF:AD:1A ACL MTU: 1021:7 SCO MTU: 120:6 Name: 'MyUCI' # hciconfig MyUCI hci0: Type: BR/EDR Bus: SDIO BD Address: 00:06:C6:FF:AD:1A ACL MTU: 1021:7 SCO MTU: 120:6 UP RUNNING PSCAN RX bytes:18393 acl:123 sco:0 events:917 errors:0 TX bytes:8238 acl:79 sco:0 commands:450 errors:0
Scanning for Bluetooth devices available for pairing (hcitool)
The hcitool
app from the bluez package can also be used to scan for and connect to Bluetooth devices in the area as well as give you information as to their identity (user defined name) and signal quality.
Examples:
- Scan for nearby discoverable Bluetooth devices:
# hciconfig hci0 up # make sure controller is powered on # hcitool -i hci0 scan # shows MAC and name of nearby devices which are configured as discoverable Scanning .. 09:40:A4:45:B1:4B P6
- The above shows a single device found named 'P6' with a unique MAC address of '09:40:A4:45:B1:4B'
- Connects to a specific Bluetooth device and show its link quality
# hcitool cc 09:40:A4:45:B1:4B; hcitool lq 09:40:A4:45:B1:4B; hcitool con Link quality: 255 Connections: < ACL 09:40:A4:45:B1:4B handle 256 state 7 lm MASTER # hcitool con Connections: #
- The above connects to the device with the specified MAC address and shows the active connection link quality
- To scan for Bluetooth Low Energy devices, use the following command:
hcitool lescan
Pinging a device to test its connection (l2ping)
When a device has been discovered you can use l2ping
from the bluez package to test the connection. This requires you to know the unique MAC address of the device:
# l2ping 09:40:a4:45:b1:4b 0 bytes from 09:40:a4:45:b1:4b id 0 time 9.12ms 0 bytes from 09:40:a4:45:b1:4b id 1 time 52.33ms 0 bytes from 09:40:a4:45:b1:4b id 2 time 22.50ms 0 bytes from 09:40:a4:45:b1:4b id 3 time 25.92ms ^C4 sent, 4 received, 0% loss
- Use 'cntl-C' to stop the ping if you did not specify a -c parameter to limit the number of ping counts
- You can ping a device even if it is no longer responding to scanning (because its no longer in discovery mode) as long as the device is powered on
Open A Connection (hcitool)
Use hcitool
to open a connection between an HCI and a bluetooth device:
# hcitool cc 54:46:6B:01:7B:2B
Link Quality (hcitool)
Use hcitool
to open a connection and determine hte link quality of a connection:
# hcitool cc 54:46:6B:01:7B:2B; hcitool lq 54:46:6B:01:7B:2B; hcitool con
Bluetooth Service Discovery Protocol (SDP) (sdptool)
The Bluetooth Service Discovery Protocol (SDP) provides a means by which service applications running on different Bluetooth enabled devices may discover each other's existence and exchange info to determine their characteristics.
Use sdptool
from the bluez package to perform SDP queries on Bluetooth devices and for administering a local SDP daemon, or sdpd
.
Example:
- Show characteristics of the Sound Intone Bluetooth headset by showing all possible service records:
# sdptool records 09:40:a4:45:b1:4b Service Name: JL_A2DP Service RecHandle: 0x10001 Service Class ID List: "Audio Sink" (0x110b) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 25 "AVDTP" (0x0019) uint16: 0x100 Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "Advanced Audio" (0x110d) Version: 0x0100 Service RecHandle: 0x10002 Service Class ID List: "AV Remote" (0x110e) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 23 "AVCTP" (0x0017) uint16: 0x100 Profile Descriptor List: "AV Remote" (0x110e) Version: 0x0100 Service Name: JL_HFP Service RecHandle: 0x10003 Service Class ID List: "Handsfree" (0x111e) "Generic Audio" (0x1203) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 4 Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "Handsfree" (0x111e) Version: 0x0105
- Show records of a bluetooth keyboard:
# sdptool records 54:46:6B:01:7B:2B Service Name: Broadcom Bluetooth Wireless Keyboard Service Description: Keyboard Service Provider: Broadcom Corp. Service RecHandle: 0x10000 Service Class ID List: "Human Interface Device" (0x1124) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 17 "HIDP" (0x0011) Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "Human Interface Device" (0x1124) Version: 0x0100 Service Name: Broadcom Bluetooth Wireless Keyboard PnP Server Service Description: Keyboard Service RecHandle: 0x10001 Service Class ID List: "PnP Information" (0x1200) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 1 "SDP" (0x0001) Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "PnP Information" (0x1200) Version: 0x0100
- Show all devices advertising the A2DP Profile:
# sdptool search A2DP Service Name: JL_A2DP Service RecHandle: 0x10001 Service Class ID List: "Audio Sink" (0x110b) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 25 "AVDTP" (0x0019) uint16: 0x100 Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "Advanced Audio" (0x110d) Version: 0x0100
Reference:
Pairing and bonding (Setting up connections)
Many of the bluetooth services can expose private data or allow control of a device, therefore for security reasons it is desired to securely pair devices in a fashion that doesn't make it too difficult to use conveniently.
Bluetooth uses a process called bonding where a bond is generated through a process called pairing. Pairing is triggered either by a specific request or triggered automatically when connecting to a service for the first time. There is usually some form of user interaction to confirm the identify of the devices but once pairing is complete a bond will have been formed between the two devices, enabling them to connect to each other in the future without requiring the pairing process again. If desired the bonding relationship can later be removed by the user which would force a pairing to be completed again.
You can also tell your controller to specifically trust a device based on its MAC address which eliminates the need for pairing. It is the controller that decides to pair or trust a device, not the device itself.
The configuration for paired devices is stored in /var/lib/bluetooth/<hci_mac>/
.
The method used for pairing a controller to a device differs depending on the version of the BlueZ stack being used:
- BlueZ 5:
- The BlueZ 5 bluetooth daemon stores its persistent pairing details in
/var/lib/bluetooth/<hci_MAC>/<device_MAC>/info
with the format of:[LinkKey] Key String <key in hex format> Type Integer <Type of link key> PINLength Integer <Length of PIN>
- therefore you can remove all pairing history by removing that file and restarting bluetoothd
- You can request pairing with devices using the
bluetoothctl
CLIpair <bdaddr>
command:# bluetoothctl [NEW] Controller 00:15:83:6B:E2:BD BlueZ 5.37 [default] [bluetooth]# power on Changing power on succeeded [bluetooth]# scan on Discovery started [CHG] Controller 00:15:83:6B:E2:BD Discovering: yes [NEW] Device 54:46:6B:01:7B:2B 54-46-6B-01-7B-2B [CHG] Device 54:46:6B:01:7B:2B RSSI: -75 [CHG] Device 54:46:6B:01:7B:2B LegacyPairing: no [CHG] Device 54:46:6B:01:7B:2B Name: Bluetooth FAVI [CHG] Device 54:46:6B:01:7B:2B Alias: Bluetooth FAVI [bluetooth]# pair 54:46:6B:01:7B:2B Attempting to pair with 54:46:6B:01:7B:2B [CHG] Device 54:46:6B:01:7B:2B Connected: yes [CHG] Device 54:46:6B:01:7B:2B Modalias: usb:v0A5Cp8502d011B [CHG] Device 54:46:6B:01:7B:2B UUIDs: 00001000-0000-1000-8000-00805f9b34fb [CHG] Device 54:46:6B:01:7B:2B UUIDs: 00001124-0000-1000-8000-00805f9b34fb [CHG] Device 54:46:6B:01:7B:2B UUIDs: 00001200-0000-1000-8000-00805f9b34fb [CHG] Device 54:46:6B:01:7B:2B Paired: yes Pairing successful [CHG] Device 54:46:6B:01:7B:2B Connected: no [CHG] Device 54:46:6B:01:7B:2B LegacyPairing: yes [CHG] Device 54:46:6B:01:7B:2B RSSI: -66 [CHG] Device 54:46:6B:01:7B:2B RSSI: -66 [bluetooth]# scan off [CHG] Controller 00:15:83:6B:E2:BD Discovering: no Discovery stopped [bluetooth]# paired-devices Device 54:46:6B:01:7B:2B Bluetooth FAVI Device 09:40:A4:45:B1:4B P6 [bluetooth]#
- above first we enable scanning, then we pair with a device, next we disable scanning (optional), and lastly we show paired devices
- You can respond to pairing requests using the bluetoothd internal agent using the
bluetoothctl
CLI:# bluetoothctl [NEW] Controller 00:15:83:6B:E2:BD BlueZ 5.37 [default] [bluetooth]# power on Changing power on succeeded [bluetooth]# agent on Agent registered [bluetooth]# default-agent Default agent request successful [NEW] Device 00:15:83:3D:0A:57 yocto18-0 Request PIN code [agent] Enter PIN code: 0000 [CHG] Device 00:15:83:3D:0A:57 Paired: yes [CHG] Device 00:15:83:3D:0A:57 Connected: no [bluetooth]# paired-devices Device 00:15:83:3D:0A:57 yocto18-0
- above we first enable the agent, then set it to the default agent and wait for pairing requests. A pairing request comes from a device with a bdaddr or 00:15:83:3D:0A:57 and a name of yocto18-0 and we enter in the PIN that the device is expecting and we pair with it
- The BlueZ 5 bluetooth daemon stores its persistent pairing details in
- BlueZ 4:
- The BlueZ 4.x bluetooth daemon stores persistent pairing details
/var/lib/bluetooth/<hci_MAC>/linkkeys
with the following format:<bdaddr> <128bit_link_key> <key_type> <key_length>
- therefore you can remove all pairing history by removing that file and restarting bluetoothd
- You can pair with a device using the python 'simple-agent' found in the bluez4 git tree here (requires python, python-dbus and python-gobject)
# ./simple-agent hci0 54:46:6B:01:7B:2B RequestPinCode (/org/bluez/449/hci0/dev_54_46_6B_01_7B_2B) Enter PIN Code: 1234 Release New device (/org/bluez/449/hci0/dev_54_46_6B_01_7B_2B) # ls /var/lib/bluetooth/00\:15\:83\:3D\:0A\:57/ classes did linkkeys profiles config lastused names sdp # cat /var/lib/bluetooth/00\:15\:83\:3D\:0A\:57/linkkeys 54:46:6B:01:7B:2B E45EED6C956306606A306EA1A2E22B68 0 4
- Depending on the version of python you have installed, you may need to patch simple-agent with the following changes:
--- simple-agent.orig +++ simple-agent @@ -2,8 +2,7 @@ from __future__ import absolute_import, print_function, unicode_literals -from gi.repository import GObject - +import gobject import sys import dbus import dbus.service @@ -122,7 +121,7 @@ path = "/test/agent" agent = Agent(bus, path) - mainloop = GObject.MainLoop() + mainloop = gobject.MainLoop() if len(args) > 1: if len(args) > 2:
- Depending on the version of python you have installed, you may need to patch simple-agent with the following changes:
- Alternatively you can also pair using the compiled agent.c found in the bluez4 git tree here
# bluetoothd # ./agent 1234 54:46:6B:01:7B:2B Pincode request for device /org/bluez/2039/hci0/dev_54_46_6B_01_7B_2B Agent has been released
- if this exist without the 'Agent has been released' message then pairing was unsuccessful
- this can be cross-compiled with the following (ie Yocto SDK):
$CC -DVERSION=4.101 $(pkg-config --cflags dbus-1) agent.c $(pkg-config --libs dbus-1) -o agent
- For examples on how to pair using dbus messages see the simple-agent and agent.c source code
- The BlueZ 4.x bluetooth daemon stores persistent pairing details
- BlueZ 3:
- The BlueZ 3.x bluetooth daemon stores persistent pairing details in
/var/lib/bluetooth/<hci_MAC>/pincodes
in the form of:<mac> <pin>
- therefore you can remove all pairing history by removing that file and restarting bluetoothd
- If you manually edit this file, you will need to restart the hcid bluetooth daemon:
# echo "00:02:72:C9:56:47 0000" >> /var/lib/bluetooth/00\:15\:83\:3D\:0A\:57/pincodes # /etc/init.d/bluez-utils restart
References:
Writing code supporting Bluetooth
If you wish to or need to write your own applications to support Bluetooth there are a variety of great resources out there on the Internet:
- http://people.csail.mit.edu/rudolph/Teaching/Articles/BTBook.pdf (PyBluez, libbluetooth, cmdline tools)
- BlueZ 5 API Documentation
- BlueZ 4 API Documentation
- BlueZ 3 API Documentation
- Don't forget to refer to the source code:
- bluez - see the docs/examples/test directories
- bluez-tools - C applications
iBeacon
iBeacon is a form of BLE that was created by Apple to provide location based information and services to iPhones.
For example, someone is walking around with an iPhone with a specific app loaded that is listening for these iBeacons. The app on the phone will respond when the iBeacon comes in range. (retail environment, sale special)