Skip Navigation

Wireless・のおと

サイレックスの無線LAN 開発者が語る、無線技術についてや製品開発の秘話、技術者向け情報、新しく興味深い話題、サイレックスが提供するサービスや現状などの話題などを配信していきます。

前の記事:「SEP2.0のはなし」へ

Bluetooth ACL のはなし

2016年12月19日 11:00
YS
今回は Bluetooth Classic の基本仕様の話です。Bluetooth (ACL) に備わっている複数のフレームタイプは一体誰がどのように選択して使い分けるのか、という単純な疑問を仕様書から読み解いてゆきます。なお本文中 Vol.2 Part.B のような表記で原仕様を示しますが、特に注記のないかぎり Core Spec 4.2 仕様書を出典としています。
ACL フレームタイプ
Bluetooth Classic には ACL (Asynchronous Connection Less) という一般データ用フレームと SCO (Synchronous Connection Oriented) という同期オーディオ用のフレームがあり、ACL には DM(エラー訂正機能:FEC あり) と DH(FEC なし)の2種類があります。これに 625μ秒の「スロット」を幾つ連続で占有するかというスロット数が加わり、「DM1」とか「DH3」のように表記されます。Bluetooth 2.0 で追加された EDR (Enhanced Data Rate) では DH フレームに限って 2 倍速、3 倍速の EDR モードが追加され、2-DH1 とか 3-DH5 のように表記します。これら ACL フレームタイプについての記述は Vol.2 Part.B 6.5.4 にありますが、まとめると次のようになります。

ACLフレームタイプとデータ長

スロット数

1

3

5

BDR FECあり

DM1

1-18 byte

DM3

2-123 byte

DM5

2-226 byte

BDR FECなし

DH1

1-28 byte

DH3

2-185 byte

DH5

2-341 byte

EDR 2Mbps

2-DH1

2-56 byte

2-DH3

2-369 byte

2-DH5

2-681 byte

EDR 3Mbps

3-DH1

2-85 byte

3-DH3

2-554 byte

3-DH5

2-1023 byte


さて Bluetooth ノード同士が通信するとき、これらのパケットタイプはどの階層でどのような基準をもって選択されるのでしょうか。なるべく高速で通信したいから 3-DH5 を名指しで使いたい、というような指定はできるのでしょうか?できるとすれば、どのようにして指定するのでしょうか。
この単純な疑問に対し、Bluetooth の仕様書に「答えはこれです」とは示されておらず、回答となる要素があちこちに散らばって記述されています。「仕様書」だから当たり前なのですが、Bluetooth を取っつきにくくする一要因のように思います(※註)。

※註:まぁ無線通信規格の仕様書なんておおむね不親切無愛想で似たようなものではありますが、それでも Bluetooth は特にわかりにくいと感じます。


L2CAP と ACL の関係
まず最初のヒントは Vol.3 Part.A "Logical Link Control and Adaptation Protocol (L2CAP)" の Section 7.2 "Fragmentation and Recombination" です。Figure 7.2 には L2CAP 層から無線パケットに至るまでの階層図が示されていますが、L2CAP 層の送信要求はいったん複数の HCI パケットに分割されてハードウェア(Bluetooth チップ)に送られ、チップ上のファームウェア(Embedded Software)は HCI パケットを再構成したあとそれを無線パケットとして再分割して送信する様子が示されています。

Bluetooth_L2CAP_ACL_s.jpg
L2CAPからHCIまでのフロー(表示)

HCI と無線パケットは 1:1 ではなく、1つの HCI パケットが複数の無線パケットに分割される(こともある)こと、それはチップファームウェアの Link Manager Link Controller 層によって行われることがわかります。パケットタイプの選択条件は「Assemble 1, 3 & 5 slot packet types as appropriate」とのみ示され、何がどう「appropriate」なのかまでは明示されていません。
選択条件は曖昧ななりに、この段階では「ACL フレームタイプの選択はチップファームウェアで行われ、上位層から直接指定する訳ではないらしい」ことがわかります。

HCI パケットの詳細は Vol.2 Part.E 5.4.2 HCI ACL Data Packets に記されています。HCI 層からチップに渡されるパラメータは Connection Handle, PB Flag, BC Flag, Total Length, Data だけで、フレームタイプを示すパラメータは付加されません。やはり HCI レベルでは ACL フレームの指定はできないことが再確認できます。

