WebUSB API を最大限に活用するためのデバイスを構築します。
この記事では、 WebUSB APIAPI 自体の簡単な説明については、USB デバイスへのアクセスに関するページをご参照ください をご覧ください。
背景
ユニバーサル シリアル バス(USB)は、 周辺機器をデスクトップ デバイスやモバイル コンピューティング デバイスに接続する。これらに加えて、 バスの電気特性を定義し、その一般的なモデルを デバイスとの通信により、USB の仕様にはデバイスのクラス 仕様。これらは特定のクラスのデバイスの一般的なモデルです。 ストレージ、オーディオ、ビデオ、ネットワークなどをデバイス メーカーが提供し、 説明します。これらのデバイスクラス仕様の利点は、 オペレーティング システム ベンダーは、クラスに基づいて 1 つのドライバを実装できます。 (クラスドライバ)と、そのクラスを実装するデバイスには、 サポートされません。これは、すべてのメーカーが 独自のデバイス ドライバを使用できます。
ただし、これらの標準化されたデバイスクラスのいずれかに適合しないデバイスもあります。 メーカーは代わりに、デバイスに「実装」とラベル付けすることを選択できます。 ベンダー固有のクラス。この場合、オペレーティング システムによって ベンダーのドライバ パッケージで提供される情報に基づいて読み込むドライバ 通常はベンダー ID とプロダクト ID のセットで、 特定のベンダー固有のプロトコルを使用します。
USB のもう一つの機能として、デバイスは複数のインターフェースを 接続されています。各インターフェースでは、 標準化されたクラスにするかベンダー固有にできます。オペレーティング システムによって 各インターフェースは、要求されるデバイスに応じて異なる ドライバです。たとえば、USB ウェブカメラは通常 2 つのインターフェースを提供します。 USB 動画クラス(カメラ用)と USB Audio Class(マイク用)です。オペレーティング システムは、1 つまたは複数のコンテナを "ウェブカメラ ドライバ"代わりに、独立した動画およびオーディオ クラス ドライバを読み込みます。 デバイスの個々の機能を担当します。この インターフェース クラスの構成により柔軟性が向上します。
API の基本
標準 USB クラスの多くには、対応するウェブ API があります。たとえば、
ページで getUserMedia()
を使用して Video クラスのデバイスから動画をキャプチャできます。
リッスンすることで、ヒューマン インターフェース(HID)クラスのデバイスから入力イベントを受信する
KeyboardEvents または PointerEvents を使用するか、ゲームパッドまたは
WebHID API。
すべてのデバイスが標準化されたクラス定義を実装するわけではないのと同様に、すべてのデバイスで
デバイスは、既存のウェブ プラットフォーム API に対応する機能を実装しています。日時
そのため WebUSB API では
ベンダー固有のインターフェースを要求し、そのインターフェースのサポートを
アクセスできるようになります
WebUSB 経由でデバイスにアクセスできるようにするための具体的な要件は、若干異なります。 プラットフォーム間での USB の管理方法の違いによる、 ただし、基本的な要件として、デバイスにデバイスに ドライバがページから制御したいインターフェースを要求します。これは次のいずれかです。 OS ベンダーが提供する汎用クラスドライバ、または OS ベンダーが提供するデバイス ドライバ ベンダー。USB デバイスは複数のインターフェースを提供できるため、各インターフェースは 独自のドライバを持っているため、いくつかのインターフェースを ドライバによって要求され、その他はブラウザからアクセスできるままにしておく必要があります。
たとえば、ハイエンドの USB キーボードは、HID クラス インターフェースを オペレーティング システムの入力サブシステムとベンダー固有の インターフェースを実装する必要があります。この ツールがメーカーのウェブサイトで配信され、ユーザーが マクロキーや照明効果など、デバイスの動作に関する プラットフォーム固有のソフトウェアを インストールする必要はありませんこのようなデバイスの設定記述子は、 次のようになります。
値 | 項目 | 説明 |
---|---|---|
構成記述子 | ||
0x09 |
bLength | この記述子のサイズ |
0x02 |
bDescriptorType | 構成記述子 |
0x0039 |
wTotalLength | この一連の記述子の合計長 |
0x02 |
bNumInterfaces | インターフェースの数 |
0x01 |
bConfigurationValue | 構成 1 |
0x00 |
iConfiguration | 設定名(なし) |
0b1010000 |
bmAttributes | リモート ウェイクアップ機能を備えた自給式デバイス |
0x32 |
bMaxPower | 最大電力は 2 mA 単位で表される |
インターフェース記述子 | ||
0x09 |
bLength | この記述子のサイズ |
0x04 |
bDescriptorType | インターフェース記述子 |
0x00 |
bInterfaceNumber | インターフェース 0 |
0x00 |
bAlternateSetting | 代替設定 0(デフォルト) |
0x01 |
bNumEndpoints | 1 個のエンドポイント |
0x03 |
bInterfaceClass | HID インターフェース クラス |
0x01 |
bInterfaceSubClass | ブート インターフェースのサブクラス |
0x01 |
bInterfaceProtocol | キーボード |
0x00 |
iInterface | インターフェース名(なし) |
HID 記述子 | ||
0x09 |
bLength | この記述子のサイズ |
0x21 |
bDescriptorType | HID 記述子 |
0x0101 |
bcdHID | HID バージョン 1.1 |
0x00 |
bCountryCode | ハードウェアの対象国 |
0x01 |
bNumDescriptors | フォローする HID クラス記述子の数 |
0x22 |
bDescriptorType | レポート記述子タイプ |
0x003F |
wDescriptorLength | レポート記述子の全長 |
エンドポイント記述子 | ||
0x07 |
bLength | この記述子のサイズ |
0x05 |
bDescriptorType | エンドポイント記述子 |
0b10000001 |
bEndpointAddress | エンドポイント 1(IN) |
0b00000011 |
bmAttributes | 割り込み |
0x0008 |
wMaxPacketSize | 8 バイトのパケット |
0x0A |
bInterval | 10 ミリ秒間隔 |
インターフェース記述子 | ||
0x09 |
bLength | この記述子のサイズ |
0x04 |
bDescriptorType | インターフェース記述子 |
0x01 |
bInterfaceNumber | インターフェース 1 |
0x00 |
bAlternateSetting | 代替設定 0(デフォルト) |
0x02 |
bNumEndpoints | 2 個のエンドポイント |
0xFF |
bInterfaceClass | ベンダー固有のインターフェース クラス |
0x00 |
bInterfaceSubClass | |
0x00 |
bInterfaceProtocol | |
0x00 |
iInterface | インターフェース名(なし) |
エンドポイント記述子 | ||
0x07 |
bLength | この記述子のサイズ |
0x05 |
bDescriptorType | エンドポイント記述子 |
0b10000010 |
bEndpointAddress | エンドポイント 1(IN) |
0b00000010 |
bmAttributes | バルク |
0x0040 |
wMaxPacketSize | 64 バイトのパケット |
0x00 |
bInterval | 一括エンドポイントの場合はなし |
エンドポイント記述子 | ||
0x07 |
bLength | この記述子のサイズ |
0x05 |
bDescriptorType | エンドポイント記述子 |
0b00000011 |
bEndpointAddress | エンドポイント 3(出力) |
0b00000010 |
bmAttributes | バルク |
0x0040 |
wMaxPacketSize | 64 バイトのパケット |
0x00 |
bInterval | 一括エンドポイントの場合はなし |
構成記述子は、連結された複数の記述子で構成されます。
説明します。それぞれが bLength
フィールドと bDescriptorType
フィールドで始まるため、
特定できます。1 つ目のインターフェースは HID インターフェースであり、
HID 記述子と、HID 記述子に入力イベントを配信するために使用される単一のエンドポイント
OS です。2 つ目のインターフェースは、ベンダー固有のインターフェースです。
デバイスへのコマンドの送信とレスポンスの受信に使用できるエンドポイント
見返りに行われます
WebUSB 記述子
WebUSB はファームウェアを変更しなくても多くのデバイスで動作しますが、 追加機能を有効にするには、デバイスに WebUSB のサポートを示す記述子です。たとえば、デフォルトの デバイスにアクセスしたときにブラウザからユーザーをリダイレクトできるランディング ページ URL 電源に接続されます。
<ph type="x-smartling-placeholder">![Chrome の WebUSB 通知のスクリーンショット](https://developer.chrome.google.cn/static/docs/capabilities/build-for-webusb/image/screenshot-the-webusb-no-531009ef49311.png?authuser=0000&hl=ja)
バイナリ デバイス オブジェクト ストア(BOS)は USB 3.0 で導入されたコンセプトです。 バージョン 2.1 では USB 2.0 デバイスにもバックポートされています。宣言 WebUSB のサポートは、次のプラットフォーム機能を含むことから始まります。 BOS 記述子の記述子:
値 | 項目 | 説明 |
---|---|---|
バイナリ デバイスのオブジェクト ストア記述子 | ||
0x05 |
bLength | この記述子のサイズ |
0x0F |
bDescriptorType | バイナリ デバイスのオブジェクト ストア記述子 |
0x001D |
wTotalLength | この一連の記述子の合計長 |
0x01 |
bNumDeviceCaps | BOS 内のデバイス機能記述子の数 |
WebUSB プラットフォーム機能記述子 | ||
0x18 |
bLength | この記述子のサイズ |
0x10 |
bDescriptorType | デバイス機能記述子 |
0x05 |
bDevCapabilityType | プラットフォーム機能記述子 |
0x00 |
bReserved | |
{0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, 0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65} |
PlatformCapablityUUID | リトル エンディアン形式の WebUSB プラットフォーム機能記述子 GUID |
0x0100 |
bcdVersion | WebUSB 記述子バージョン 1.0 |
0x01 |
bVendorCode | bWebUSB の bRequest 値 |
0x01 |
iLandingPage | ランディング ページの URL |
プラットフォーム機能 UUID では、これを WebUSB プラットフォーム機能として識別します。
記述子は、デバイスに関する基本情報を提供します。ブラウザの場合
デバイスの詳細情報を取得するため、bVendorCode
値を使用して
デバイスに追加のリクエストを発行できます。現在指定されているリクエストは
GET_URL
は URL 記述子を返します。これらは String と同様の
最小バイトで URL をエンコードするように設計されています。URL
"https://google.com"
の記述子は次のようになります。
値 | 項目 | 説明 |
---|---|---|
URL 記述子 | ||
0x0D |
bLength | この記述子のサイズ |
0x03 |
bDescriptorType | URL 記述子 |
0x01 |
bScheme | https:// |
"google.com" |
URL | UTF-8 でエンコードされた URL コンテンツ |
デバイスを最初に接続したとき、ブラウザは BOS 記述子を
標準的な GET_DESCRIPTOR
コントロール転送を発行します。
bmRequestType | bRequest | wValue | wIndex | wLength | データ(レスポンス) |
---|---|---|---|---|---|
0b10000000 |
0x06 |
0x0F00 |
0x0000 |
* | BOS 記述子 |
通常、このリクエストは 2 回行われます。1 回目は wLength
が十分に大きいため、
これにより、ホストは名前を指定せずに wTotalLength
フィールドの値を
大規模な転送をコミットし、ディスクリプタ全体の長さが
認識します。
WebUSB プラットフォーム機能記述子の iLandingPage
フィールドが
ゼロ以外の値を指定すると、ブラウザは WebUSB 固有の GET_URL
リクエストを実行します。
bRequest
を bVendorCode
値に設定してコントロール転送を発行することにより、
プラットフォーム機能記述子から取得し、wValue
を iLandingPage
に設定します。
あります。GET_URL
のリクエスト コード(0x02
)は wIndex
に入れます。
bmRequestType | bRequest | wValue | wIndex | wLength | データ(レスポンス) |
---|---|---|---|---|---|
0b11000000 |
0x01 |
0x0001 |
0x0002 |
* | URL 記述子 |
この場合も、最初に長さを調べるために、このリクエストが 2 回発行されることがあります。 あります。
プラットフォーム固有の考慮事項
一方 WebUSB API は、 USB デバイスのデベロッパーは、 アプリケーションを制御するために必要です。
macOS
macOS の場合、特別な操作は必要ありません。WebUSB を使用するウェブサイトは、 カーネル ドライバまたはカーネル ドライバによって要求されていない できます。
Linux
Linux は macOS に似ていますが、ほとんどのディストリビューションではデフォルトで
アクセスを許可する必要があります。udev というシステム デーモンが、
デバイスへのアクセスを許可されたユーザーとグループの割り当てを担います。ルール
指定したベンダーに一致するデバイスの所有権を割り当てます。
プロダクト ID を、アクセス権を持つユーザーの共通のグループである plugdev
グループに追加します。
次のとおりです。
SUBSYSTEM=="usb", ATTR{idVendor}=="XXXX", ATTR{idProduct}=="XXXX", GROUP="plugdev"
XXXX
は、デバイスの 16 進数のベンダー ID とプロダクト ID に置き換えます。
例:ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e11"
は Nexus One にマッチします
できます。これらは通常の「0x」なしで記述する必要があります。接頭辞とすべて小文字
必要があります。デバイスの ID を確認するには、次のコマンドを実行します。
ツール lsusb
。
このルールは、/etc/udev/rules.d
ディレクトリ内のファイルに配置する必要があります。
はデバイスが電源に接続されるとすぐに有効になります。再起動する必要はありません。
udev。
Android
Android プラットフォームは Linux をベースとしていますが、
できます。デフォルトでは、ドライバがビルドされていないデバイス
ブラウザがオペレーティング システムに取り込むことができます。開発者は
ユーザーがサービス アカウントに接続するときに追加の手順が
クリックします。ユーザーがデバイスへの応答としてデバイスを選択すると、
requestDevice()
。Android は、許可するかどうかを尋ねるプロンプトを表示します。
アクセスできます。このメッセージは、ユーザーがウェブサイトに戻った場合にも再表示されます。
デバイスに接続する権限を持っており、ウェブサイトから
open()
。
さらに、Android の方がパソコンの Linux よりも多くのデバイスにアクセスできる デフォルトで含まれるドライバの数が少なくなるためです。たとえば、 USB - シリアル アダプターによって一般的に実装される USB CDC-ACM クラスです。 は、Android SDK にはシリアル デバイスとの通信用の API ではありません。
ChromeOS
ChromeOS も Linux をベースとしており、変更は不要 変更します。permission_scheduler サービスは USB へのアクセスを制御します。 少なくとも 2 台以上の認証情報があれば、ブラウザは 1 つの未申請インターフェースがあります。
Windows
Windows ドライバモデルでは追加要件が導入されています。 ユーザー アプリケーションから USB デバイスを開く機能以上では、 ドライバがロードされていなくてもデフォルトで適用されます。代わりに、特別な という 2 つのドライバがあります。このドライバは、インタフェースとして アプリがデバイスへのアクセスに使用する デバイスが決まりますこれを行うには、カスタム システムにインストールされている、またはデバイスに改変されたドライバ情報ファイル(INF) Microsoft OS 互換性記述子を提供するファームウェアを 列挙できます。
ドライバ情報ファイル(INF)
デバイスに遭遇した際の対処方法を Windows に指示するドライバ情報ファイル
説明します。ユーザーのシステムにはすでに WinUSB ドライバが組み込まれているため、
あとは、INF ファイルでベンダーとプロダクト ID を関連付けるだけです。
新しいインストール ルールが適用されます。以下のファイルは基本的な例です。保存する
拡張子が .inf
のファイルで、「X」でマークされたセクションを変更してから、
クリックして [インストール] を選択します。選択できます。
[Version]
Signature = "$Windows NT$"
Class = USBDevice
ClassGUID = {88BAE032-5A81-49f0-BC3D-A4FF138216D6}
Provider = %ManufacturerName%
CatalogFile = WinUSBInstallation.cat
DriverVer = 09/04/2012,13.54.20.543
; ========== Manufacturer/Models sections ===========
[Manufacturer]
%ManufacturerName% = Standard,NTx86,NTia64,NTamd64
[Standard.NTx86]
%USB\MyCustomDevice.DeviceDesc% = USB_Install,USB\VID_XXXX&PID_XXXX
[Standard.NTia64]
%USB\MyCustomDevice.DeviceDesc% = USB_Install,USB\VID_XXXX&PID_XXXX
[Standard.NTamd64]
%USB\MyCustomDevice.DeviceDesc% = USB_Install,USB\VID_XXXX&PID_XXXX
; ========== Class definition ===========
[ClassInstall32]
AddReg = ClassInstall_AddReg
[ClassInstall_AddReg]
HKR,,,,%ClassName%
HKR,,NoInstallClass,,1
HKR,,IconPath,%REG_MULTI_SZ%,"%systemroot%\system32\setupapi.dll,-20"
HKR,,LowerLogoVersion,,5.2
; =================== Installation ===================
[USB_Install]
Include = winusb.inf
Needs = WINUSB.NT
[USB_Install.Services]
Include = winusb.inf
Needs = WINUSB.NT.Services
[USB_Install.HW]
AddReg = Dev_AddReg
[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x10000,"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
; =================== Strings ===================
[Strings]
ManufacturerName = "Your Company Name Here"
ClassName = "Your Company Devices"
USB\MyCustomDevice.DeviceDesc = "Your Device Name Here"
[Dev_AddReg]
セクションでは、デバイスの DeviceInterfaceGUID のセットを構成します。
ダウンロードしますアプリで GUID を使用するには、すべてのデバイス インターフェースに GUID が必要です。
Windows API でアプリケーションを見つけて接続します。New-Guid
PowerShell を使用する
ランダム GUID を生成します。
開発目的の場合は、Zadig ツールを利用することで、 USB インタフェース用にロードされたドライバを WinUSB ドライバに置き換えます。
Microsoft OS 互換性記述子
上記の INF ファイルを使用する方法は、すべてのファイルを構成し、 マシンに事前に転送されますWindows 8.1 以降の場合は、代替機能として カスタム USB 記述子を使用します。これらの記述子を使用すると、 システムに最初に接続したとき、Windows オペレーティング システムに 通常は INF ファイルに含まれます。
WebUSB 記述子を設定すると、Microsoft の OS を簡単に追加できます。
記述することもできます。まず、このファイルで BOS 記述子を拡張します。
追加のプラットフォーム機能記述子。必ず wTotalLength
を更新してください
これを考慮するには bNumDeviceCaps
を使用します。
値 | 項目 | 説明 |
---|---|---|
Microsoft OS 2.0 プラットフォームの機能記述子 | ||
0x1C |
bLength | この記述子のサイズ |
0x10 |
bDescriptorType | デバイス機能記述子 |
0x05 |
bDevCapabilityType | プラットフォーム機能記述子 |
0x00 |
bReserved | |
{0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F} |
PlatformCapablityUUID | リトル エンディアン形式の Microsoft OS 2.0 プラットフォーム互換性記述子 GUID |
0x06030000 |
dwWindowsVersion | Windows の最小互換バージョン(Windows 8.1) |
0x00B2 |
wMSOSDescriptorSetTotalLength | 記述子セットの合計長 |
0x02 |
bMS_VendorCode | その他の Microsoft 記述子を取得するための bRequest 値 |
0x00 |
bAltEnumCode | デバイスは代替の列挙に対応していません |
WebUSB 記述子と同様に、使用する bRequest
値を選択する必要があります。
制御転送を制御します。この例では、
0x02
。wIndex
に配置された 0x07
は、Microsoft OS を取得するコマンドです。
デバイスからの 2.0 記述子セット。
bmRequestType | bRequest | wValue | wIndex | wLength | データ(レスポンス) |
---|---|---|---|---|---|
0b11000000 |
0x02 |
0x0000 |
0x0007 |
* | MS OS 2.0 記述子セット |
USB デバイスは複数の機能を持つことができるため、記述子の最初の部分は
set は、後続のプロパティが関連付けられている関数を示します。「
複合デバイスのインターフェース 1 を設定する例を以下に示します。この記述子は、
このインターフェースに関する 2 つの重要な情報があります互換性のある
ID 記述子は、このデバイスが WinUSB に対応していることを Windows に伝えます。
ドライバです。レジストリ プロパティ記述子は
上の INF の例の [Dev_AddReg]
セクションで、レジストリ プロパティを
この関数にデバイス インターフェース GUID を割り当てます。
値 | 項目 | 説明 |
---|---|---|
Microsoft OS 2.0 記述子セット ヘッダー | ||
0x000A |
wLength | この記述子のサイズ |
0x0000 |
wDescriptorType | 記述子セットのヘッダー記述子 |
0x06030000 |
dwWindowsVersion | Windows の最小互換バージョン(Windows 8.1) |
0x00B2 |
wTotalLength | 記述子セットの合計長 |
Microsoft OS 2.0 構成サブセット ヘッダー | ||
0x0008 |
wLength | この記述子のサイズ |
0x0001 |
wDescriptorType | 構成サブセットのヘッダーの記述。 |
0x00 |
bConfigurationValue | 構成 1 に適用されます(構成にかかわらず、0 からインデックス付けされます) 通常、インデックス番号は 1) |
0x00 |
bReserved | 0 に設定する必要があります。 |
0x00A8 |
wTotalLength | このヘッダーを含むサブセットの合計長 |
Microsoft OS 2.0 関数サブセット・ヘッダー | ||
0x0008 |
wLength | この記述子のサイズ |
0x0002 |
wDescriptorType | 関数のサブセットのヘッダー記述子 |
0x01 |
bFirstInterface | 関数の最初のインターフェース |
0x00 |
bReserved | 0 に設定する必要があります。 |
0x00A0 |
wSubsetLength | このヘッダーを含むサブセットの合計長 |
Microsoft OS 2.0 互換 ID 記述子 | ||
0x0014 |
wLength | この記述子のサイズ |
0x0003 |
wDescriptorType | 互換性のある ID 記述子 |
"WINUSB\0\0" |
CompatibileID | 8 バイトにパディングされた ASCII 文字列 |
"\0\0\0\0\0\0\0\0" |
SubCompatibleID | 8 バイトにパディングされた ASCII 文字列 |
Microsoft OS 2.0 レジストリのプロパティ記述子 | ||
0x0084 |
wLength | この記述子のサイズ |
0x0004 |
wDescriptorType | レジストリプロパティ記述子 |
0x0007 |
wPropertyDataType | REG_MULTI_SZ |
0x002A |
wPropertyNameLength | プロパティ名の長さ |
"DeviceInterfaceGUIDs\0" |
PropertyName | UTF-16LE でエンコードされた null 終端を持つプロパティ名 |
0x0050 |
wPropertyDataLength | プロパティ値の長さ |
"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\0\0" |
PropertyData | GUID と 2 つの null 終端文字(UTF-16LE でエンコード) |
Windows がこの情報をデバイスに照会するのは 1 回だけです。デバイスが動作している場合 有効な記述子を返さないと、次回以降は再確認を求められません。 デバイスが接続されました。Microsoft は、USB デバイス レジストリのリストを提供しています。 Entries は、デバイスの列挙時に作成されるレジストリ エントリを記述するものです。日時 テストでは、デバイス用に作成されたエントリを削除して、Windows に読み取りを強制的に試みます。 使用します。
これらの機能の使用方法について詳しくは、Microsoft のブログ投稿をご覧ください。 使用します。
例
両方の WebUSB を含む WebUSB 対応デバイスを実装するコード例 記述子と Microsoft OS 記述子は、以下のプロジェクトにあります。