ncs: どのくらいserviceの実装に書くのか
2024/09/25
BLEのサービスは、主に ATT の定義を規定して、それに沿って実装していくだろう。
ATT に書き込むとどうだとか、読み込むとどうだとかあるとは思うが、それは実装した後のことで Central と Peripheral としては ATT 定義を信用して作業することになる。
そうなると、ncs で service の実装をするとき、ATT の部分を処理するところと、その前後で処理をするところに分けられるだろう。
このサービスはこの Peripheral でしか動かないからサービスと一緒にハードウェアの処理も実装してしまえ、なんて考えてしまったので反省するために文章としてつらつらと書くことにした次第である。
まあ、どこででも言われる、実装はなるべく疎結合にしておけ、というやつだ。
わかっているつもりだけどやってしまうのは、わかってないんだろうなぁ。
nrf のサービス実装を見てみる
せっかくなので既存の実装を見ておこう。
LBS
- lbs.c
- ボタンをポーリングで読むかどうかで Characteristic の実装が違う
- ポーリングの場合は
read_button()
とグローバル変数button_state
を使う- ボタンの読み込みが発生したとき
button_state
にコールバックの戻り値(ボタンの読み込み結果を返す想定だろう)を行った後bt_gatt_attr_read()
を行う(コード) - bt_gatt_attr_read()は第3引数
buf
を更新する
- ボタンの読み込みが発生したとき
- ポーリングの場合は
- ボタンをポーリングで読むかどうかで Characteristic の実装が違う
BMS
- bms.c
- Characteristic 定義には
user_data
はNULL
bt_gatt_attr_read()
でもuser_data
は出てこない
- Characteristic 定義には
NUS
- nus.c
user_data
は出てこないしbt_gatt_attr_read()
もない
user_data
LBS は グローバル変数のbutton_state
は更新しかしないというのがあやしい。
予想ではBT_GATT_SERVICE_DEFINE()
でCharacteristic定義のBT_GATT_CHARACTERISTIC()
最後のパラメータ”user_data”がattr->user_data
になる、だ。
bt_gatt_attr_read()
の説明には「Read attribute value from local database storing the result into buffer」などと書いてあるが、local database ってどこにあるんだ、となるではないか。
DevAcademy BLE Lesson 4 Exercise 2 のコードを使って確認しよう。
この辺にattr->user_data
とbutton_state
のアドレスを出力させる。
<inf> Lesson4_Exercise2: attr->user_data=0x0x200032bd, &button_state=0x0x200032bd
うむ、予想通り一致した。
user_data
を使ったりグローバル変数の方を使ったりとまちまちなのは何でだろう?
この表を見ると type によって user_data
の意味が違うようだ。
自分でサービスを制御する場合はどうでもよいけど、CCCD みたいにお任せするときは適切なデータが入っているようになっているのだろう。
しかしこの表は GATT Client の方にあるのだが GATT Server でも同じと思っていてよいのだろうか。
ページが広すぎてとても読みきれない。。。
おわりに
- サービス定義はハードウェアに依存しないようにしよう
- そういう部分はコールバックで相手に任せるべし