2013/12/08

[ble]BLEのホッピング

Bluetoothは、1つの周波数を使って通信するのではなく、ある程度の範囲の周波数をチャネルに区切り、動的にチャネルを切り替えながら通信を行うらしい。
これを「ホッピング」などと呼ぶそうだ。
あまりわかっていないので、調べておこう。

Core_V4.1[pdf]が出てるけど・・・まだCore_V4.0[pdf]の資料で見ていきます。


BLEは、チャネルが40(0~39)ある。
そのうち、37, 38, 39chはAdvertising専用。
残りの0~36chがデータ通信用。

image

(Core_V4.0[pdf] p.2199)

RFのチャネル番号と、Data/Advertisingのチャネル番号は異なるようだ。
以下は、Data/Advertisingのチャネル番号で表現しよう。

 

PDUの種類も、Advertising channel用とData channel用の2種類に分かれている。
今回調べたいものは通信中だから、Data channel用のPDUになる。


channel selection algorithm

image

(Core_V4.0 p.2239)

 

image

(Core_V4.0 p.2212)

 

Data channelは37個あるが、それは状態を持っているようだ。
状態のテーブルがあって、"used"とか"unused"とかが割り当てられている感じがする。
次に使うチャネル番号を決めるときは"unused"となっているものの中から選んでいくけど、37回やると全部"used"になってしまうから、計算式で計算されたチャネル番号の状態を"unused"に戻していく。
それを「channel selection algorithm」と呼んでいるのだろう。

channelについては、「4.5.8.1 Channel Classification」に説明があった。
Data channelは「used channels」(used for the connection)と「unused channels」(not used for the connection)があり、これを「channel map」と呼んでいるそうだ。
used=使ってよい、unused=使うな、という意味か。
そして、used channelsの最小数は2、とある。つまり、最低でも2ch分は空いていないといかんということか。

このmap情報は、Link層が管理していて、masterが用意し、slaveはそれを受けとって使うそうだ。
最初は、CONNECT_REQ PDUに載せ、変更するときはLL_CHANNEL_MAP_REQ PDUを使うみたい。

 

数式としては以下の2つだけだ。

unmappedChannel = (lastUnmappedChannel + hopIncrement) % 37  ... (1)
remappingIndex = unmappedChannel % numUsedChannels ... (2)

"unmappedChannel"は、現在のところ未割り当てになってるチャネル番号。
上記の計算で、次に未割り当てにするチャネル番号を決める。
"lastUnmappedChannel"は、文字通り、最後に「unmapped」にしたチャネル番号で、最初は0。

1イベントが終わったら、式(1)でunmappedChannelを計算する。
unmappedChannelの状態が"used"だったら、そのチャネル番号をData channelとして使う。
状態が"unused"だったら、式(2)でremappingIndexを計算。

この"remappingIndex"は状態のテーブルとは別で、"used"になってるチャネル番号のものを集めたテーブル用の番号だ。
そのテーブルからremappingIndexのところにあるチャネル番号をData channelとして使うことになる。

 

訳してみたが、あってるだろうか?
実際に計算してみよう。
37チャネルでやると大変だから、5チャネルにしてやってみるか。
hopIncrement=1にしておこう。

mapped 0 1 2 3 4
state used used unused unused used

まず、最初はlastUnmappedChannelが0なので、0chを使う。

mapped 0 1 2 3 4
state used used unused unused used

0chが終わったので、計算。

unmappedChannel = (0 + 1) % 5 = 1

次は1chを使う。

mapped 0 1 2 3 4
state used used unused unused used

1chが終わったので、計算。

unmappedChannel = (1 + 1) % 5 = 2

あら大変、2chは「unused」だ。
このときは式(2)を使う。

remappingIndex = 2 % 3 = 2

remap 0 1 2
ch 0ch 1ch 4ch

remappingテーブルの2番目は4chなので、次は4chを使う。

mapped 0 1 2 3 4
state used used unused unused used

4chが終わったので、計算。

unmappedChannel = (4 + 1) % 5 = 0

また0chに戻る。


そんなわけで、ホッピングするチャネルを知るためには、masterからslaveに渡されるチャネルマップとhopIncrementを取得すれば良いことになる。

CONNECT_REQ PDUなるものがあるらしいので、見ておこう。
これは接続時のものなので、Advertising用のPDUだ。

image

(Core_V4.0 p.2206)

image

(Core_V4.0 p.2207)

ここの、ChMとHopがそうだ。
5octで40bitだから、それぞれに1/0を立てていくんだろう。

では、SensorTagで実際にキャプチャしてみよう(iPad mini old)。


image

最初が1Fだから、3bit分抜かれている。Advertising用だろうな。
37~39chなので一番最後だが、Bluetoothは並びがLittle Endianだから、先頭のb7~5ビットに0が入っているのだろう。
hopIncrementは8。

image

8 --> 16 --> 24 --> 32、ときて、次は40だけど37でmoduloして余りが3だから、3ch。

うん、解釈は間違ってないようだ。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。