hiro99ma blog

Something technical

ble: gattlib (3)

2025/04/05

はじめに

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

現状の問題点

失敗してもコールバック関数が呼ばれるのはたぶん仕様

gattlib_connect()が入口なのだが、 非同期になってあちこち飛ぶ。
たぶんここでエラーの時は第1引数をNULLにしてコールバックしているのだろう。

なので、接続エラーでコールバック関数が呼ばれるのはたぶん仕様だ。
後日に間違っていることに気付いたら記載を修正しよう。

接続失敗はリトライ

ときどき接続に失敗するというのは嫌な話だ。
機器が遠いとかなら仕方ないが RSSI が -75 dBm 付近というのはそんなに悪くないと思う。

ぐだぐだ言っても仕方ないので、困ったときのリトライ処理を入れることにした。
接続失敗でコールバックが呼ばれるが gattlib_connect() の戻り値もエラーになるのでリトライできるのだ。

今のところ 3回程度リトライすればエラーの後に接続はできている。

なぜ失敗するのか

リトライするのは悪い考えではないが、そもそもこんなに接続に失敗するようなものではないと思う。

前者は試すことはできるのだけど、性能ってなんだよっていう気もする。
うちの RasPi は WiFi を使っていないので RF 方面で衝突とかはないと思う。 ハードウェアとしてオフにはなっていないかもしれないが、それでも受信しかしてないよな・・・?

Android というか nRF Connect アプリではすぐ接続できるのだが ble_scan は結構もたつく感じがある。
モバイルだから Bluez などとは違う系統なんだろうか?

Linux の Bluetooth は私がよく知らないので他の環境と比較ができない。

HCIのログ

hcidump でログが取れるそうなのでやってみた。

$ hcidump

なんとなくだが、正常時のログはこう。

接続に失敗する場合、この間に別の HCI Event が挟まっていた。
HCI を使っているアプリは ble_scan だけなので、これが何かやっているということだ。

私としては全部スキャンが終わってから接続しているイメージだったのだけど、 pthread とかコールバックとかやっているせいでうまくいっていないのか。

Copilot にか Gemini にかレビューをしてもらったときに、 意図的かもしれないけど同期が取れてないところがあるよ、 みたいなことが書いてあったのでそのまま反映させたのだ。
そういうのがよくなかった?
いや、それは接続に失敗したから追加したんだったと思う。

コードを見ると、確かにスキャンでデバイスが見つかったら pthread_create() でそれぞれ処理させているだけだな。 pthread_mutex_lock() で縛ってはいるようだけど、うまくいってない?

はい、コードを見ずに使っているのは良くないですね。
ちゃんと調べます。。。


 < Top page


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

GitHub

X/Twitter

Homepage