では、Bluetooth の ACL フレーム選択は全くもってチップに丸投げで上位層からは一切制御できないのかと言うと、そうとも限りません。幾つか指定可能な仕組みが用意されています。この「幾つか」がまたバラバラに記述されているのでわかりにくいことこの上ないのですが。


まずは Vol.2 Part.E 7.1.5 Create Connection Command。これは L2CAP の接続確立に伴って発行されるコマンドで、TCP でいえば socket connect に相当します。これに呼応して返される Connection Complete イベントの Connection_Handle が HCI ACL Data Packets で指定される Connection Handle になります。
さて Create Connection Command は Packet_Type という 16 ビットのパラメータを伴います。

Create ConnectionコマンドのPacket_Type

0x0001

(Reserved)

0x0100

2-DH3

0x0002

2-DH1

0x0200

3-DH3

0x0004

3-DH1

0x0400

DM3

0x0008

DM1

0x0800

DH3

0x0010

DH1

0x1000

2-DH5

0x0020

(Reserved)

0x2000

3-DH5

0x0040

(Reserved)

0x4000

DM5

0x0080

(Reserved)

0x8000

DH5

 

この Packet_Type は各ビットが対応するフレームタイプの使用可否を示すビットマスクであり、本文中には

The Packet_Type command parameter specifies which packet types the Link Manager shall use for the ACL connection. When sending HCI ACL Data Packets the Link Manager shall only use the packet type(s) specified by the Packet_Type command parameter or the always-allowed DM1 packet type. Multiple packet types may be specified for the Packet Type parameter by performing a bit-wise OR operation of the different packet types. The Link Manager may choose which packet type to be used from the list of acceptable packet types.

という記述があります。Vol.3 Part.A 7.2 で「as appropriate」とのみ記されていた送信フレームタイプ選択条件の一つが「コネクション設立時に上位層から指定された Packet_Type マスク値に合致するフレームタイプである」こと、しかし「DM1 は常に使用可能」として定義されていることがわかります。

Linux の BlueZ では hciconfig <hci> ptype で「パケットタイプの一覧」が表示され、hciconfig <hci> ptype DM1,DH1,DM3,... のようにコンマつなぎの文字列で「パケットタイプの一覧」が指定できることになっています。しかしドキュメント(man hciconfig)にはこれが一体何のためにどう使われるのか明記されていません。実はこの ptype は Create Connection に指定されるパラメータを保持しています。hciconfig ではこれを ioctl HCISETPTYPE としてカーネル内の Bluetooth スタックに渡し、スタックではこれを HCI 固有のデータメンバ hdev->pkt_type に記録します。コネクション作成時にはこの値がコネクション固有のデータメンバ conn->pkt_type にコピーされ、HCI_OP_CREATE_CONN コマンドの発行時にパラメータ構造体 cp.pkt_type に(リトルエンディアン変換されたうえで)改めてコピーされ HCI 経由でチップに渡されます。

なるほどというか、これでフレームタイプを指定するメカニズムがあることがわかりました。ところが、これだけでは済まないのが Bluetooth が一筋縄でゆかないところです。


ACL BDR と EDR について
Packet_Type マスクでは BDR/EDR のフレームタイプが一覧のマスクとして指定できますが、実は Bluetooth の仕様上、通信線路上で BDR と EDR は同時に使用できません。Bluetooth のフレームフォーマットは Vol.2 Part.B 6.4 にありますが、TYPE フィールドには 4bit が割り当てられており 16 種が表現可能です。ACL(BDR) では 4 種(NULL, POLL, FHS, DM1)を固定割付け、残り 12 種のうち 6 種に DH1, AUX1, DM3, DH3, DM5, DH5 を割り当てています。6 種が未割当(undefined)となっているので、そこに EDR の 2-DH1/DH3/DH5, 3-DH1/DH3/DH5 を割り当てればピッタリ収まりそうな気がするのですが、何故か Bluetooth SIG は EDR 拡張時にこの方式を取らず、「PTT」というパラメータによって既存 BDR の既存割り当てを切り替える形で EDR のフレームタイプを割り当てました。

Bluetooth ACLのフレームタイプ

Type

PTT=0

(BDR)

PTT=1

(EDR)

0000

NULL

NULL

0001

POLL

POLL

0010

