前回の「ラズパイでBLEタグ - REX-SEEK2 Bluetooth+LE対応 紛失防止タグを使う(その1)」では、
REX-SEEK2をラズパイから制御する方法として、デバイスアドレスの取得、設定情報の取得、
ブザーを鳴らす、LEDを点灯させるといったことを紹介しました。
引き続き REX-SEEK2をラズパイから制御する方法について紹介します。
REX-SEEK2 Bluetooth+LE対応 紛失防止タグ
今回は、REX-SEEK2のボタンが押されたことを検出する方法です。
■通知(Notify)について
前回の「ラズパイでBLEタグ - REX-SEEK2 Bluetooth+LE対応 紛失防止タグを使う(その1)」では、クライアント(ラズパイ)がGATTプロトコルの[Read Characteristic Value][Write Characteristic Value] を使ってREX-SEEK2のCharacteristic値の取得、設定情報を読み出し、設定値の書込みでブザーを鳴らす、LEDの点灯などを行いました。
今回のREX-SEEK2のボタン押下の検出では、ボタン押下は任意のタイミングで発生します。
このような任意のタイミングで発生するイベントを処理するにはGATTプロトコルの[Notify Characteristic Value] を使います。
前回紹介した [Read Characteristic Value] では、
(1) クライアントからサーバへリクエストを送る
(2) クライアントはサーバからのレスポンスが返るのを待ってブロックされる
(3) サーバがクライアントにレスポンスを送る
(4) クライアントがレスポンスを受取ってブロックから抜け出す
(5) レスポンスに対応した処理を行う
というように、リクエストとレスポンスが一対一に対応した流れで処理が終わります。
一方、[Notify Characteristic Value]では、
(1) クライアントからサーバへ通知が行われるよう設定する
(2) イベントが発生したタイミングでサーバからクライアントへ一方的に通知が行われる
(3) クライアントが通知を受け取った処理を行う
(4) 新たなイベントが発生し、サーバからクライアントへ通知が行われる
(5) クライアントが新たな通知を受け取った処理を行う
というように、イベントが通知される都度処理が行われます。
したがって、今回のような REX-SEEK2のボタンがどのタイミングで押されるかが分からないようなイベントの通知には、この[Notify Characteristic Value]が適しています。
この通信では、サーバ側でデータの準備できたタイミングでデータが転送されるため、クライアントが予期しないデータを通知されないように、サーバからの通知を許可する・許可しないをあらかじめサーバに対して設定しておきます。
そのための機能が次で説明する CCCD です。
■CCCD(Client Characteristic Configuration Descriptor)通知について
さきに説明したNotifyをクライアントが受取るには、前もってサーバ側の CCCD というCharacteristic に対してNotify を許可するフラグに許可を示す「1」を書込んでおく必要があります。
そして、このCCCDには適用されるCharacteristicの範囲があります。
該当のCCCDが属しているCharacteristicのグループ内のみ有効となります。
このNotifyの許可フラグは接続が切れた後も保持されます。
したがって、クライアントで通知の受取が不要なったら、Notifyの許可を無効にする必要があります。
それでは具体的な流れを見ていきましょう。
■REX-SEEK2で通知可能なアトリビュート/属性データについて
すべてのCharacteristicが通知に対応しているわけではありません。
該当のCharacteristicのPropertyが、Notify対応の場合に限ります。
REX-SEEK2では、以下の2つのServiceがNotofyに対応します。
Service:Battery Service / Service UUID: 0x180F
これは、GATTで定義されているServiceです。
Servcie | Characteristic UUID | Properties | Value |
Battery Level | 0x2A19 | Notify, Read | バッテリ電圧計測値 |
Client Characteristic Config Descriptor | 0x2902 | – | Battery Level Serviceに対するCCCD 00:通知無効 01:通知有効 |
Service:SEEK Vender Service / Service UUID: 0x1523
これは、ベンダーユニークとして定義されているServiceです。
Servcie | Characteristic UUID | Properties | Value |
Button Event | 0x1524 | Notify, Read | Button notification |
Client Characteristic Config Descriptor | 0x2902 | – | Button Event Serviceに対するCCCD 00:通知無効 01:通知有効 |
■ハンドル番号の取得
今回対象とするUUIDに対するハンドル番号を取得します。
gatttoolを使って — char-desc コマンドでCharacteristicをスキャンします。
対象とするCharacteristic のハンドル番号とそのCharacteristicが属しているCCCD (UUID=0x2902)のハンドル番号を取得しておきます。
今回の説明で使用するボタン押下の検出では、[Button Event]サービス(UUID=0x1524) が対象となるので、そのCCCD (UUID=0x2902)のハンドル番号が「0x001C」であることがわかります。
■通知(Notify)の許可とREX-SEEK2からの通知の受取
サーバからクライアントへの通知(Notify)を許可するには、gatttoolを使って — char-write-req コマンドで該当Characteristicの値をNotification 有効に変更します。
同時に「-listen」オプションを指定して、通知を待ちます。
書式
sudo gatttool -b C5:E6:B7:56:05:42 -t random --char-write-req -a 0x001c -n 0100 --listen
コマンド | –char-write-req | キャラクタリスティックの値を設定 |
オプション | -b C5:E6:B7:56:05:42 | 対象とするREX-SEEK2のデバイスアドレスを指定 |
-t random | LEアドレスをランダムに指定にする | |
-a 0x001c | UUID「0x2902」のハンドル番号「0x001c」を指定 | |
-n 0100 | 設定する値を指定 | |
–listen | 通知を待つ |
実行後、以下のメッセージが表示されれば設定が有効となり、Notification を受ける準備ができています。
Characteristic value was written successfully
実際にREX-SEEK2のボタンを押して確認してみると、REX-SEEK2のボタンを押す度に以下のようなメッセージが表示されます。
Notification handle = 0x001b value: 01
上記メッセージで受け取った通知イベントのCharacteristicのハンドル番号とCharacteristicの値が表示されています。
以上でREX-SEEK2のボタン押下の通知イベントを取得する手順が確認できました。
次頁から、これまでに確認したことをPythonスクリプトに展開して説明していきます。