18

I have a device with a few custom GATT services, and I would like to write a Linux program to interact with it. After some searching I found out that Linux is using BlueZ to handle the Bluetooth LE protocol. I'm using Ubuntu 15.10 with BlueZ 5.35, but I cannot figure out how use this BlueZ from a user-space program. I cannot find an API documentation anywhere, no tutorials, examples, nothing. Is it even possible to use this BlueZ stack to do anything other than just connecting to Bluetooth devices with default services? And if so, where is the documentation? (Preferably C/C++ API but at this point anything goes)

UnTraDe
  • 3,747
  • 10
  • 36
  • 60
  • Yes it's possible. But there is a learning curve. The bluez APIS are documented in the [bluez tree](https://github.com/r10r/bluez/blob/master/doc/). Those are all DBUS APIs. So to use them you first need to learn a bit about DBUS. There are different bindings to make use of DBUS. They include python, Glib and QT. There are others. – kaylum Feb 14 '16 at 09:51
  • every one here talks about the LE Client as Linux , no one talks about the Linux LE as a server . – Raulp Aug 21 '21 at 05:38

5 Answers5

17
  • Have a look at attrib/gatttool.c in the bluez sources [1]. Gatttool is a command line utility for connecting to BTLE devices using the C "API". The GATT interface is not exposed in libbluetooth though.

  • A newer alternative to gatttool and thus another example to learn from is the btgatt-client, which you can find in tools/btgatt-client.c (to enable compilation configure bluez with --enable-experimental).

  • Besides the C interface bluez integrated a DBUS interface. bluetoothctl is an example tool using the DBUS interface. The code of bluetoothctl can be found in client/ [2].

  • Another example program using the C interface of bluez is the Anki Drive SDK [3]. It packaged the bluez GATT C interface in its own library libbzle [4]. When using the C interface you have to connect a socket when establishing a BTLE connection. The gatttool does this via the GATT interface, which in turn uses glib iirc. But you can also do this using syscalls (socket, connect, ...) as explained e.g. here [5]. This document also explains:

Unfortunately, as of now there is no official API reference to refer to, so more curious readers are advised to download and examine the BlueZ source code.

Gilbert Brault also extracted the GATT interface from bluez [6] and links to a rudimentary doxygen documentation of the GATT interface [7] with the following disclaimer:

This is a work in progress with the intent of documenting all important functions and data structures

Also Szymon Janc gave a nice overview in his talk "Bluetooth on Modern Linux" at the Embedded Linux Conference 2016 [8]. Starting at 42:00 he talks about the unexposed C interface. But in general he seems to recommend the DBUS API (see "Tips" slide at 45:30). Some DBUS documentation can be found in doc/gatt-api.txt [9] and Python examples using the DBUS interface can be found in test/.

Hope this helps.

[1] http://git.kernel.org/cgit/bluetooth/bluez.git/tree/attrib/gatttool.c
[2] http://git.kernel.org/cgit/bluetooth/bluez.git/tree/client/
[3] https://github.com/anki/drive-sdk/
[4] https://github.com/anki/drive-sdk/tree/master/deps/bzle/
[5] https://people.csail.mit.edu/albert/bluez-intro/c404.html
[6] https://github.com/gbrault/gattclient
[7] http://gbrault.github.io/gattclient/index.html
[8] https://www.youtube.com/watch?v=tclS9arLFzk
[9] http://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/gatt-api.txt

Fritz
  • 1,293
  • 15
  • 27
user1225999
  • 912
  • 8
  • 14
16

I feel your pain. I needed to add user input from a custom BLE peripheral, a simple remote pushbutton, to an embedded program running under Linux (Stretch) on a Raspberry Pi. I was stunned by the needless complexity and Spartan (not a compliment) documentation of the BlueZ API. All the BlueZ “examples” are written from the perspective that Bluetooth is the center of the universe and the user wants to support every Bluetooth device ever invented. In my case I knew exactly the device, service, and GATT characteristics I needed to interact with, and I wanted a minimum overhead task that would do its thing in a low priority thread.

It turns out a BLE central client is pretty straightforward using BlueZ, but it was an arduous road starting with the source for the BlueZ utility bluetoothctl in release 5.49. I accomplished my needs using only three unmodified source files from the BlueZ distribution and excerpts from an additional three source files. Since the BlueZ source is inextricably dependent on D-Bus and the Gnome GLib main loop, I grudgingly included them.

Following OlivierM's generous lead, and in hopes that my embarrassingly massive investment in time saves someone else a month of their life, I have posted my example Bluetooth BLE client on GitHub: https://github.com/jjjsmit/BluetoothBLEClient

JJJSchmidt
  • 820
  • 6
  • 13
6

It would arguably be simpler and quicker to write a shell script on Linux to do what you need to do. The BlueZ commands are relatively simple and straightforward, and there are many tutorials and questions on how to use it.

Tutorials:-

http://www.jaredwolff.com/blog/get-started-with-bluetooth-low-energy/ https://learn.adafruit.com/reverse-engineering-a-bluetooth-low-energy-light-bulb/control-with-bluez https://lilyhack.wordpress.com/2014/02/03/ble-read-write-arduino-raspberry-pi/ http://joost.damad.be/2013/08/experiments-with-bluetooth-low-energy.html

Questions:-

Once you are more familiar with using the commands manually you can then write a minimal shell script so that this is automated for you.

Community
  • 1
  • 1
Youssif Saeed
  • 11,789
  • 4
  • 44
  • 72
  • 2
    I've used a lot of these commands to test the capabilities of the BlueZ, and it has the features I need. But I need to create something more sophisticated than a shell script. – UnTraDe Feb 18 '16 at 07:12
  • Some of those articles mention tools that are now deprecated on Linux, like `hcitool`, `gatttool`. https://wiki.archlinux.org/title/bluetooth#Deprecated_BlueZ_tools – Raleigh L. Oct 26 '22 at 22:45
2

I had a similar issue which is to interact with a BLE device with a GATT C/C++ API. I have realized there was no such API existing. The way I fixed my issue was to write my own GATT library. I have pushed the code on Github: https://github.com/labapart/gattlib

I use this library in my own BLE project and it fulfils my needs. I created few examples https://github.com/labapart/gattlib/tree/master/examples that use the library to encourage people to use it and have better feedback.

OlivierM
  • 2,820
  • 24
  • 41
1

I recently found out that Qt has Bluetooth Low Energy support as host since Qt 5.7. Qt Bluetooth LE. It is available under LGPLv3 or commercial license, and exposes a C++ API.

Jon Nordby
  • 5,494
  • 1
  • 21
  • 50
  • I would appreciate some open source programs who use this api. I try to use it in a program but I get unexplainable crashes with it. For example connect to one device read the service. Disconnet and then connect to annother device leads to crash. Also I found that i had to force to a certain Bluetooth dbus version. without it commands could not be send and received properly to a device. See for example this: https://forum.qt.io/topic/122098/qt-bluetooth-low-energy-notification-bug-downgrade-qt . Problem is beside the qt examples i could not find any more sophisticated programs use it. – Sandro4912 Mar 08 '22 at 19:32