hiro99ma blog

Something technical

ble: gattlib (2)

2025/04/04

前回の続きで gattlib で BLE の central 操作するのを検討している。

ble_scan のログが出力されない

前回の追記に ble_scan で切断がうまく行かないことを書いた。
何度か試していると、そもそも接続されたりされなかったりしていた。

GATTLIB_LOG() でログ出力しているようなのだが、どうにも出力されていないように見える。
どうやら gattlib のログ出力はビルド時に決定するもので、デフォルトは syslog だそうだ。
ライブラリの各 API が出力するログレベルについては GATTLIB_LOG_LEVEL で決めることになりそう。

sudo apt install libbluetooth-dev libreadline-dev libglib2.0-dev libpcre3-dev
git clone https://github.com/labapart/gattlib.git
cd gattlib
git checkout -b v0.7.2 refs/tags/0.7.2
mkdir build && cd build
cmake -DGATTLIB_LOG_LEVEL=3 -DGATTLIB_LOG_BACKEND=printf ..
make

前回は cpack で ZIP圧縮して $HOME/.local/ 以下に展開したのだが、 共有ライブラリは自分でインストールしたファイルのパスを検索してくれない。
開発が終わったらシステムに展開しても良いが、当面は LD_LIBRARY_PATH=$HOME/.local/lib などと設定して自前で対処する。

開発中はライブラリからもログが出た方がわかりやすい(個人の感想)ので、 システム側にはログ出力無し版、ローカルにはログ出力あり版をインストールして使い分けるとよいのか。

ble_scan の接続が不安定?

ログを出力するようになって接続できる確率が上がったような気がする(気のせいかもしれない)。
スキャンされている peripheral はこちら。

期待通りに動作した場合、スキャン、接続、サービスやキャラクタリスティックの検出、切断、が全部行われる。

------------START xx:xx:xx:xx:xx:xx ---------------
Connecting bluetooth device xx:xx:xx:xx:xx:xx
gattlib_device_set_state:/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX: Set state CONNECTING
DBUS: device_property_change(/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX): Connection
DBUS: device_property_change(/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX): Service Resolved
gattlib_device_set_state:/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX: Set state CONNECTED
services_count=4
service[0] start_handle:16 end_handle:19 uuid:a00c1710-74ff-4bd5-9e86-cf601d80c054
service[1] start_handle:10 end_handle:14 uuid:00001523-1212-efde-1523-785feabcd123
service[2] start_handle:1b end_handle:1c uuid:8d53dc1d-1db7-4cd3-868b-8a527460aa84
service[3] start_handle:01 end_handle:07 uuid:0x1801
characteristic[0] properties:08 value_handle:0017 uuid:a00c1711-74ff-4bd5-9e86-cf601d80c054
characteristic[1] properties:08 value_handle:0019 uuid:a00c1712-74ff-4bd5-9e86-cf601d80c054
characteristic[2] properties:08 value_handle:0014 uuid:00001525-1212-efde-1523-785feabcd123
characteristic[3] properties:12 value_handle:0011 uuid:00001524-1212-efde-1523-785feabcd123
characteristic[4] properties:14 value_handle:001c uuid:da2e7828-fbce-4e01-ae9e-261174997c48
characteristic[5] properties:02 value_handle:0007 uuid:0x2b2a
characteristic[6] properties:0a value_handle:0005 uuid:0x2b29
characteristic[7] properties:20 value_handle:0002 uuid:0x2a05
Disconnecting bluetooth device /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX
DBUS: device_property_change(/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX): Disconnection
gattlib_device_set_state:/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX: Set state DISCONNECTING
gattlib_device_set_state:/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX: Set state DISCONNECTED
------------DONE xx:xx:xx:xx:xx:xx ---------------
Close bluetooth adapter hci0

接続できない場合は “Device connected error” になっている。

------------START xx:xx:xx:xx:xx:xx ---------------
Connecting bluetooth device xx:xx:xx:xx:xx:xx
gattlib_device_set_state:/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX: Set state CONNECTING
DBUS: device_property_change(/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX): Connection
Device connected error (device:/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX): GDBus.Error:org.bluez.Error.Failed: le-connection-abort-by-local
gattlib_device_set_state:/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX: Set state DISCONNECTED
Gattlib connection not initialized.
Fail to discover primary services.
Cannot disconnect - connection parameter is not valid.
Failed to disconnect from the bluetooth device 'xx:xx:xx:xx:xx:xx'(ret=1)
Failed to connect to the bluetooth device 'xx:xx:xx:xx:xx:xx'(ret=268485668)
------------DONE xx:xx:xx:xx:xx:xx ---------------
Close bluetooth adapter hci0

考察

“Device connected error” はここで出力している。

最後のエラー値 268485668 = 0x1000C424 は、0x1000_0000GATTLIB_ERROR_DBUS グループ、0xc4 がドメイン。
errorGError なのでドメインというのはGLibのエラードメイン だろう。

