借り初めのひみつきち

仮ブログです。

Compound Device と Composite Device

Compound と Composite の違い、わかりますか?

このふたつの単語、綴りも似ていますが意味も似ていて、ニュアンスの違いを説明しろと言われると正直ちょっと自信がないです。

USB 規格には Compound DeviceComposite Device という2種類の用語が存在していてそれぞれ別の意味を持ちます。

Compound Device

Compound Device は一言で言うと USB ハブを内蔵したデバイスで、 USB ハブとセットになったキーボードやドックなどが該当します。

Compound Device は物理的にはひとつのデバイスですが、内部的には USB HUB とそれにぶら下がった複数のデバイスとして USB バスのツリー上で認識され、それぞれの内蔵デバイスは独立した USB アドレスを持ちます。

Compound Device は USB ハブの Hub Descriptor 内の wHubCharacteristics にある2ビット目のフラグで判別することができます。

f:id:neriring16:20210920224040p:plain

このビットが1の場合、単純に独立した USB ハブではなく、 Hub Descriptor の後半の方にある DeviceRemovable で non-removable と指定されたビットに該当するポートにあるデバイスとまとめた Compound Device ということになります。

f:id:neriring16:20210920224050p:plain

Composite Device

Composite Device は一言で言うと複数の機能 (Interface) を持った USB デバイスで、トラックパッドと一体化したキーボードなどが該当します。 ちなみに、これにさらに USB ハブが付いてる場合は Compound Device でありかつ Composite Device ということになります。

Composite Device は USB バス上でも単一のアドレスを持った単一のデバイスとして認識され、複数の Interface で複数の機能を提供します。

HID と Composite Device

ここから先はちょっと複雑な話になりますが、キーボードやマウスは USB HID という規格のデバイスになります。

HID 規格は人間と機械の間にある全てのデバイスを定義しようとしたとても壮大な規格で、キーボードやマウス以外にもさまざまなカテゴリのデバイスが定義されています。 そして、 HID に対応したデバイスはレポートと Usage によってさまざまな機能を提供しています。 そのため、 HID デバイスは HID という単一の Interface だけでも複数の機能を提供するものがあります。

よくあるキーボードで通常の文字キー以外に、電源関係、マルチメディア操作、その他のショートカットなどに対応しているものがあります。 実はこれらのキーは HID 規格上では別々の Usage として定義されています。

ほとんどの USB キーボードは HID Boot キーボードというクラスに属していて、いくつか定型の決まり事があります。 そして、 HID Boot キーボードクラスの仕様だけでは先述のようなキーは仲間外れになってしまうので、キーボードと別の HID Interface として定義してる場合と、キーボードを含めてごちゃ混ぜの独自の汎用 HID デバイスとして定義している場合があります。

このようなデバイスWindows PC に接続してデバイスマネージャを見てみると、複数の謎の HID デバイスとして認識されることがありますが、先述のように単一の Interface の場合と複数の Interface に分かれている本当の意味での Composite Device の場合があります。

HID デバイスはレポートの自由度が高すぎる反面、複雑すぎて単一機能のデバイスなのか複数機能のデバイスなのかを判断するのがとても難しいです。 HID デバイスの場合は Interface が1つでも本質的には Composite Device とあまり変わらないということがわかるかと思います。

余談ですが、 HID デバイスには実際には提供していない機能を含んだ定型文のようなレポートディスクリプタを返すデバイスが時々存在します。 おそらくいくつかの機能をまとめた便利チップみたいなものがあってそれをカスタマイズして使っているんだと思いますが、キーボードの形をしていないのにキーボードの定義が含まれていたり、マウスの機能がないのにマウスの定義が含まれていたり、どこにも存在しないキーの定義が含まれていることがあるのでレポートディスクリプタをあまり信用してはいけないかも知れません。