FreeBSDでBluetooth Low Energy(BLE)を動かしてみる

日本語として不正確な気もしないでもないですが、技術者な皆さんなら意味は伝わるだろうということで。あと、厳密にはFreeBSDではなくGhostBSDです（ただし、FreeBSDになくてGhostBSDにある機能を使っているわけではないので、FreeBSDでもここに書いた内容は変わらないはず）。

# 用意するもの

- FreeBSD 13[^bug]

<details><summary>12系統のFreeBSDだと、BLEデータの解析処理にバグがあって受信データがまともに表示できません。</summary>13だと大丈夫です。なのでGhostBSDのlatestを使ってます。が、もしかしたら、今だとlatestでなくてもFreeBSDの13系統を使うようになっていて大丈夫かもです。が、そこを確認するほどの元気はありません。</details>

- BLEが受信できる何か

<details><summary>無線レシーバーとか呼ばれるものです。</summary>手元のは多分[BUFFALO製の無線レシーバー](https://www.buffalo.jp/product/detail/bsbt4d200bk.html)かなと思いますけど、これもそれ以上調べる元気はありません。</details>

- BLEが発信できる何か

<details><summary>ビーコンとか言うものでしょうか。</summary>手元にあるのはCYALKIT-E02ですね。そのうち丸い方。</details>

[^bug]: え、「こんなところでグダグダ言ってないで、本家にバグ報告しろ」と？してますよ。でも信用されてないのかバグ報告が下手なのか未だに対応されてないのです:sob:。ま、13では動くわけですから、12にこだわるわけでなければ、急いで直してもらわなくても、、、、ちなみに、12と13だとこの辺りのコードは大幅に違いますので、13から12へのバックポートというのもあまり期待はできないかな、と。バグ報告に12向けのパッチもつけてはいるのですが、、、

# やりかた
とりあえず、（必要ならBLEが受信できる何かを挿して）以下のようにすれば何か表示されます、すなわち動作には成功、ばんざーい。

```コマンドラインの例
dmsg
sudo ngctl list
sudo hccontrol le_enable enable
sudo hccontrol le_set_scan_param passive 10 10 public all
sudo hccontrol le_set_scan_enable enable
hccontrol read_neighbor_cache
```
FreeBSD 12（を使っているGhostBSD）の頃はこの前に

```
sudo kldload ng_ubt
```

というのも必要でした。が、FreeBSD 13（を使っているGhostBSD）では「すでにロード済み」と怒られましたので、外しています。これがGhostBSDの親切設計によるものかFreeBSDのバージョンの違いによるものかはよく分かっていません。なので、もし「ここに書かれているようにやってみたけど上手く行かない」という場合には"kldload"を試してみる価値はあると思います。

これだけだと投稿数稼ぎに見えるので、以下に各コマンドの詳細のようなものを。

## dmsg
必須ではないと思います。「BLEが受信できる何か」が挿されたことをFreeBSDがちゃんと認識しているのか（念のため）確認しています（ということだと思います）。手元では以下のような表示が増えました。

```結果
ugen0.2: <vendor 0x0a12 CSR8510 A10> at usbus0
ubt0 on uhub2
ubt0: <vendor 0x0a12 CSR8510 A10, class 224/1, rev 2.00/88.91, addr 2> on usbus0
```

USBにBluetoothの何かが挿されたよと表示されているのだと思います。

## sudo ngctl list
これも必須ではないと思います。「BLEが受信できる何か」が挿されて、BLEのデータを処理する基盤となる仕組みが整ったことを（念のため）確認しています（ということだと思います）。手元では以下のように表示されました。

```
There are 8 total nodes:
  Name: btsock_hci_raw  Type: btsock_hci_raw  ID: 00000002   Num hooks: 1
  Name: btsock_l2c_raw  Type: btsock_l2c_raw  ID: 00000003   Num hooks: 1
  Name: btsock_l2c      Type: btsock_l2c      ID: 00000004   Num hooks: 1
  Name: btsock_sco      Type: btsock_sco      ID: 00000005   Num hooks: 0
  Name: ubt0            Type: ubt             ID: 00000013   Num hooks: 1
  Name: ubt0hci         Type: hci             ID: 00000015   Num hooks: 3
  Name: ubt0l2cap       Type: l2cap           ID: 00000019   Num hooks: 3
  Name: ngctl8221       Type: socket          ID: 0000001f   Num hooks: 0
```

「btなんとか」とかそれっぽいものが表示されていますので、準備はできているということなのではないでしょうか。

## sudo hccontrol le_enable enable

これはコマンド名(le_enable)の通り、BLEの機能を有効にするということなのでしょうね。"LE enabled"と表示されました。

## sudo hccontrol le_set_scan_param passive 10 10 public all

これもコマンド名(le_set_scan_param)の通り、BLE関連のパラメータを設定しているということなのでしょう。個々のパラメータの意味はよく分かってません。それに特に応答もありません。が、結果的には動いているっぽいので、まあいいかな、と。

## sudo hccontrol le_set_scan_enable enable

これもコマンド名(le_set_scan_enable)の通り、BLEのスキャンを有効にするということなのでしょう。"LE Scan: Enabled"と表示されました。

## hccontrol read_neighbor_cache

これはsudo不要です。readするだけだからでしょうか。手元では以下のように表示されました。

```
T BD_ADDR           Features                Clock offset Page scan Rep. scan
P 00:a0:50:06:14:1b 00 00 00 00 00 00 00 00            0      0xbe         0
	Flags: 04 
	Manufacturer: Apple, Inc.
	Manufacturer specific data: 02 15 00 05 00 01 00 00 10 00 80 00 00 80 5f 9b 01 31 00 01 88 67 c3 
```

Manufacturerに"Apple, Inc."なんて表示されてしまっていますが、そんなお金持ちではありません。これはCYALKIT-E02の初期設定が適当で、そのまま動かすと"Apple, Inc."の番号を使っていることになってしまうからです。なので、発信されているデータをちゃんと受信してちゃんと解析できているという意味では「正しく」動作しています。
CYALKIT-E02（の丸くない方、四角い方）を使えば、その辺りの値を修正できるはずなので、頑張ればいいのですが、今のところそこまでの元気はありません。

# 参考

参考にしたのは以下のサイト（のはず）です。

https://ror.hj.to/ja/issei/entries/j9x7fl-p207l8guqdud/node