BLEは超便利!?My NP1アプリBLE通信で苦労した話
パイオニア株式会社 SaaS Technology Center モバイル開発部プロダクトマネージャー&Androidエンジニアの山本です!
今回は、NP1(エヌピーワン:エッジデバイス)とMy NP1アプリ(スマホアプリ)を接続・通信するBluetooth Low Energy(以下、BLE)について苦労話を語っていこうと思います。
NP1とは?
NP1は今年の3月に発売されたパイオニアの新商品で、音声だけで案内するスマート音声ナビやクラウドドライブレコーダー、定額使い放題Wi-Fiを搭載したパイオニアの全く新しい車用デバイスです。
NP1は画面を搭載しておらず、NP1を操作するには音声やMy NP1アプリを接続して操作します。
その接続や通信でNP1とMy NP1はBLEを採用しています。
My NP1アプリについてはこちら
なぜBLEを採用しているのか?
ひとことで〜
超低消費電力!
一般的にはBluetoothの手別は大きく分けて2種類あって、Bluetooth ClassicとBLEがあります。
スマホアプリでBluetooth Classicを使用すると、スマホのバッテリー残量がすぐなくなってしまうことありますよね。
例えば、Audio機器やヘッドセット、PCとのデータ通信などでずっと繋ぎっぱなしにしておくと、すぐバッテリーがなくなってしまいます。
My NP1はNP1(エッジデバイス)と常時接続することを前提としていますので、すぐバッテリーが切れてしまうとアプリが使えなくなってしまいます。
My NP1ではユーザーのペインを取り除くためにも、BLEを採用することにしました。
BLEってどんな技術?
BLEって実際どういう技術なのでしょうか?
技術的解説を見てみましょう。
特徴は、BTClassicに比べて1/30の超低消費電力で動作できるということです。
その代わり、通信帯域が狭かったり、送信パケットサイズが小さいなどのデメリットも存在します。
また、ペリフェラルとセントラルが分かれていることで、アプリレイヤーでハンドリングしやすいメリットがあります。
このような特徴をうまく使えば、超低消費電力の恩恵を受けながら、データ通信が可能ということになります。
My NP1ではどうやって使っている?
My NP1はNP1(エッジデバイス)と通信をするためにBLEを採用していますが、具体的には下記の機能で使用されています。
My NP1はNP1の設定を行う
NP1が取得した情報をMy NP1へ通知してもらい、画面を変化させる
NP1が取得した情報をMy NP1へ通知してもらい、同期を取る
この3点で使用されています。
例えば「My NP1はNP1の設定を行う」は下記のような画面で使われています。
これは実際にアプリ内でどう処理されてNP1と通信をしているのでしょうか?
My NP1ではModelの中に複数クラスを抱えており、BLEコマンドハブ機能部とBLEコマンド作成部と通信管理部に分けて機能分担処理しています。
Androidにおいて通信管理部はバックグラウンドでの動作をできるように、独立した形(Service)で作成したり、MVVMを少しカスタマイズしました。
My NP1でのBLEの特別な使い方はある?
My NP1で考慮しなければいけないのは、実装難易度を下げながら、セキュアな通信を実現した上で、NP1の状態を把握して接続と通信を行わないといけないということです。
My NP1では設計段階で上記を考慮し、5つの特徴を実装しました。
1:プロトコルバッファでエンコード/デコードしたバイナリを通信をする
通常はBLEで通信する場合は、バイナリデータ(コンピュータが理解しやすいデータ配列のこと)のフォーマットを定義して、その定義に沿ってスマホアプリ側と車載器で個々に実装する必要があります。
しかし、個々で実装した場合、データフォーマットの解釈誤りなど、送受信データをチェックしないといけないため、考慮するものが増え、試験する上でも手間です。
なので、My NP1とNP1(エッジデバイス)では独自の通信仕様をプロトコルバッファで構築し、送受信で使用するコマンド体系を定義することで、データバイナリ上で通信実現しました。
プロトコルバッファを使用することで、データフォーマットの解釈誤り/実装誤りを回避できるようになりました。
2:スキャン時にUUIDフィルタをかける
一般的なデバイススキャンの場合、アプリが接続したいデバイス以外のデバイスまで表示してしまうことになり、ユーザーとしては、たくさんのスキャン結果の中から目的のデバイスを探さなければなりません。
スキャンする際にUUIDフィルタ(Universally Unique IDentifierフィルタ:デバイスを一意に定義するIDをフィルタするもの)を使用して、NP1(エッジデバイス)のみスキャンすることで、ユーザーがNP1を見つけやすくしました。
3:スキャンしたNP1デバイスへの複数のGATT通信を同時に行う
NP1は販売店で取付されることも考慮しなければいけません。販売店の環境は、多数のNP1がペアリング状態である可能性もあります。
2で書いたように目的のNP1を探すために複数のGATT通信を同時に行なっています。
※GATT通信とは:GATT (Generic Attribute Profile)というBLE機器が持つデータ構造とその操作方法を定義したもので通信すること。
詳しい解説はこちら
4:機器登録する前と後で暗号化の仕組みを変える
NP1(エッジデバイス)は機器登録前と機器登録後で暗号化の仕組みが違います。
機器登録後のBLE通信はセキュアである必要があります。
それは、ユーザーを紐づける内容のデータ通信をやりとりするためです。
しかし、機器登録前はユーザーを紐づける内容のデータ通信は行っておらず、BLE通信はセキュアである必要はありません。
そのため、機器登録前と機器登録後で暗号化の仕組みを変えています。
具体的には、NP1の取り付けを行う時は暗号化しておらず、機器登録後、ルート情報などを通信する際などは暗号化された状態となっています。
5:クロージャーベースのI/F思想を導入
MVVMでいうViewからModelへBLEで通信した情報のやり取りを行う際、送受信で使用するコマンド体系(read/write等)を意識して画面操作を行なっていると、画面操作側でリクエスト管理をしなければならなくなり、かなり非効率です。
Viewに近くなればなるほど、送受信で使用するコマンド体系を意識せずデータを簡単にコールバックで受け取れるように、クロージャーベースのコマンド体系I/F思想を取り入れました。
このI/F思想によって、BLEのコマンド体系と画面操作がくっきりと分けられることができるため、ユニットテストの効率化やコーディングの作業分担などが容易に行えるようになりました。
※コールバック:プログラム中で、ある関数などを呼び出す際に別の関数などを途中で実行するよう指定する手法のこと
※クロージャ:組み合わされた(囲まれた)関数と、その周囲の状態の参照の組み合わせのこと
苦労話
いろいろなことを考慮しなければいけない中で、やっぱり苦労したところもありました。
1:車載器との接続確立シーケンスが複雑
先にも書いた通り、機器登録する前と後で暗号化の仕組みを変える以上、NP1(エッジデバイス)の起動モード(機器登録する前と後)が異なるということになります。
それによって、接続のシーケンスを1本では事足りず、2本用意しなければならなくなりました。
起動モードもNP1の側面ボタンで変化してしまうので、My NP1はボタン押下に追従できるようにエラー分岐を複数用意しなければなりませんでした。
2:アクセストークンを利用したBLEコマンドのハンドリング
BLE通信コマンドにアクセストークンを用いたことで、NP1のモードにより使うトークンを変えなければならなくなりました。
機器登録前のトークンは保持する必要ないのですが、機器登録後のトークンは保持しなければならず、アプリ終了後も保持しなければなりません。
この辺の考慮は当たり前なのですが、アプリ終了のハンドリングもしなければならず苦労しました。
他にも、NP1の処理能力を考慮してタイミングのチューニングをおこなったり、機能制限に対するエラー分岐などを考慮しております。
3:デバッグ時の送受信データ解析が難解
BLEの恩恵をうけたことで、検証でも大変なこともありました。
プロトコルバッファを使っているため、アプリ層でのデータハンドリングは便利ですが、通信管理部での解析時の送受信データ解析は逆に難解になります。
通信コマンドをビルドする上では、定義ファイルに従ってプロトコルバッファに任せればいいのですが、バイナリダンプ(バイナリデータの出力)が正しいデータかどうか確認する上では逆にパース(解析)しないといけなくなります。
プロトコルバッファ定義は複数あるので、どの定義ファイルに従っているダンプなのか調査が大変で、バイナリレベルで可読もできないので解析に時間がかかりました。
4:端末による制動の違い
各社スマホ端末でBLEの振る舞いが異なったり、Androidバージョンでも異なり、機種やバージョンに依存しないロジックを検討しなければならず、整合性を合わせるのが大変でした。
1機種のためにロジックを見直さなければならないなど、工数/予算と普及率のトレードオフ関係にも悩まされましたね(笑)
最後に
いかがでしたでしょうか?
BLEを使うってメリットもあるけど大変なこともありますよね。
他にもMy NP1では、レガシーの技術を現代のスマホでも実現できるようにしたり(RTSPを使用した動画ストリーミング再生)、トレンドのアーキテクチャ(navigation・viewbinding・LiveDataなど)を採用したりしています。
この記事が面白いと思っていただけたら、スキやコメントお待ちしております。
モバイル開発部では、パイオニアのスマホアプリのグロースアップに協力してくれる仲間を募集しています。
<パイオニア採用情報>
<カジュアル面談 Meety>
<新入社員とベテラン社員の対談 - モバイル開発のリアル ->