Bluetooth Low-Energy on Linux API - linux

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)

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

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

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:-
Using Bluetooth low energy in linux command line
Bluetooth Low Energy: listening for notifications/indications in linux
How can I connect to the FitBit Zip over Bluetooth 4.0 LE on Linux with bluez?
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.

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.

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.

Related

How to interact with BLE devices through Linux using C programs?

I am fairly new to the BLE world. Assuming I have a BLE device Eg: A heart rate monitor, How do I interact with that BLE device using C code.
I am able to see the Heart rate data using the command line tool 'bluetoothctl'. If I want connect to the same device through C code and see the Notified data, how do I go about it?
Though some codes on the Internet and GitHub helped me to scan for the device, I do not have any idea on how to connect to the device, read the GATT characteristics of the BLE device. I'd even appreaciate it if anyone points me to the API documentations of BlueZ, I literally have no clue what the programs are all about. Any assistance would be of great help.
The preferred API for BlueZ uses the D-Bus bindings. The documentation for those APIs are at:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc
There are Python examples of how to use the D-Bus API at:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test
bluetoothctl is written in C and the source is available at: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/client

Zephyr OS understanding

Initially I built the Zephyr bluetooth application for native linux and run it in conjunction with Bluez on a BLE controller.I understand that in this, Linux OS and Bluez are used along with Zephyr host stack.
Now, I have flashed bluetooth application from Zephyr stack (samples/bluetooth/beacon)to NXP board successfully. Here there is no bluez used.
For this case, I have a few basic understanding questions:
1. Is the OS functionality also embedded in the bin file that is created after application is compiled. I mean I understand bluetooth stack is Zephyr, but which OS is used on board ?
2. Also, is there any functionality similar to hcitool in Bluez in Zephyr bluetooth stack?
3. Is there any functionality like btmon or hcidump?
To answer your questions:-
Zephyr is an OS itself - it is a Real-Time Operating System (RTOS)
that runs on top of many different types of hardware, just like how
Linux is an operating system that runs on top of many different
hardware. Zephyr is mainly written in C and under the hood talks
directly to the specific processor using its registers and the
vendor's stack. You can find a list of all supported boards
here.
Not identical to hcitool, but there is an hci layer example that
allows you to send raw hci commands. You can find more details on
this here and here. At the end of the day, you may not
need to use hci because it is a low layer and you can probably
achieve the same functionality through higher leve API. All Zephyr's
Bluetooth examples can be found here.
Again, nothing like btmon on Linux how you can see the raw HCI
packets for each command, but Zephyr does support different
Bluetooth logging options depending on the hardware used. More
information on this can be found here.
I hope this helps.

Programming a BLE server and a client both in a Raspberry Pi

I want to implement a BLE in a Raspberry which sends the result of a sensor apart from it's characteristics and make another Raspberry to obtain that data.
Because the language that offers the possibility to read data from the sensor is written in C, C++ and Python, I have been searching through multiple libraries like pygattlib, pygatt, pybluez and bluepy with no result to know how to send data in addition with their characteristics.
Is there any option to reproduce my request?.
I also read about iBeacon and Eddystonne protocol from Apple and Google, however my first point is to comunicate between two Raspberry (server and client).
If you are using rpi you should have Bluez preinstalled. Bluez provides API through D-Bus which you can use to add GAP and GATT functionality. The documentation is in source code of Bluez.
BLE advertising (GAP profile) documentation: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/advertising-api.txt
BLE data transfer (GATT profile) documentation: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/gatt-api.txt
Of course it easier to have an example. They are in Bluez repo too! They are written in Python but it should be easy to translate it to different language because they are using only D-Bus.
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/example-gatt-server
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/example-gatt-client
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/example-advertisement
I'll mark this as an answer because I could make it possible with the libraries written in javascript noble and bleno

Bluez server for bidirectional communication

I want to create on my Linux desktop a small server listening to requests using Bluetooth. Clients (such as mobile phones or tablets) will connect to this server and exchange data back and forth.
It should be straightforward, but I'm unable to find an up-to-date tutorial for Bluez's new DBUS-based API, and Bluez documentation is basically just a huge data dump.
Any suggestions on how I should proceed? (The language used does not really matter, since there are DBUS bindings for all major languages.)
These are some useful links to get started, it's not much but it's a start.
Textual (and up-to-date) description of the DBus interfaces exposed by bluez5 : https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc
You can find example for gatt client/server in the prevous cgit at the following path : /tree/src/shared/
An overview of Bluez and it's dbus interfaces (conference given at the 2016 Open IoT Summit) : https://www.youtube.com/watch?v=tclS9arLFzk
If you need example for your dbus bindings, I suggest looking at their test files
As you said yourself, there are dbus bindings in many languages however the language does matter. For example, some old low-level C API are not advised (see for yourself the advices in the dbus tutorial on freedesktop.org)
I suggest the following steps to start (especially for LE) :
Read the adapter-api.txt (first link) description and try to build a proxy to interact the org.bluez.Adapter1 interface (when trying to build the proxy: name would be 'org.bluez' and object path '/org/bluez/hci0' as describded in adapter-api.txt). Call StartDiscovery and StopDiscovery
Once scanning is done, print your proxy introspection to find the devices discovered (you should see MAC addresses preceded by "dev_")
Build proxies to interact with the device (read the device-api.txt file description to find out what you need)
For LE, if you want to access the Services of a Device. Introspect your device proxy and you will find it'serices. Repeat the process to reach Characteristics and Descriptors.

Tools for bluetooth monitoring

For my project I have an Android phone and an Arduino device that communicate via Bluetooth. I was wondering if anyone knows any software tools I could use to monitor a bluetooth communications between two devices. Something like a packet eavesdropping. Preferably for Linux.
Take a look at ubertooth one. In the linked webpage there are instructions on how to build the dongle, as well as links to shops selling assembled dongles may be bought. Ubertooth one should work well with Kismet, and thus in Linux, by using a BT plugin (disclaimer: I have no personal experience on this).
Sounds like you are after a Bluetooth sniffer.
Bad news: They are almost exclusively Windows OS based and cost mega-$.
http://www.fte.com/products/bluetooth.aspx
If you were using BlueZ for one side of the communication you could use the BlueZ HCIDUMP app and Wireshark.
I don't think anyone has made a Linuz/Bluez Sniffer - could be wrong.

Resources