knowledge_base:programming:bluetooth

AMA and Bluetooth Programming

working advertising data (iOS):

mgmt# add-adv -g -d 030203fe171603fe7101010001000000000000000000000000000000 -s 0b09616d615f73616d706c65 1
              -g is general-discoverable flag
              -u is uuid (big endien) if in -d, uuid and everything else should be expressed in small endien
              -d is data starting with length, AD type (16 is service data type), uuid ... length, AD type, ...
              -s is scan data starting with length, AD type (09 is full name) ...

After Alexa App Setup:

Values written:
10 00 05 08 14 a2 01 00
alexa_tx_write_cb called
Values written:
10 00 05 08 15 aa 01 00
alexa_tx_write_cb called
Values written:
10 00 05 08 5a d2 05 00
alexa_tx_write_cb called
Values written:
10 00 0b 08 32 92 03 06 10 a6 b0 f7 df 05

Run “sudo btmon” on a separate window to monitor HCI activities

$ sudo btmgmt
[mgmt]# info
Index list with 1 item
hci0:   Primary controller
        addr B8:27:EB:95:C2:E1 version 7 manufacturer 15 class 0x000000
        supported settings: powered connectable fast-connectable discoverable bondable link-security ssp br/edr hs le advertising secure-conn debug-keys privacy static-addr
        current settings: powered bondable ssp br/edr le secure-conn
        name le_ama_sample_001
        short name
[mgmt]# power off
hci0 Set Powered complete, settings: bondable ssp br/edr le secure-conn
[mgmt]# bredr off
hci0 Set BR/EDR complete, settings: bondable le secure-conn
[mgmt]# connectable on
hci0 Set Connectable complete, settings: connectable bondable le secure-conn
[mgmt]# discov on
hci0 Set Discoverable complete, settings: connectable discoverable bondable le secure-conn
[mgmt]# io-cap 0x03                                               #NoInputNoOutput
IO Capabilities successfully set
[mgmt]# power on
hci0 Set Powered complete, settings: powered connectable discoverable bondable le secure-conn
[mgmt]# advertising on
hci0 Set Advertising complete, settings: powered connectable discoverable bondable le advertising secure-conn # Current settings: 0x00000e1b
hci0 00:B3:62:41:9A:68 type LE Public connected eir_len 0         # paired with an iPhone
hci0 00:B3:62:41:9A:68 type LE Public disconnected with reason 3  # unpaired by the iPhone

sudo btmgmt advertising off

Then use your own custom ad and scan payload like so:

sudo btmgmt add-adv -d 02010606094142434400 -s 05061805051206000a00020a00 1

This will turn on advertising with your custom payload once you've powered up the adapter. The example above sets up the complete name in the advertisement payload. The scan response payload is also set with the following: 16-bit UUID, connection interval range, and TX power level:

Complete name: “ABCD”
UUID: 1805
Connection interval range: 7.5 ms to 12.5 ms
TX power level: 0 dBm

If you want to understand the meaning of the header bytes in the payloads I've posted, I suggest you read the Bluetooth Core Specification documents. Another place to look is in the BlueZ source code (eir.h in the src directory).

https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/advertising-api.txt#n99

You might want to check out the main.c file in the client folder of the most recent Bluez source code. It's the source code for the bluetoothctl tool. Run it too. The source code shows exactly how they use GDBus, including proxies, agents, calling methods like described in the API (/doc folder) and all that. It's in C and uses the high level API.

I suggest you step through the code because it took me 2 weeks endlessly trying to understand Bluez in C and the fact that there's no documentation, but when I read that main.c file I was ready in a day. Read up on proper Dbus API documentation and more importantly the concepts. Some documents that helped me:

The gdbus tool: https://developer.gnome.org/gio/stable/gdbus.html

These contain all the calls to gdbus and objects in the main.c file and explain them very well. https://developer.gnome.org/gio/stable/gdbus-convenience.html

