BGAPIのサンプルコードの解析と GATT の勉強で見通しができてきたので、メモしておきます。
iBuffaro の BSHSBTPT01BK は SIG が規定する Proximity プロファイルに対応しています。
そこで、Proximity プロファイルの Imediate Alert Service (IAS) のクライアントを BLED112 を使って実装してみます。
IAS とは、キータグのようなサーバに対してアラートレベルの値を送信すると、サーバはその値に応じた動作をするサービスです。BSHSBTPT01BK では次のような動作をします。
Alert Level の値 | BSHSBTPT01BKの動作 |
0x00 (No Alert) | 動作なし(あるいは動作停止) |
0x01 (Mild Alert) | バイブレーション |
0x02 (High Alert) | ブザー鳴動 |
サーバが保持する上記のような値は「特性値」と呼ばれます。
アラートレベルの送信手続きは "WriteWithoutResponse" を使うことが規定されています。
これはクライアントがサーバに値を書き込む際にサーバからの応答がないことを表しています。
IAS サービスと、アラートレベルの特性値の UUID は以下の値が規定されています。
Imediate Alert Service | 0x1802 |
Alert Level | 0x2a06 |
通常の UUID は 128ビット(16バイト)で与えられますが、上記は SIG が定める 16ビットの特殊な UUID になっています。
さて、BLED112 を制御する BGAPI では、次のような流れで行うようです。
以下、すでにサーバ(BSHSBTPT01BK)と クライアント(BLED112) の間でコネクションが成立しているものとし、いずれもクライアントがサーバに対して行う処理を想定します。
(1) サーバのプライマリサービスを検索し、目的のサービス(今回は IAS)の UUID を持つものを調べ、その際のハンドルの領域(目的のサービスのはじめのハンドルから終わりのハンドル)を取得する。
(2) ハンドルの領域内で目的の特性値の UUID を持つものを調べ、そのハンドルを決定する。
(3) ハンドルを使って特性値の処理 (今回は WiteWithoutResponse) を行う。
結論を言ってしまうと、BSHSBTPT01BK では Alert Level のハンドルは 0x0d (13) となっていました。
BSHSBTPT01BK 限定ならばハンドル 0x0d を使っていきなり (3) でも問題ありません。
(もちろん、他のキータグではハンドルは別の値になっていることが予想されるので、これはなりたちません)
BGAPI で WiteWithoutResponse を行う関数は次の通り:
ble_cmd_attclient_write_command(connection,atthandle,data_len,data_data)
従って、次のような実装となりました。
(主要部分のみ抜粋)
uint16 handle_alert_level = 0x0d; // アラーとレベルのハンドル uint8 alert_level = 0x02; // 0x00:No Alert, 0x01:Mild Alert, 0x02:High Alert // コネクション状態が変化したときに呼ばれるコールバック関数 void ble_evt_connection_status( const struct ble_msg_connection_status_evt_t *msg ){ if (msg->flags & 1) { // 新規コネクション ble_cmd_attclient_write_command( msg->connection, // コネクションのハンドラ handle_alert_level, // アラートレベルのハンドル 1, // 書き込むバイト列のサイズ(バイト数) &alert_level // 書き込むバイト列(のポインタ) ); } }
ソースコードの全体は後日公開します。
GATT の規定等は以下を参照
Bluetooth GATT | Specifications | Bluetooth Development Portal