Though not commonly known among many consumers, Bluetooth® technology is constantly and consistently advancing to include more features, widening the inclusion of device types that can benefit from Bluetooth connectivity, and progressing the evolution of a world without wires.
The Bluetooth Special Interest Group (SIG) typically has more than 50 active specification development projects at any given time. These projects include everything from adding minor features to existing Bluetooth specifications to creating new specifications that add major functionality to Bluetooth wireless technology.
A good example is the work currently in progress to add additional capabilities and features to Bluetooth LE Audio. Released only a few years ago, ongoing work on Bluetooth LE Audio is in motion to further enhance the next generation of wireless audio.
Bluetooth LE Audio Project Enhancements
Bluetooth LE Audio represents an entirely new platform for supporting audio applications on Bluetooth technology. Beyond enhancing existing Bluetooth applications like wireless calling and media, Bluetooth LE Audio is set to drive innovation in wireless audio for decades to come. Currently, there are three categories of Bluetooth LE Audio advancements in progress: standardization of specific capabilities, sound exposure, and enhancements to Auracast™ broadcast audio.
With ChromeOS 122, ChromeOS began replacing its current Bluetooth software implementation withFluoride, the Android Bluetooth stack. This migration, named Project Floss, started in early 2021. It has taken nearly two and a half years to achieve quality parity with Bluez, ChromeOS’s previous Bluetooth stack, for the most frequent ChromeOS use cases. Let’s take a look at why we decided to migrate—and the benefits to the Bluetooth landscape we hoped to achieve.
The Bluetooth ecosystem is a large, diverse, and exponentially growing collection of devices, expanding by over 27 billion devices in the last four years [1]. Specifically relevant in the context of ChromeOS, there are nearly six billion audio devices and four billion Human Interface Devices such as mice, keyboards, and game controllers. These two categories make up the vast majority of Bluetooth peripherals connected to ChromeOS devices.
ChromeOS, and Linux in general, is still a relatively new contender in the consumer PC space—and, as a result, not the primary focus for peripheral device manufacturers when it comes to interoperability testing and validation. Compounded with the many variations of kernels actively supported across the fleet of ChromeOS devices, it is challenging to maintain device interoperability with the ChromeOS platform (or to motivate the ecosystem to dedicate resources toward validation).
Our previous Bluetooth stack, BlueZ, used a different code base and APIs between phone and PC ecosystems—leading to friction. This friction led to a longer time-to-market for new features. The maintenance cost of BlueZ is also higher than Floss, because over 50% of the code is in the Linux kernel, causing extra work when dealing with different versions.
The Android Bluetooth stack is a great alternative for a few reasons:
Large user base for better interoperability testing with peripheral devices.
Simpler technical architecture that is almost entirely in userspace.
Improved testability and security (userspace isolation and migration to Rust).
We created Project Floss as the ChromeOS and Linux frontend to Fluoride. Our core goals for Floss were to reduce engineering overhead, converge Google's efforts on a single stack, and reduce ecosystem fragmentation.
BlueZ roughly splits Bluetooth software implementation into three areas: the kernel, the userspace daemon, and the audio server.
The audio server implements the Hands-Free profile and audio encoding/decoding.
The userspace daemon exposes the D-Bus APIs necessary to control Bluetooth and handles most of the device and profile management.
Finally, the kernel implements most of the core functionality and exposes several sockets to allow communication with the kernel.
Migrating from Bluez to Floss simplifies a lot of the system architecture:
The audio server can control the audio connection via D-Bus and send data to the userspace daemon over domain sockets because it sends raw PCM data and does not handle any of the encoding/decoding.
The Bluetooth implementation is fully contained in the Floss daemon. The Floss daemon is sandboxed in userspace using minijail to reduce its permissions to the minimum set necessary for Bluetooth operation, which greatly improves the security of the system.
The kernel exposes a raw HCI socket directly to userspace for exclusive ownership.
The Floss implementation shares most of its code with Android via libbluetooth, the native implementation of the Bluetooth stack. Floss implements the D-Bus APIs for managing devices, media and sockets by calling the necessary methods in libbluetooth. Since Floss is written entirely in Rust, there is a Rust to C/C++ layer called topshim which translates methods and data to allow the two code blocks to work together.
The Android specific portion of the implementation deals with which APIs are exposed to applications, how the system audio interacts with Bluetooth, and how the HALs are implemented (HCI HAL and various Audio HALs).
In our internal tests, we saw performance improvements across the following metrics: reduced pairing duration, increased pairing success rate, and increased reconnection success rate.
Chart showing the pairing time between BlueZ and Floss
Chart showing the pairing outcome between BlueZ and Floss
Chart showing the reconnection success between BlueZ and Floss
In addition to improved performance, with Floss we can bring new features to ChromeOS with faster speed and built-in interoperability with Android.
The Bluetooth market is constantly growing, and by 2026 there are expected to be seven billion Bluetooth device shipments globally. By 2026, it’s projected that three billion of seven billion devices will be LE Audio devices. LE Audio will enhance the performance of Bluetooth audio, add support for hearing aids, and enable Broadcast Audio, an innovative new Bluetooth feature with the potential to once again dramatically improve the way we experience audio and connect with the world around us.
With Fluoride already supporting several advanced codecs, Floss will work to enable additional codecs to enable higher quality voice and audio streaming.
By sharing the underlying code base within Google, we can maximize the benefits of varying priorities in different products rather than having them compete with each other. Having one group focused on car interoperability and another focused on cross-device experiences will result in both benefits at the same time and scale throughout our product lines.
Both Android and ChromeOS are motivated to provide timely updates to our customers and the larger ecosystem. This is key to ensure that we have a coherent codebase and reduce overall fragmentation in the Bluetooth ecosystem.
We aspire to position Project Floss as a standalone open source project that can reach beyond the walls of Google’s own operating system in a way where we can maximize the overall value and agility of the larger Bluetooth ecosystem. We also intend to support the Linux community as a whole with the goal that Floss can easily run on most Linux distributions.
The Web Bluetooth API and the Web Serial API allow web apps to communicate with Bluetooth Low Energy (BLE) devices and serial devices, respectively. While many web developers are already using these APIs to great success, there is a growing demand for support for Bluetooth Classic devices as well.
Now, the Web Serial API supports communicating with RFCOMM services on paired Bluetooth Classic devices including the Serial Port Profile (SPP) in Chrome 117 on desktop. This opens up new possibilities for web developers and users alike. Here are some real-world devices that can benefit from this:
Pixel Buds Pro and other wireless earbuds use RFCOMM to manage audio settings and firmware updates.
Mobile point-of-sale systems use Bluetooth SPP to communicate with receipt printers.
Livestock RFID tag readers use Bluetooth SPP to log animal movements.
Take yourself back to the late 90s. You just put your Palm Pilot into its cradle to sync your calendar for the next day. Wouldn't it be nice if you could do that wirelessly instead? With this new "Bluetooth" technology you can get rid of all those messy cords. Wireless is the future! There's only one problem, everything that exists is designed to connect with an RS-232 cable. So, Bluetooth uses the Radio Frequency Communication (RFCOMM) protocol to provide that interface to all of the existing software and hardware.
Even today, RFCOMM services are widely used in new and existing hardware. It allows for meeting specific latency and bandwidth requirements that are not met by Bluetooth Low Energy so far. That is why we’ve developed an integration between Web Serial, an API for connecting to serial devices, and Bluetooth, to enable access to these legacy RFCOMM services before manufacturers eventually migrate to Bluetooth Low Energy and developers can use the Web Bluetooth API instead.
Web Serial API changes
Starting in Chrome 117 on desktop, web developers can now reliably communicate with paired Bluetooth Classic devices through RFCOMM services using the Web Serial API. This was made possible by the following updates to the Web Serial API:
Chrome now enumerates paired Bluetooth devices that expose a serial interface using the standardized Bluetooth Classic Serial Port Profile.
Chrome can now communicate with the serial interface even if the operating system has not created a device node through an emulated serial port specifically.
Chrome can now communicate with a non-Serial Port service that exposes an RFCOMM serial interface (see non-standard Service Class IDs).
You can learn about how to use the Web Serial API in the Read from and write to a serial port article. This article assumes you have basic knowledge about Bluetooth and focuses on the serial over Bluetooth changes.
Without specifying any filters, calling navigator.serial.requestPort() allows users to select non-Bluetooth serial ports, Bluetooth serial ports that have been mapped already, and any unmapped serial ports provided by the standardized Bluetooth Classic Serial Port Profile.
// Prompt user to select any serial port. const port = await navigator.serial.requestPort();
Although most devices expose SPP-based communication through the standardized Bluetooth Classic Serial Port Profile, some use custom RFCOMM-based services. These devices have a Service Class ID that is not in the standard Bluetooth UUID range.
You need to pass the allowedBluetoothServiceClassIds list to navigator.serial.requestPort() to access these custom RFCOMM-based services as shown in the example below.
// Prompt user to select any serial port. // Access to the custom Bluetooth RFCOMM service above will be allowed. const port = await navigator.serial.requestPort({ allowedBluetoothServiceClassIds:[myBluetoothServiceUuid], });
Note that all Service Class IDs that use the Bluetooth SIG Base UUID (that is, all UUIDs that end in "-0000-1000-8000-00805f9b34fb") are blocked except the Serial Port Profile ID as Chrome does not support Bluetooth Classic services such as audio and video.
You can also use the bluetoothServiceClassIdfilter key when calling navigator.serial.requestPort()to prompt the user with a list of filtered Bluetooth serial ports identified by Service Class IDs. See the example below.
// Prompt the user to select Bluetooth serial ports with // the custom Bluetooth RFCOMM service above. const port = await navigator.serial.requestPort({ allowedBluetoothServiceClassIds:[myBluetoothServiceUuid], filters:[{ bluetoothServiceClassId: myBluetoothServiceUuid }], });
If the serial port is part of a Bluetooth device, a new bluetoothServiceClassId key containing the Service Class ID associated with the RFCOMM channel that the port is connected to is available in the serial port info returned by calling port.getInfo(). If the serial port is mapped, it returns "00001101-0000-1000-8000-00805f9b34fb" or 0x1101 in its short form.
const{ bluetoothServiceClassId }= port.getInfo();
Use case example: Control Pixel Buds Pro
The Pixel Buds Pro Web Companion App is a new web app that allows users to control their Pixel Buds Pro from any device with a web browser. It is built using Progressive Web Apps technologies for an instant load experience and can optionally be installed alongside other operating system apps.
The app uses the Web Serial API to communicate with the Pixel Buds Pro. This allows users to control various settings on their Pixel Buds Pro, such as active noise control, equalizer, in-ear detection, and firmware updates.
To try the Pixel Buds Pro Web Companion App, visit mypixelbuds.google.com on a ChromeOS device (other platforms coming soon).
Bluetooth™️ is a wireless technology used to build Personal Area Networks (PAN) or piconets. Since it’s original development by Ericsson in 1989, it has grown in popularity to the point where today it has become a standard feature in many segments of the consumer electronic market.
The use of Bluetooth in industrial IoT is also growing, mostly due to Bluetooth LE, a newer variant of Bluetooth optimized for minimum power usage, as is required for wireless, battery-powered sensor devices.
This blog post takes you through the important details of the Bluetooth LE technology from the perspective of an IoT developer. It is based on the presentation at the Internet of Things conference “From the sensor to the cloud” 2021, by our Founder & Chief Technologist Günter Obiltschnig.
A few facts about Bluetooth
Development of Bluetooth technology was originally initiated by Nils Rydbeck (Ericsson) in 1989. The first use case was not until ten years later, and was released at Comdex in 1999 as the first hands-free mobile headset. It won the “Best of show Technology Award”. This first product had a range of 10 meters but nowadays, that range can go up to 100m with Bluetooth 5.0.
Bluetooth uses the globally unlicensed ISM (industrial, scientific, medical) radio bands from 2402 to 2480 GHz. One of the major advantages of Bluetooth is that it does not rely on a wireless network infrastructure.
The name Bluetooth is an anglicized version of the Scandinavian Blåtand/Blåtann, the epithet of the tenth-century king Harald Bluetooth who united dissonant Danish tribes into a single kingdom. The implication is that Bluetooth unites communication protocols in the same way king Bluetooth united tribes.
Bluetooth Low Energy (LE)
Bluetooth LE (formerly also known as Bluetooth Smart) was introduced with the Bluetooth 4.0 specification in 2010. It is intended to reduce power consumption and cost while maintaining a similar communication range. The actual connection times are reduced to a few milliseconds; significantly less than Bluetooth, which has connection times ranging from a few seconds up to a few hours.
Bluetooth LE can co-exist with Bluetooth on the same controller, however, the Bluetooth LE protocol stack is different from classic Bluetooth. It uses the same 2.4 GHz radio bands as Bluetooth, but a different communication protocol and different channels with 2 MHz bandwidth.
Bluetooth LE is targeted at devices with very low-power requirements, such as fitness and health sensors (heart rate monitors, thermometers, blood pressure, etc) as well as fitness trackers, battery-powered environmental and industrial sensors, beacons, etc.
Bluetooth LE uses a unique 48-bit address per device (MAC address). Similar to Ethernet MAC addresses, the first part of the address is the “vendor prefix”, which allows to deduct the vendor of a Bluetooth device (or at least its chipset) from its address.
Bluetooth LE Radio
Bluetooth LE uses 40 channels with 2 MHz bandwidth. Within each channel, Gaussian Frequency Shift Keying (GFSK) is used, similar to classic Bluetooth 1.0. The bitrate is 1 Mbit/sec, with an option for 2 Mbit/sec in Bluetooth 5.0.
Bluetooth LE uses frequency hopping like “classic” Bluetooth, but in a different variant (direct sequence spread spectrum).
Bluetooth LE Protocol Stack
GAP – Generic Access Profile
Bluetooth LE devices use the Generic Access Profile for device discovery and advertisement.
GAP distinguishes between devices based on their roles. Central devices are typically a computer or smartphone. Peripheral devices are often small, low-power and resource-constrained devices like sensors.
In order to discover peripheral devices, a central device sends out a broadcast message (scan response request). Upon receiving the scan response request, the peripheral device will respond with advertising data. This includes device name and address, and other data. Advertising data can also include small amounts of custom data. This is used by Bluetooth LE beacons (e.g., iBeacon).
Both peripheral and central devices can assume one or both of the other GAP roles, which are Broadcaster and Observer. A very typical example would be a sensor in broadcast mode sending data to a central device in observer mode.
GATT – Generic Attribute Profile
GATT defines the following concepts, which are often reflected in Bluetooth LE APIs.
Client: typically a computer or smartphone that sends GATT commands and requests and receives responses from servers. Also referred to as central device.
Server: a device (e.g., a sensor) that receives commands and requests and returns responses. Also referred to as peripheral device.
Characteristic: a data value transferred between client and server. Consists of multiple attributes containing the actual value, as well as configuration options and meta data.
Different data types are supported, but on protocol level an attribute value is always a sequence of bytes. Characteristics and their attributes are used for reporting sensor values (e.g., temperature) and also for configuring devices (e.g., setting sample rate on an accelerometer). The maximum length is 512 bytes. Numeric values are usually stored in little-endian format.
Service: a collection of related characteristics, which operate together, e.g. the sensor value and configuration parameters.
Descriptor: provides additional information about a characteristic’s attribute, e.g. physical unit or minimum and maximum values.
Identifier: services, characteristics and descriptors are attributes identified by UUIDs. The 128-bit UUIDs are mapped to device-specific 16-bit values (handles) for use in the protocol. Bluetooth reserves UUIDs in range xxxxxxxx-0000-1000-8000-00805F9B34FB for standard attributes, which are transmitted as 16-bit or 32-bit values in the protocol.
GATT Operations
GATT comes into play once a connection is made between two devices. For data to be delivered and received, some or all of the following operations can be executed.
discover UUIDs for primary services
find a service with a given UUID
find secondary services for a given primary service
discover all characteristics for a given service
find characteristics matching a given UUID
read descriptors for a particular characteristic
read the value of a characteristic (a sequence of bytes)
write the value of a characteristic (a sequence of bytes)
request notifications and indications.
Servers can send notifications and indications to clients on certain state changes (e.g., the sensor value has changed); indications must be acknowledged by the client.
Bluetooth LE Profiles
Like classic Bluetooth, Bluetooth LE defines a number of profiles. All Bluetooth LE profiles are based on GATT, therefore, a Bluetooth LE profile defines the services and characteristics (and their IDs) that a device must support.
Examples:
BLP – Blood Pressure Profile
HTP – Health Thermometer Profile
GLP – Glucose Profile
HRP – Heart Rate Profile
CPP – Cycling Power Profile
WSP – Weight Scale Profile
LNP – Location and Navigation Profile
ESP – Environmental Sensing Profile
BlueZ – Bluetooth & Bluetooth LE on Linux
BlueZ is the official Linux Bluetooth protocol stack. It was originally developed by Max Krasnyansky at Qualcomm (starting in 2001), and is available for Linux kernels 2.4.6 and newer. Currently the main developers are Marcel Holtmann and Johan Hedberg, currently at Intel.
BlueZ is listed as a qualified protocol stack on the Bluetooth Qualification website, which simplifies the product qualification process. It consists of kernel modules and user space libraries and is included in all major Linux distributions. BlueZ has a low-level C API and a high-level D-Bus API.
BlueZ is licensed under the GPL, but is (apparently) in the process of being moved to LGPL.
bluepy
bluepy by Ian Harvey is a Python interface to Bluetooth LE on Linux. bluepy consists of a Python module and an executable (bluepy-helper) written in C. The bluepy-helper executable wraps the BlueZ C API in a command-line interface.
The output of bluepy-helper commands is easily parseable by programs. The bluepy python module starts bluepy-helper and sends command via a pipe. It can also be used interactively, which is great for making the first steps with a Bluetooth LE peripheral.
bluepy-helper is licensed under the GPL, like the BlueZ libraries it uses (derived work), however programs launching bluepy-helper and talking to it via a pipe need not be under GPL.
The hexadecimal string 4475636B5F52656C65617365 translates to “Duck_Release”, which actually does not make much sense, but it is what the specific device (a Xiaomi Mijia temperature and humidity sensor).
We can now implement a high-level Bluetooth LE API for a programming language of our choice on top of bluepy-helper. We only need to be able to start a process and communicate with it via a pipe.
For macchina.io EDGE, we have created a C++ API that can also be used from JavaScript.
Connect: start a new bluepy-helper helper process for the peripheral.
Disconnect: kill helper process.
For every operation, send the respective command to bluepy-helper and parse the result.
Handle indications and notifications.
Perform some state-keeping.
In addition to the generic Peripheral interface, macchina.io EDGE also has high-level support for a few specific Bluetooth LE devices, such as a TI SensorTag or a Bosch XDK.