FHSS

FHSS

0011

DM1

DM1

0100

DH1

2-DH1

0101

undefined

undefined

0110

undefined

undefined

0111

undefined

undefined

1000

undefined

3-DH1

1001

AUX1

AUX1

1010

DM3

3-DH3

1011

DH3

2-DH3

1100

undefined

undefined

1101

undefined

undefined

1110

DM5

2-DH5

1111

DH5

3-DH5


PTT というのは Packet Type Table の略で、その値については Vol.2 Part.C 5.2 LMP Parameter Definitions に示されています。

Name

Len

Type

Detailed

packet type table

1

u_int8

0:1Mb/s only

1:2/3Mb/s

2-255:reserved


しかし既に示したように、Create Connection Command の引数には PTT という値は含まれていません。そもそも PTT はベースバンドリンク(MAC アドレス間)に付随するパラメーターで、論理リンク(≒L2CAP コネクション)毎に設定することもできません。

一体誰がどうやって PTT を設定するのかというと、LMP_packet_type_table_req (Vol.2 Part.C 4.1.11) によって設定されます。EDR を使いたいノードは PTT=1 として LMP_packet_type_table_req を発行し、それが LMP_accepted_ext で返された場合、それ以降ノード間で交換される ACL パケットは DM1 を除いて PTT=1 の EDR パケットに切り替えられます。この切り替えは「ベースバンドリンク」なので送受信両方向に適用され、以降に開設される L2CAP コネクションに限らず、既存の L2CAP コネクションにも全て適用されます(ただし、同期音声用の SCO は ACL とは別に BDR/EDR の切り替えメカニズムを持っています)。

しかし、何だか不便なメカニズムに思えますね。一旦 EDR に切り替えたあと電波状況が悪化してエラー率が上がった場合、BDR 変調に落としてエラー率を改善しようとしても DH3 や DH5 などの BDR マルチスロットフレームを試行することができず、一気に DM1 にまで落とす必要があります。DH3 や DH5 を使うためには再び LMP で PTT=0 をネゴシエーションせねばならず、もしその後で電波状況が改善し EDR を使いたくなったらまた PTT=1 に切り替えなければなりません。
モバイル使用が考慮されていた筈の Bluetooth で、しかも ACL BDR のフレームタイプに未割当て領域が残っていて BDR/EDRを混在できる余地があったのに、何故こんな仕様が採用されたのかよくわかりません。制定当時、いずれ EDR がデファクトスタンダードになって BDR など過去の遺物と化すだろうという希望的観測とか、将来 Super EDR モードが開発されてフレームタイプが増えるかも知れないから 4bit 16 種を全部使い尽くすべきではない、という判断でもあったのでしょうか。
現実には Bluetooth Classic の PHY 高速化は EDR で打ち止めとなり、更なる高速化は Bluetooth の帯域外 (UWB や PAL/AMP) として企画されしかも普及せず、Bluetooth 5 LE の高速化でも EDR は「なかったこと」のようにスルーされて 2Mbps GFSK が採用されることになるのですが。これも例によって「世間によくある話」なのかもしれません。


LMP の盲腸たち
さて Bluetooth はあと2つのフレーム選択機構を持っています。一つは LMP Channel Quality Driven Data Rate Change (Vol.2 Part.C 4.1.7)、もう一つは LMP Control of Multi-slot Packets (Vol.2 Part.C 4.1.10) で、どちらも Bluetooth 1.0 仕様から存在する非常に古いコマンドです。

まず比較的単純な Multi-slot Packets の方から説明します。これは LMP_max_slot と LMP_max_slot_req という2つのコマンドを持ち、もともとは前者が「マスターからスレーブに対する送信可能な最大スロット数の許可」、後者が「スレーブからマスターに対する送信可能な最大スロット数の許可要求」を意味していました。Bluetooth 1.2 以降では解釈が拡大されてマスター/スレーブの制約が撤廃され、「相手に対する送信可能(つまり自分が受信可能)な最大スロット数の許可」「自分が送信したい最大スロット数の許可要求」となっています。スロット数はデフォルト 1 として定義されているので、ベースバンドリンクした直後の状態では DM1/n-DH1 しか送信できず、DM3 や DH5 などのマルチスロットフレームは LMP_max_slot の交換があってからしか使えないことになります。


