====== AMA and Bluetooth Programming ====== [[knowledge_base:programming:ble_gatt|BLE GATT Profile]] {{:knowledge_base:bluetooth_core_v5.0.pdf|Bluetooth 5.0 Specification}} ===== AMA App initial query ===== 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 ===== Bluetooth Programming ===== ==== BLE only on Rpi3 ==== 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). ==== A Good Source ==== 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. ==== Other Sources ==== [[https://dbus.freedesktop.org/doc/dbus-python/|https://dbus.freedesktop.org/doc/dbus-python/]] [[https://github.com/OnBeep/opuslib|https://github.com/OnBeep/opuslib]] [[https://cdn-learn.adafruit.com/downloads/pdf/install-bluez-on-the-raspberry-pi.pdf|https://cdn-learn.adafruit.com/downloads/pdf/install-bluez-on-the-raspberry-pi.pdf]] [[https://www.youtube.com/watch?v=tclS9arLFzk|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: [[http://bluez.org/download|bluez.org/download]]. If that page is dead, use [[https://www.kernel.org/pub/linux/bluetooth/|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 [[https://en.wikipedia.org/wiki/D-Bus|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 [[https://www.youtube.com/watch?v=tclS9arLFzk|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 [[https://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html|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!