D-Feet, an invaluable tool to inspecting and learning about Dbus on your system. Try checking out the /bluez bus. https://wiki.gnome.org/action/show/Apps/DFeet?action=show&redirect=DFeet

or

sudo apt-get install d-feet

Not much of a tutorial, but worth a read to understand some concepts, as the bluetoothctl tool fits into what they're trying to say here. http://dbus.freedesktop.org/doc/dbus-tutorial.html

The bluetoothctl creates an interactive shell though, so it might not be wise to waste time trying to fit in your code, but just pick what you need from it.

https://dbus.freedesktop.org/doc/dbus-python/

https://github.com/OnBeep/opuslib

https://cdn-learn.adafruit.com/downloads/pdf/install-bluez-on-the-raspberry-pi.pdf

https://www.youtube.com/watch?v=tclS9arLFzk

https://raspberrypi.stackexchange.com/questions/66540/installing-bluez-5-44-onto-raspbian/74712

A bit late here, but I recently suffered the headache of following a variety of different guides, none of which worked for me. So here is another guide…that probably won't work for you ;)

I downloaded the most recent version from the official page: bluez.org/download. If that page is dead, use this one instead.

For example, at the time of writing it was 5.47, so I used (on my raspberry):

''wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.47.tar.xz
''

Then I extracted it and built it:

''tar -xf bluez-5.47.tar.xz
cd bluez-5.47
''

Read the README! It lists the dependencies and the configure switches:

Install the dependencies first: (glib, dbus, libdbus, udev, etc.) Most of them are already installed and if not they should be easy to install, all provided by package manager. Once you've done that:

''./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc --localstatedir=/var
''

I also added –enable-experimental because I believe the GattCharacteristics object is part of the experimental features. Then do:

''make
sudo make install
''

It takes maybe 10 minutes to compile. After installing, you should find bluetoothd in /usr/libexec/bluetooth. You should also see bluetoothd in /usr/lib/bluetooth.

Go to each of these directories and type

''./bluetoothd --version
''

You'll note that the one in libexec is new and the one in lib is old.

BlueZ creates these d-bus objects and interface to expose the bluetooth devices to you in nice ways.

In order to make sure that d-bus is talking to you new BlueZ 5.47 and not your old BlueZ 5.23, you need to tell systemd to use the new bluetooth daemon:

'' sudo vim /lib/systemd/system/bluetooth.service
''

Make sure the exec.start line points to your new daemon in /usr/libexec/bluetooth.

For me, that wasn't enough. No matter what, upon restart I always got bluetoothd 5.23… So I just created a symlink from the old one to the new.

First rename the old file:

''sudo mv /usr/lib/bluetooth/bluetoothd /usr/lib/bluetooth/bluetoothd-543.orig
''

Create the symlink:

''ln -s /usr/libexec/bluetooth/bluetoothd /usr/lib/bluetooth/bluetoothd
sudo systemctl daemon-reload
''

That should do it.

Now, I have to say this, even though it's not relevant to the question:

If you want to develop an application for your pi, read the blueZ docs folder. It introduces you to something called d-bus, which is really worth learning about, and allows you to develop your application in python, node.js, or c (and more). Watch this video on bluez dev.

There are a lot of red herrings out there: wrappers that attempt to give you “easy” functionality. Even resources that say there is a lack of documentation on how to develop bluetooth. However, as soon as you want to do anything beyond simply connecting to the device and viewing it's characteristics, you're going to realize the wrapper will fail you.

Do yourself a favor. Take a few hours to learn how BlueZ works (the video I linked is solid gold). It uses something called d-bus. Read a bit about d-bus. If you like Python, look at the code in the test folder. Read the python dbus tutorial once or twice. It will pay off so nicely. I wasted a few days trying to find something easy, but this turned out to be the best way.

Good luck!

  • Last modified: 2022/12/02 14:55
  • by George Wayne