打造可充分運用 WebUSB API 的裝置。
本文說明如何打造可充分運用 WebUSB API。如需 API 本身的簡介,請參閱「存取 USB 裝置」 。
背景
通用串列匯流排 (USB) 已成為 Google Cloud 將週邊裝置連線至電腦和行動運算裝置。除了 定義公車的電動特性 以及一般模型 USB 規格包括一組裝置類別 規格。這些是適用於特定裝置類型的一般模型, 例如儲存空間、音訊、影片和網路等 這些裝置類別規格的優點是 作業系統廠商可以根據 類別實作單一驅動程式 規格 (「類別驅動程式」),以及所有實作該類別的裝置都會 支援。對所有需要編寫程式碼的製造商來說 為開發人員
然而,有些裝置並不屬於任一標準化裝置類別。A 罩杯 製造商可選擇將自家裝置標示為 特定供應商課程在此情況下,作業系統會選擇 根據供應商驅動程式套件中提供的資訊進行載入的驅動程式, 通常也是一組已知會導入 各供應商專用的通訊協定
USB 的另一項功能是,裝置可能會為 保持連線狀態每個介面均可實作 標準化類別或供應商專屬作業系統選擇 不同介面都能聲明各項介面對應的正確驅動程式 驅動程式庫。舉例來說,USB 網路攝影機通常提供兩種介面 實作 USB 影片類別 (適用於攝影機),另一個實作 USB 裝置 音訊類別 (適用於麥克風)。作業系統不會載入一個 "網路攝影機驅動程式"但會載入獨立的影片和語音類別驅動程式 這些程式碼會負責裝置的個別功能這個 介面類別組合提供更高的彈性。
API 基本資訊
許多標準 USB 類別都有對應的網路 API。舉例來說
頁面可以使用 getUserMedia()
從視訊課程裝置擷取影片
或是透過監聽器,從人工介面 (HID) 類別裝置接收輸入事件
適用於 KeyboardEvents 或 PointerEvents,或使用 遊戲手把或
WebHID API。
並非所有裝置都會實作標準化類別定義
裝置會實作與現有網路平台 API 相對應的功能。時間
在此情況下,WebUSB API 可以藉由提供網站的方式來填補此缺口
聲明供應商專屬介面,並直接從該介面導入相關支援
頁面顯示的內容
透過 WebUSB 存取裝置具體的規定略有不同 因為作業系統管理 USB 的方式不同 不過基本需求是,裝置本身並不會有 驅動程式。可以是 一般類別驅動程式:OS 廠商或 即可。由於 USB 裝置可提供多個介面,且每個介面都可能 有專屬驅動程式,就能打造支援某些介面的裝置 ,而其他人則可透過瀏覽器存取。
舉例來說,高階 USB 鍵盤可提供 HID 類別介面, 作業系統的輸入子系統及供應商特有聲明的所有聲明 WebUSB 仍可供設定工具使用的介面。這個 這個工具可以在製造商網站上提供,讓使用者變更 例如微距鍵和打光效果等裝置行為的控制因素 安裝任何平台專屬軟體。這類裝置的設定描述元 如下所示:
值 | 欄位 | 說明 |
---|---|---|
設定描述元 | ||
0x09 |
bLength | 此描述元的大小 |
0x02 |
bDescriptorType | 設定描述元 |
0x0039 |
wTotalLength | 這一系列描述元的總長度 |
0x02 |
bNumInterfaces | 介面數量 |
0x01 |
bConfigurationValue | Configuration 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 (印度) |
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 (印度) |
0b00000010 |
bmAttributes | 大量 |
0x0040 |
wMaxPacketSize | 64 位元組封包 |
0x00 |
bInterval | 不適用於大量端點 |
端點描述元 | ||
0x07 |
bLength | 此描述元的大小 |
0x05 |
bDescriptorType | 端點描述元 |
0b00000011 |
bEndpointAddress | 端點 3 (OUT) |
0b00000010 |
bmAttributes | 大量 |
0x0040 |
wMaxPacketSize | 64 位元組封包 |
0x00 |
bInterval | 不適用於大量端點 |
設定描述元包含多個串連的描述元
。每個欄位都以 bLength
和 bDescriptorType
欄位開頭,方便
。第一個介面是 HID 介面,
HID 描述元以及單一端點,用來將輸入事件傳送至
以及作業系統第二個是供應商專屬的介面,
可用來將指令傳送至裝置及接收回應的端點
傳回的結果。
WebUSB 描述元
WebUSB 雖適用於多種裝置,不需手動修改韌體, 標示裝置時, 說明 WebUSB 支援的描述元。舉例來說,您可以指定 到達網頁網址,瀏覽器將使用者導向 已接上電源。
![Chrome 中 WebUSB 通知的螢幕截圖](https://developer.chrome.com/static/docs/capabilities/build-for-webusb/image/screenshot-the-webusb-no-531009ef49311.png?authuser=6&hl=zh-tw)
二進位裝置物件存放區 (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 | WebUSB 的 bRequest 值 |
0x01 |
iLandingPage | 到達網頁網址 |
平台功能 UUID 識別為 WebUSB 平台功能
描述元,可提供裝置的基本資訊。瀏覽器專區
針對使用 bVendorCode
值的裝置擷取更多相關資訊,
向裝置發出更多要求。目前所指定的唯一要求是
GET_URL
,這會傳回網址描述元。這些字元與字串類似
描述元的情形,主要是在最少位元組中對網址進行編碼。網址
"https://google.com"
的描述元看起來會像這樣:
值 | 欄位 | 說明 |
---|---|---|
網址描述元 | ||
0x0D |
bLength | 此描述元的大小 |
0x03 |
bDescriptorType | 網址描述元 |
0x01 |
bScheme | https:// |
"google.com" |
網址 | UTF-8 編碼網址內容 |
當裝置首次插入瀏覽器時,系統會讀取 BOS 描述元 (
發出這個標準 GET_DESCRIPTOR
控制移轉作業:
bmRequestType | bRequest | wValue | wIndex | wLength | 資料 (回應) |
---|---|---|---|---|---|
0b10000000 |
0x06 |
0x0F00 |
0x0000 |
* | BOS 描述元 |
這項要求通常會發出兩次,第一次是大小夠大的 wLength
以便主機找出 wTotalLength
欄位的值
發布至大型傳輸,並在完整的描述元長度為
目前已知
如果 WebUSB 平台功能描述元的 iLandingPage
欄位設為
瀏覽器設為非零的值,然後執行 WebUSB 專屬 GET_URL
要求
透過發出控制移轉作業,並將 bRequest
設為 bVendorCode
值。
從平台功能描述元並將 wValue
設定為 iLandingPage
值。GET_URL
(0x02
) 的要求代碼來自 wIndex
:
bmRequestType | bRequest | wValue | wIndex | wLength | 資料 (回應) |
---|---|---|---|---|---|
0b11000000 |
0x01 |
0x0001 |
0x0002 |
* | 網址描述元 |
再次提醒,為了初次探測長度,可能會發出兩次這項要求 所讀取的描述元
特定平台注意事項
WebUSB API 會嘗試提供一致的存取介面 USB 裝置的開發人員仍應留意先前 才能存取裝置。
macOS
macOS 不需要任何特殊設定。使用 WebUSB 的網站可連線至 並聲明任何介面皆未由核心驅動程式聲明擁有權,或 或其他應用程式。
Linux
Linux 與 macOS 類似,但根據預設,大多數發行版並未設定使用者
有權開啟 USB 裝置的帳戶。名為 udev 的系統 Daemon
負責為使用者和群組指派可存取裝置的權限。一項規則
如此一來,系統就會指派與指定廠商相符的裝置擁有權,
產品 ID 加入 plugdev
群組,這是具存取權的使用者通用群組
適用於週邊裝置:
SUBSYSTEM=="usb", ATTR{idVendor}=="XXXX", ATTR{idProduct}=="XXXX", GROUP="plugdev"
將 XXXX
替換為裝置的十六進位供應商 ID 和產品 ID。
例如:「ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e11"
」會與 Nexus One 相符
電話。不得以一般的「0x」寫成前置字元和全部小寫
例如文字如要尋找裝置的 ID,請執行指令列
工具 lsusb
。
這項規則應置於 /etc/udev/rules.d
目錄中的檔案中,且
會在裝置插上電源後立即生效。因此不需要重新啟動
udev。
Android
Android 平台以 Linux 為基礎,但不需修改
系統設定根據預設,未建構驅動程式的裝置
才能使用瀏覽器。開發人員
但請注意,使用者在連線至網路時
裝置。使用者選取裝置以回應
requestDevice()
,Android 會顯示提示,詢問是否允許
使用 Chrome 存取如果使用者返回網站,這個提示也會再次顯示
已具備連線至裝置和網站通話的權限
open()
。
此外,在 Android 上存取的裝置數量比電腦 Linux 還多 因為預設納入的司機較少明顯的遺漏情形,例如 是 USB CDC-ACM 類別,通常由 USB 對序列轉接器實作 Android SDK 中沒有用於與序列裝置通訊的 API。
ChromeOS
ChromeOS 同樣以 Linux 為建構基礎,因此不需要進行任何修改 轉換至系統設定permissions_broker 服務控制 USB 存取權 並且允許瀏覽器存取這些內容,前提是 一個無人認領的介面
Windows
Windows 驅動程式模型包含一項額外需求。與 使用者應用程式開啟 USB 裝置的能力上, 預設值,即使沒有載入驅動程式也一樣。而是指定 WinUSB 驅動程式,如要提供介面,則需載入 存取裝置所用的應用程式。方法是使用 系統上安裝的驅動程式資訊檔案 (INF),或修改裝置 提供 Microsoft OS 相容性描述元 列舉。
駕駛資訊檔案 (INF)
驅動程式資訊檔案會指示 Windows 遇到裝置時應採取什麼動作
因為我們的遊戲
在 2010 年間脫穎而出由於使用者的系統已包含 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,應用程式才能
可透過 Windows API 找到裝置並進行連線。使用 New-Guid
PowerShell
cmdlet 或線上工具來產生隨機 GUID。
基於開發目的,Zadig 工具提供了一個簡單的介面 以 WinUSB 驅動程式取代為 USB 介面載入的驅動程式。
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,採用 Little-Endian 格式 |
0x06030000 |
dwWindowsVersion | 最低相容 Windows 版本 (Windows 8.1) |
0x00B2 |
wMSOSDescriptorSetTotalLength | 描述元集的總長度 |
0x02 |
bMS_VendorCode | bRequest 值,用於擷取進一步的 Microsoft 描述元 |
0x00 |
bAltEnumCode | 裝置不支援替代列舉 |
與 WebUSB 描述元一樣,您必須挑選要使用的 bRequest
值
控制與這些描述元相關的移轉作業。在這個範例中
0x02
。0x07
,位於 wIndex
中是擷取 Microsoft OS 的指令
2.0 在裝置上進行描述元集。
bmRequestType | bRequest | wValue | wIndex | wLength | 資料 (回應) |
---|---|---|---|---|---|
0b11000000 |
0x02 |
0x0000 |
0x0007 |
* | MS OS 2.0 描述元集 |
USB 裝置可以有多個功能,因此描述元的第一個部分
組會說明下方與屬性相關聯的函式。
下方範例會設定複合裝置的介面 1。描述元
作業系統有兩項關於此介面的資訊相容的
ID 描述元可告知 Windows 此裝置與 WinUSB 相容
驅動程式庫。註冊資料庫屬性描述元的功能類似
上述 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 編碼的屬性名稱含空值結束字元 |
0x0050 |
wPropertyDataLength | 屬性值的長度 |
"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\0\0" |
PropertyData | GUID 加上兩個以 UTF-16LE 編碼的空值結束字元 |
Windows 只會向裝置查詢這項資訊一次。如果裝置使用 未以有效的描述元回應,系統下次擷取 裝置已連線。Microsoft 已提供 USB 裝置登錄清單 項目,用於說明列舉裝置時建立的登錄檔項目。時間 測試 刪除為裝置建立的項目,強制 Windows 嘗試讀取 來覆寫描述元
詳情請參閱 Microsoft 的網誌文章,瞭解這些方法的使用方式 描述元
範例
實作包含 WebUSB 的 WebUSB 感知裝置程式碼範例 您可在下列專案中找到描述元與 Microsoft OS 描述元: