hiro99ma blog

Something technical

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

アプリを作るならライブラリをどこかにまとめないと面倒だ。
cmakecpack という組み合わせでパッケージを作ることができるそうだ。
デフォルトだと 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 を流用できた。


 < Top page


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

GitHub

X/Twitter

Homepage