ble: gattlib (3)
2025/04/05
はじめに
前回の続きで gattlib で BLE の central 操作するのを検討している。
現状の問題点
- BLEのスキャンはできているが、接続がときどき失敗する
- 接続に失敗してもコールバック関数が呼ばれるのが嫌だ
失敗してもコールバック関数が呼ばれるのはたぶん仕様
gattlib_connect()
が入口なのだが、
非同期になってあちこち飛ぶ。
たぶんここでエラーの時は第1引数をNULL
にしてコールバックしているのだろう。
なので、接続エラーでコールバック関数が呼ばれるのはたぶん仕様だ。
後日に間違っていることに気付いたら記載を修正しよう。
接続失敗はリトライ
ときどき接続に失敗するというのは嫌な話だ。
機器が遠いとかなら仕方ないが RSSI が -75 dBm 付近というのはそんなに悪くないと思う。
ぐだぐだ言っても仕方ないので、困ったときのリトライ処理を入れることにした。
接続失敗でコールバックが呼ばれるが gattlib_connect()
の戻り値もエラーになるのでリトライできるのだ。
今のところ 3回程度リトライすればエラーの後に接続はできている。
なぜ失敗するのか
リトライするのは悪い考えではないが、そもそもこんなに接続に失敗するようなものではないと思う。
- Raspberry Pi 4 のオンボード Bluetooth はあまり性能が良くない
- USBドングルので試してみる
- プロトコルの段階であまりよろしくない
前者は試すことはできるのだけど、性能ってなんだよっていう気もする。
うちの RasPi は WiFi を使っていないので RF 方面で衝突とかはないと思う。
ハードウェアとしてオフにはなっていないかもしれないが、それでも受信しかしてないよな・・・?
Android というか nRF Connect アプリではすぐ接続できるのだが ble_scan
は結構もたつく感じがある。
モバイルだから Bluez などとは違う系統なんだろうか?
Linux の Bluetooth は私がよく知らないので他の環境と比較ができない。
HCIのログ
hcidump
でログが取れるそうなのでやってみた。
$ hcidump
なんとなくだが、正常時のログはこう。
LE Create Connection
LE Read Remote Used Features
Disconnect
接続に失敗する場合、この間に別の HCI Event が挟まっていた。
HCI を使っているアプリは ble_scan
だけなので、これが何かやっているということだ。
私としては全部スキャンが終わってから接続しているイメージだったのだけど、 pthread とかコールバックとかやっているせいでうまくいっていないのか。
Copilot にか Gemini にかレビューをしてもらったときに、
意図的かもしれないけど同期が取れてないところがあるよ、
みたいなことが書いてあったのでそのまま反映させたのだ。
そういうのがよくなかった?
いや、それは接続に失敗したから追加したんだったと思う。
コードを見ると、確かにスキャンでデバイスが見つかったら pthread_create()
でそれぞれ処理させているだけだな。
pthread_mutex_lock()
で縛ってはいるようだけど、うまくいってない?
はい、コードを見ずに使っているのは良くないですね。
ちゃんと調べます。。。