BLE基礎 (4)
2024/08/09
前回 USB-CDCでログ出力できるようにしたが、printk()
はバッファされず、出力し終わるまで戻ってこない関数とのこと。
Linuxでのstderr
みたいなものか。
バッファされるとプログラムの進みとタイミングがずれたりしてわかりづらいだろうってことで Exercise ではprintk()
を使っているのかもしれない。
Lesson 2 – Bluetooth LE Advertising
Advertising についてである。 こちらは Nordic のウェビナーPDF だが、あとで読みたいところである。
Everything you need to know about Bluetooth LE advertising(PDF)
Lesson
内容は読めばよいので、概要だけ。
- Advertising process
- Advertisingってなに?という基本事項
- Advertising types
- Advertisingの種類は4つある
- 3つは例が書いてあるのでなんとなくわかるが
ADV_SCAN_IND
はなんだろう。組み合わせとしてできるから禁止するほどでもないしいいか、って感じだろうか。SCAN_REP
を返すからちょっと情報が多く取得できるとかかもしれない。
- Bluetooth address
- BLEアドレスの種類
- Advertisement packet
- Advertising の PDU(Packet Data Unit)について
- 接続したら GATT でアクセスするけど Advertising は GAP だからプロトコルスタックの図でも GATT と GAP が並列で並んでいるのかな。
- 送信も受信もライブラリがある程度やってくれるだろうが、デバッグするときには知っておいた方が良いのかも。
- 持っているBLEスニファだとこんな感じで取得できる。
- DevAcademyの最後にスニファの章があるので作るコーナーなのかも
- 持っているBLEスニファだとこんな感じで取得できる。
- 構造はともかく、どういうデータが入れられるかとサイズは知らないといかんが、ここにはそこまで詳しいことは書いてない。
Exercise
あとは exercise が 3つとクイズが 1つだ。 exercise で使うリポジトリは問題用と解決済みがあるので、答え合わせできるのがありがたい。
前回の exercise でnRF5340 MDBT53-1Mモジュールピッチ変換基板にLEDを追加したが、overlay で追加したのでそのファイルを持ってこないといかんかった。 ボード定義ファイルにいれるほどではないけど、よく使う設定を再利用したいものだ。 しかしボード定義を増やすのは面倒なので、それなら overlay ファイルをコピーすれば済むだけなのはまだ手軽なのか。
Setting the advertising data
Advertising するだけ。
BT_LE_ADV_NCONNは「Non-connectable advertising with private address」で定義値はここにある。
近くにBT_LE_ADV_PARAM()
を使った定義がいろいろあるが、コードを見ないとなんだかわからないな。
BT_LE_ADV_PARAM()
- 第1パラメータ
0
: non-connectableBT_LE_ADV_OPT_CONNECTABLE
: connectable
- 第2, 3パラメータ
- intervalのmin, max
- 第1パラメータ
ADV_SCAN_IND
とADV_NONCONN_IND
の指定はないので、おそらく response packet を与えているかどうかで判断しているのだろう。
今回は指定しているからADV_SCAN_IND
になっているはずである。
私の使っているBLEスニファーだと ADV_DISCOVER_IND
と表示されているが、Adv PDU Header の Type値が6
なので、Core_v5.1 Vol.6 Part B “2 Air interface packets” の Table 2.3 によると ADV_SCAN_IND
のことらしい(Core_v4.0 だと Table 2.1)。
Dynamically changing the advertising data
パラメータの中の”Manufacturer Specific Data”を動的に更新する。
普通だとbt_le_adv_start()
でパラメータを与えて開始するので、
BT_LE_ADV_PARAM()にmin, maxを指定するが、単位は秒数とかではなく0.625ms
に掛ければ秒数になるという値である。
min <= max になっていればよいらしい。
ここでは min=800
, max=801
なので min=500msec
, max=500.625msec
である。
といいつつ、実際に動かすと 450msec くらいになったりもしていた。 nRF Connect for Mobile を Refresh すると 500msec 付近になっていたから、一度 SCAN が途切れたりして計算がずれただけとかだろうか。
なんでadv_mfg_data
にconst
が付いてないのかと思ったら、adv_mfg_data
のアドレスをad[]
が持っていて、ボタンが押されたらadv_mfg_data
の中身を更新してbt_le_adv_update_data()
するというしくみだからだった。
ただadv_param
はconst
でよいはずだ。そんなに細かく気にするところではないだろうが、RAMは大切だし、初期値持ちになるので Flashにもデータがある。そして初期値をRAMにコピーするという手間もあるので、const
でよいなら付けた方が良いはずだ。
ま、間違ってないよね?? C言語も久々なので弱気になっている。
Exercise 3
接続するタイプの advertising。 LBS を使ったサンプルなので以前と同じ感じになりそうだが、アドレスの変更をやっている。 non-connectable advertising の場合はデフォルトで Non-Resolvable Random Private アドレスだが、connectable advertising の場合は Random Static アドレスだそうだ。
当たり前だが変更はできていた。
パケットとしては AdvA に入っているだけだし、外側からは違いが分からないように見えるが、コア仕様書「Vol.6, Part B, 1.3 Device address」を見ると static, non-resolvable, resolvable の区別は値で付けられている。
ただし Public と Private の区別は付けられないのでどうでもよいのか(2024/09/29:TxAdd
でPublicかRandomかの区別は付く)?
ちなみに Public アドレスの方は「Vol.2, Part B, 1.2」にある。昔は上位24bitが “company_assigned”、下位24bitが “company_id” という名称だったのだが、今は LAP(24bit), UAP(8bit), NAP(16bit) だけになっていた。
サービスのUUIDがBT_UUID_LBS_VALで定義されているので<bluetooth/services/lbs.h>
をincludeしてみたのだが、ビルドエラーになった。
他にもincludeしないと解決できないということか。
nRF Connect for Mobile から CONNECT はできるのだが、Characteristic として出てくるのは 0x1800 と 0x1801 といういつものやつだけで LBS は出てこない。
コールバック関数の登録もないので、接続しても LEDは変化しない。bt_lbs_init()
を呼び出していないからだろう。