#define GATTLIB_ERROR_DBUS_WITH_ERROR(error) \
	(GATTLIB_ERROR_DBUS | (error->domain << 8) | (error->code))

“le-connection-abort-by-local” は GError なので Bluez か。 ERR_LE_CONN_ABORT_BY_LOCAL に対応するメッセージである。

local だから Raspberry Pi の方が停止させた?
“connection parameter is not valid” なので相手からの接続パラメータがおかしかったのかと思ったが、 これは gattlib_disconnect() で切断しようとしたけど引数が NULL だったというパラメータなので関係ない。

dmesg でも何か出力されているわけではない。

journalctl -u bluetooth では No matching connection for device というログが出ていた。 これは Bluez が出力しているようだが正常に終わった場合も出力されているのでひとまず無視だ。

だいたい接続できていないのに “Fail to discover primary services.” が出力されているということは、 gattlib_connect() がコールバック関数を接続していないのに呼び出しているということだ。
関数コメントには connect_cb is the callback to call when the connection is established と書いてあるので、ここがまず期待した動作になっていない。
ひとまずコールバック関数の on_device_connect()gattlib_connection_t* が NULL かどうかはチェックしよう。

そうするとこんなログになる。
gattlib のログと自分のログの見分けが付かないが、これは syslog で出力する前提だからかもしれない。

------------START xx:xx:xx:xx:xx:xx ---------------
Connecting bluetooth device xx:xx:xx:xx:xx:xx
gattlib_device_set_state:/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX: Set state CONNECTING
DBUS: device_property_change(/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX): Connection
Device connected error (device:/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX): GDBus.Error:org.bluez.Error.Failed: le-connection-abort-by-local
gattlib_device_set_state:/org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX: Set state DISCONNECTED
Fail to connect device.
Failed to connect to the bluetooth device 'xx:xx:xx:xx:xx:xx'(ret=268485668)
------------DONE xx:xx:xx:xx:xx:xx ---------------
Close bluetooth adapter hci0

結局のところ、”le-connection-abort-by-local” 以上の内容はログからは分からない。

考察2

正常に動作した際の最後のログが “Adapter cannot be closed as some devices are not disconnected” になっていることがある。 gattlib_adapter_close() が出力しているのだが、まだ peripheral が切断処理中なのに呼び出したせいかもしれない。
このログで終わったときにもう一度 ble_scan を実行するとエラーになるのでは!

・・・と思ったが、関係なかった。
もちろん、正常に終了したあとに実行してもうまくいったりいかなかったりで関係なさそう。

実行する間隔が短いとか長いとかでエラーになるのではとも思ったが、関係なさそうだ。

おわりに

分らぬ。全く何事も我々には判らぬ。。。
今回はこのくらいにしておこう。

gattlib は直接関係ないんじゃないかという気はしている。

Bluez のバージョンは 5.66 だった。

$ dpkg -l | grep libbluetooth-dev
ii  libbluetooth-dev:arm64               5.66-1+rpt1+deb12u2                 arm64        Development files for using the BlueZ Linux Bluetooth library

今日時点での最新バージョンは 5.82だ。
5.66 は May 4, 2023 ということでもうすぐ 2年前ということになる。 勝手にアップデートして良いものだろうか。

README を見て気付いたが bluez は別パッケージなのか。

$ dpkg -l | grep bluez
ii  bluez                                5.66-1+rpt1+deb12u2                 arm64        Bluetooth tools and daemons

バージョンはどちらも 5.66 なのだが依存があるわけではなさそうだ。
両方アンインストールして configure --enable-library するのがよいか。

$ sudo apt remove libbluetooth-dev
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
  libbluetooth-dev
0 upgraded, 0 newly installed, 1 to remove and 4 not upgraded.
After this operation, 884 kB disk space will be freed.
Do you want to continue? [Y/n]
 $ sudo apt remove bluez
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
  bluez pi-bluetooth pulseaudio-module-bluetooth
0 upgraded, 0 newly installed, 3 to remove and 4 not upgraded.
After this operation, 5549 kB disk space will be freed.
Do you want to continue? [Y/n]
$ sudo apt install libdbus-1-dev libudev-dev libical-dev
$ git clone https://github.com/bluez/bluez.git
$ git checkout -b v5.82 refs/tags/5.82
$ ./bootstrap
$ ./configure --enable-library
$ make
$ sudo apt remove libbluetooth-dev bluez
$ sudo make install
$ ldconfig
$ /usr/local/bin/bluetoothctl --version
bluetoothctl: 5.82
$ sudo systemctl daemon-reload
$ sudo systemctl restart bluetooth

アップグレードは成功したが ble_scan は 3回くらいやったらエラーが起きた。
原因は別にあるかー。


 < Top page


コメント(Google Formへ飛びます)

GitHub

X/Twitter

Homepage