LMP_max_slot は「許可する」だけで、送信フレームタイプの選択はあくまで通信相手のチップに任されます。「DM5/DH5 を送ってもいいよ」という許可はできても、「多少電波状況が悪くても DH5 で送り続けてくれ」というような指定はできません。Channel Quality Driven Data Rate Change (CQDDR) は、これを指定可能にするための仕組みです。
CQDDR は LMP_auto_rate (パラメータ無し) と LMP_prefered_rate (8bit の data_rate パラメータ付随) という2種類のコマンドからなります。LMP_auto_rate は「フレームタイプは勝手に選択していいよ」という指示(通常はデフォルト)であり、一方 LMP_prefered_rate は任意のフレームタイプを「可能なかぎりコレを使ってくれ」として指定するコマンドです。ただし、あくまで「prefered」なので強制力はありません。

もともと Bluetooth 1.0 において data_rate は 0:medium rate(FEC 使用=DM), 1:high rate(FEC 未使用=DH) の2種類しかなく、実質的には FEC の ON/OFF を指定するコマンドとして位置づけられていました。Bluetooth 1.2 では上位ビットにも意味が追加され、bit1-2 によってスロット数(※註)を指定できるようになり、「可能な限り DH5 を使ってくれ」という指示ができるようになっています。
Bluetooth 2.0 では更に上位ビットに意味が追加され、bit3-4 が EDR のビットレート(0=DM1, 1=2Mbps, 2=3Mbps)、bit5-6 が EDR のスロット数となりました。しかしここまで来ると、はっきり言って「一体何がしたいのか訳がわからない」コマンドになっていますね。BDR/EDR フレームが同時混在できず、いちいち LMP で PTT を交換しないと切り替えられない前述の仕様と併せて考えると尚更です。

※註:LMP_max_slot の max_slot パラメータは 1, 3, 5 を直接指定しますが、LMP_prefered_rate の data_rate では 0=未指定1=1, 2=3, 3=5 スロットという対応になります。何でこんな所をわざわざ違えるんでしょうね?これらの値定義は LMP 仕様には直接記されておらず、Core Spec 4.2 Vol.2 Part.C 5.2 LMP Parameter Definitions の表にまとめて記載されています。「仕様書」としては正しい書き方なのでしょうが、ただでさえ「あちこちバラバラ」な記述がにますます見通しが悪くなっています。


まとめ
まとめると、Bluetooth Classic における ACL の送信フレームタイプの選択は

(1) 基本的には Bluetooth チップの判断に任される。送信フレームタイプを上位層から直接指定するメカニズムは無い。

(2) 上位層は ACL コネクション接続時に PTYPE パラメータで使用するフレームタイプのマスクを指定できる。ただし DM1 はマスクに関わらず常に有効となる。

(3) EDR 2Mbps, 3Mbps モードは、ベースバンド間で PTT=1 を交換(LMP_packet_type_table_req) しないと使用できない。また PTT=1 成立後はフレームタイプの定義が上書きされ、DM1 以外の ACL BDR パケットは使用できなくなる。

(4) DM3, DH5 などマルチスロットパケットは、ベースバンド間で使用許可の確認交換(LMP_max_slot)をするまで使用できない。

(5) CQDDR (LMP_prefered_rate) を用いることで、通信相手に対して「可能な限りこれで送って欲しい」というフレームタイプを指定することはできる。ただし、あくまで「可能な限り」であって強制力はない。また CQDDR もベースバンド間の指定であり、コネクション毎に指定することはできない。

ということになります。

例によって例のごとく、まとめてしまえば簡単なことですが、これを Bluetooth の仕様書から読み解くのはちょっと骨です。またネットをざっくり検索してみたかぎり、こういう風にまとめた解説も見当たりません。良くて「送信フレームタイプはリンクマネージャーによって選択される」という記述がある程度で、この「リンクマネージャー」が LMP ではなく Bluetooth チップ上のファームウェア機能の話であることや、そこに LMP が Max slot や Prefered rate といった(中途半端な形で)関わってくることはわかりません。
私も Bluetooth の開発に着手した時からずっと持っていた疑問だったものの、分厚い仕様書に何度もチャレンジしては敗退し、今回ようやく読み解いた次第です。

次の記事:「D-Bus のはなし」へ

ページの先頭へ戻る

最新の記事

カテゴリ

バックナンバー