Search code examples
ubuntubluetoothbluetooth-lowenergybluezbluetooth-gatt

How to deal with BlueZ bluetooth instability?


Background

My team has been trying to implement a bluetooth LE 'api' for a while now. We decided on BLE over legacy Bluetooth due to iOS (one of our client device types) blocking legacy BT for anyone not on their approved device list. We're primarily using the Intel AX200/AX201 bluetooth hardware running on a small edge device with Ubuntu Server 22.04 LTS. Though we also test with a Raspberry Pi 4 and nVidia Jetson for some of our development.

After realizing there were no real Java (our core language) bridges/bindings for BLE, we came upon guidance on StackOverflow suggesting that most custom BLE on Linux is done by customizing the BlueZ source and adding their custom GATT characteristics to the BlueZ source (e.g. modifying gatt-database.c), so we went that route. Our handful of characteristics are very simple and rather than build all of our business logic into the BlueZ source, we instead call and interact with shell scripts via popen/printf/read which handle the majority of 'business logic'.

The Issues

That said, we can barely get Bluetooth LE to work consistently with even the simplest characteristics. Our connections to some devices are mostly stable, while very unstable to other devices. (e.g. iOS vs a laptop) Perhaps this just requires some retry handling, but also...

We have consistently seen that any time our Ubuntu/BlueZ stack enters some kind of 'faulted' state, the actual BT hardware becomes completely bricked until we perform full power cycle. Only after a hard restart can we expect to see normal behavior again.

At the same time, Bluetooth is everywhere and while it's generally a fairly buggy protocol, it usually works with some minor fiddling. So I'm inclined to think we're doing something wrong.

So BlueZ+Ubuntu appears too unreliable for us to use, and we're considering using a UART or Ethernet based interface instead, but before giving up on it, I'm here to ask...

The question

Is there something really major we're missing here? How do products use BLE successfully on Linux based systems? Is BlueZ just absolutely awful for everyone? Is there a different library we should be using? Should we be using different hardware?

My question is maybe fuzzy because we don't even really know what the root issue is, beyond BLE being a buggy mess for us.


Solution

  • I guess most people that use BlueZ use the DBus API (https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc) which can be consumed by any language that has a client library for DBus, rather than modifying the source code of BlueZ.

    If you want to try out a completely different solution than BlueZ you can try out my library at https://github.com/Emill/node-ble-host, which in my opinion is more simple to use. It's however written for Javascript...

    And FYI most BLE products don't use BlueZ. Both Android and iOS have their own implementations and embedded products ("bare metal") use the Bluetooth stacks provided by the chip manufacturer.