Flutterアプリを設計している中でbluetoothを扱うケースが多いが、bluetoothの信号の伝達シーケンスは、アンドロイドとLinuxで相違がある。特にlinuxの場合は接続シーケンスにおいてflutter_blue_plusとBlueZ daemonの間での状態の不一致が多々発生し、この状態不一致を許容し包括するための設計にはかなり苦労している。この状態不一致の主な要因は、Linuxではbluetoothの管理において「分散型」の設計となっているためであり、この点を少々調査解析する。
<Linuxの場合の簡略信号伝達シーケンス>
Flutter App (Dart)
│
▼
flutter_blue_plus_linux
│
▼
D-Bus
│
▼
bluetoothd (BlueZ daemon)
│
▼
Bluetooth Controller Chip
│
▼
BLE Device
<Androidの場合の簡略信号伝達シーケンス>
Flutter App (Dart)
│
▼
flutter_blue_plus
│
▼
Bluetooth Service
│
▼
Fluoride (旧BlueDroid)
│
▼
Bluetooth Controller Chip
│
▼
BLE Device
flutter_blue_plus_linux は D-Bus を使って BlueZ と通信しているが、その通信キャッシュの_client.devices の更新タイミングが両者の間で一致しないことが多々ある。また、BlueZの状態遷移が不安定なような挙動を目撃することがある。これを認識してその補償方式を構築していく必要がある。
Androidではflutter_blue_plusが通信キャッシュにてBluetooth Service以下と通信しているが、この通信キャッシュはflutter_blue_plusではハンドリングできないような仕組みである。換言すれば、OSが一貫してbluetoothの状態を管理しており、アプリ側とOS側(bluetoothデーモン側)の間での状態不一致が発生する頻度は非常に低い。
Flutterアプリの検証においても、Linuxにおいては『BLEデバイスがアプリ側のscanで見えたのに内部Deviceリストに存在しない』というような問題が多々発生するが、Androidでは発生したことがない。このためLinuxにおいては、bluetoothのscan/connect/discover/disconnectの通信シーケンスの確立および補償処理には非常に苦労している。
今後は、WebSocket方式あるいはUnix Domain Socket方式を使ってFlutterアプリ側とbluetooth管理側を『分離』して、通信の安定性を向上させることを計画する。
