ble: gattlib
2025/03/31
はじめに
最近コーディングというか、製品のコーディングをしていない。
特に作りたいものもないので、ここ1年くらいで調べた範囲で作ることにした。
Raspberry Pi があるので、それに BLE central をやってもらおう。
この時点で調べた範囲に入っていないのだが、まあよい。
gattlib
Bluez を使ってみようと思ったのだが、使うのが難しそうだった。
ラッパーのようになっていて BLE 用の gattlib というものがあったので少し動かした。
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 ..
make
これでサンプルアプリまでビルドされる。
ble_scan はちょっと危険?
ble_scan
を動かしてみた。sudo
なしで動作している。
$ ./examples/ble_scan/ble_scan
Discovered xx:xx:xx:xx:xx:xx - 'Zephyr Heartrate Sensor'
Scan completed
------------START xx:xx:xx:xx:xx:xx ---------------
------------DONE xx:xx:xx:xx:xx:xx ---------------
名前が “scan” なのだが connect もするようだ。
DONE と出力されるのだが Advertising が止まったままなので disconnect しない・・・?
Ctrl+C で終了させてもそのままなので、明示的に切断させないと kernel 側かどこかが維持してしまうようだ。
これ、自動的にスキャンして接続してしかも維持するので、 マンションみたいな集合住宅だと気付かずに見知らぬ人の BLE 機器に接続したままにしてしまいそうだ。
disconnect していないと思ったのは Android の nRF Connectアプリで Advertising が確認できなかったというだけなので、 もしかしたら disconnect していたけど Advertising を止めていただけかもしれない。
全部処理が終わるときに gattlib_disconnect()
を実行して切断するように見えるので、Ctrl+C で止めるのが良くないのか。
いや、全部じゃないな。
1つの機器の接続をして、キャラクタリスティックなどを一通り検出したら disconnect している。
なので接続した状態で Ctrl+C すると切断しないかもしれない。
Bluetooth の一時停止
rfkill
で無線関係の機器をブロックできるそうだ。
$ rfkill
ID TYPE DEVICE SOFT HARD
0 bluetooth hci0 unblocked unblocked
1 wlan phy0 unblocked unblocked
$ rfkill block 0
$ rfkill
ID TYPE DEVICE SOFT HARD
0 bluetooth hci0 blocked unblocked
1 wlan phy0 unblocked unblocked
この状態で ble_scan
するとエラーになるので止まってるだろう。
$ ./examples/ble_scan/ble_scan
** (process:215757): WARNING **: 09:27:09.093: Error setting property 'Powered' on interface org.bluez.Adapter1: GDBus.Error:org.bluez.Error.Failed: Failed (g-io-error-quark, 36)
gattlib_ble_scan: Failed to set discovery filter: GDBus.Error:org.bluez.Error.NotReady: Resource Not Ready (196.36)
gattlib_ble_scan: Failed to scan.
が!
これでも Advertising が始まっていなかった。
接続されたままなのか、peripheral が何かしているのか判断できない。
けれども、Android の nRF Connect で connect / disconnect したときは Advertising が始まっているからなあ。
あー、でも時間が経つと Advertising が自動で止まっている感じもするので断言できない。
Raspberry Pi の再起動をせずに Bluetooth 機能を止めたいだけなので、 一番根っこに近いと思われる systemctl で再起動させた。
$ sudo systemctl restart bluetooth
これで大丈夫な気はするのだが、確実にやるなら USBドングルにして引っこ抜けるようにするべきか。
Linux の BLE ON/OFF 関連コマンド
順番が逆になったが、Linux で使用できる BLE の ON/OFF 制御ができるコマンドを調べておこう。
ハードウェアに近いところになるので、たぶん BLE というよりも Bluetooth 全般になると思う。
rfkill
無線関連の有効・無効関連だけを操作するコマンド。
引数無し, block <ID>
, unblock <ID>
を覚えておけば良いだろう。
list
はちょっと丁寧に出力されるくらいだと思うが同じ Bluetooth でも機器の違いが分かりやすかったりするのかも?
うちには 1つずつしかないので未確認だ。
先ほどは効果がないようなことを書いたが、 Advertising が出ているかどうかを外部から監視しただけなので まだわからない。
hciconfig
sudo hciconfig <device> down
でダウンさせることができる。
これで rfkill
すると “HARD” が blocked になるかと思ったが、そうはならなかった。
sudo hciconfig
での出力は “DOWN” になっていた。
systemctl では止まらない?
` sudo systemctl stop bluetooth` でサービスを止められる。。。
と先ほどまで信じていた。
が、status を見ると active のままだ。
$ sudo systemctl stop bluetooth
$ systemctl status bluetooth
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; preset: en>
Active: active (running) since Tue 2025-04-01 10:37:04 JST; 5s ago
........
しかも、hciconfig
で DOWN させていたのが UP RUNNING に戻ってしまった。
journalctl
で確認すると、Stopping になって Stopped になるが、すぐ Starting になって Started になった。
再起動したなら hciconfig
が UP RUNNING になったのも不思議ではない。
gattlib
アプリを作るならライブラリをどこかにまとめないと面倒だ。
cmake
と cpack
という組み合わせでパッケージを作ることができるそうだ。
デフォルトだと RPM だが Raspberry Pi なので DEB にした。。。
が sudo dpkg
でないと動かないみたい。
cpack
は ZIP でもできるそうだ。
$ cpack -G ZIP -DCPACK_PACKAGE_INSTALL_DIRECTORY=$HOME/.local
CPack: Create package using ZIP
CPack: Install projects
CPack: - Run preinstall target for: gattlib
CPack: - Install project: gattlib []
CPack: Create package
CPack: - package: /home/xxx/gattlib/build/gattlib_0.4-dev_aarch64.zip generated.
$ unzip -l gattlib_0.4-dev_aarch64.zip
Archive: gattlib_0.4-dev_aarch64.zip
Length Date Time Name
--------- ---------- ----- ----
0 2025-04-01 14:35 gattlib_0.4-dev_aarch64/lib/
0 2025-04-01 14:35 gattlib_0.4-dev_aarch64/lib/pkgconfig/
199 2025-03-31 21:46 gattlib_0.4-dev_aarch64/lib/pkgconfig/gattlib.pc
651720 2025-03-31 21:47 gattlib_0.4-dev_aarch64/lib/libgattlib.so
0 2025-04-01 14:35 gattlib_0.4-dev_aarch64/include/
30835 2025-03-31 21:44 gattlib_0.4-dev_aarch64/include/gattlib.h
--------- -------
682754 6 files
lib/
と include/
を $HOME/.local/
の中に展開した。
ためしに ble_scan
のビルドだけやってみた。
以前 Bluez のサンプルをビルドしたときの Makefile を流用できた。