สร้างอุปกรณ์เพื่อใช้ประโยชน์จาก WebUSB API อย่างเต็มที่
บทความนี้จะอธิบายวิธีสร้างอุปกรณ์เพื่อใช้ประโยชน์จาก WebUSB API อย่างเต็มที่ สำหรับข้อมูลเบื้องต้นเกี่ยวกับ API โปรดดูเข้าถึงอุปกรณ์ USB บนเว็บ
ที่มา
Universal Serial Bus (USB) กลายเป็นอินเทอร์เฟซทางกายภาพที่ใช้กันมากที่สุดในการเชื่อมต่ออุปกรณ์ต่อพ่วงกับอุปกรณ์คอมพิวเตอร์เดสก์ท็อปและอุปกรณ์เคลื่อนที่ นอกจากการกำหนดลักษณะทางไฟฟ้าของรถบัสและรุ่นทั่วไปสำหรับการสื่อสารกับอุปกรณ์แล้ว ข้อมูลจำเพาะของ USB ยังมีชุดข้อกำหนดเฉพาะระดับอุปกรณ์ด้วย โมเดลเหล่านี้เป็นเวอร์ชันทั่วไปสำหรับอุปกรณ์บางประเภท เช่น พื้นที่เก็บข้อมูล เสียง วิดีโอ เครือข่าย และอื่นๆ ที่ผู้ผลิตอุปกรณ์สามารถนำมาใช้ได้ ข้อดีของข้อมูลจำเพาะของคลาสอุปกรณ์เหล่านี้คือ ผู้ให้บริการระบบปฏิบัติการสามารถใช้ไดรเวอร์ 1 ตัวโดยขึ้นอยู่กับข้อกำหนดของคลาส ("ไดรเวอร์คลาส") และจะมีการรองรับอุปกรณ์ที่ใช้คลาสดังกล่าว การทำเช่นนี้เป็นการปรับปรุงที่ยอดเยี่ยมกว่าผู้ผลิตทุกรายที่ต้องเขียนไดรเวอร์อุปกรณ์ของตนเอง
แต่อุปกรณ์บางเครื่องไม่เข้ากับหนึ่งในคลาสอุปกรณ์มาตรฐานเหล่านี้ ผู้ผลิตอาจเลือกติดป้ายกำกับอุปกรณ์ของตนว่าใช้คลาสเฉพาะผู้ให้บริการแทน ในกรณีนี้ ระบบปฏิบัติการจะเลือกไดรเวอร์อุปกรณ์ที่จะโหลดตามข้อมูลที่ให้ไว้ในแพ็กเกจไดรเวอร์ของผู้ให้บริการ โดยปกติแล้วจะเป็นชุดผู้ให้บริการและรหัสผลิตภัณฑ์ซึ่งเป็นที่ทราบว่าใช้โปรโตคอลเฉพาะผู้ให้บริการที่เจาะจง
ฟีเจอร์อีกอย่างของ USB คืออุปกรณ์อาจมีอินเทอร์เฟซที่หลากหลายกับโฮสต์ที่เชื่อมต่ออยู่ แต่ละอินเทอร์เฟซสามารถใช้คลาสมาตรฐานหรือจะใช้เฉพาะผู้ให้บริการก็ได้ เมื่อระบบปฏิบัติการเลือกไดรเวอร์ที่เหมาะสมในการจัดการกับอุปกรณ์ ไดรเวอร์ที่แตกต่างกันจะอ้างสิทธิ์อินเทอร์เฟซแต่ละรายการได้ เช่น เว็บแคม USB มักมีอินเทอร์เฟซ 2 แบบ แบบแรกใช้คลาสวิดีโอ USB (สำหรับกล้อง) และอีกแบบหนึ่งใช้คลาสเสียง USB (สำหรับไมโครโฟน) ระบบปฏิบัติการจะไม่โหลด "ไดรเวอร์เว็บแคม" ตัวเดียว แต่จะโหลดไดรเวอร์คลาสวิดีโอและคลาสเสียงแบบอิสระแทน ซึ่งมีหน้าที่การทำงานของอุปกรณ์แยกต่างหาก องค์ประกอบคลาสอินเทอร์เฟซนี้ให้ความยืดหยุ่นที่มากขึ้น
ข้อมูลเบื้องต้นเกี่ยวกับ API
คลาส USB มาตรฐานจำนวนมากมี API เว็บที่สอดคล้องกัน ตัวอย่างเช่น หน้าเว็บสามารถบันทึกวิดีโอจากอุปกรณ์คลาสวิดีโอโดยใช้ getUserMedia()
หรือได้รับเหตุการณ์อินพุตจากอุปกรณ์คลาสของอินเทอร์เฟซมนุษย์ (HID) โดยการฟัง KeyboardEvents หรือ PointerEvents หรือใช้ Gamepad หรือ API WebHID
อย่างไรก็ตาม อุปกรณ์บางรุ่นไม่มีการกำหนดคลาสที่เป็นมาตรฐาน อุปกรณ์บางรุ่นไม่มีฟีเจอร์ที่สอดคล้องกับ API ของแพลตฟอร์มเว็บที่มีอยู่ ในกรณีนี้ WebUSB API สามารถเติมเต็มช่องว่างดังกล่าวโดยให้เว็บไซต์ต่างๆ อ้างสิทธิ์อินเทอร์เฟซเฉพาะผู้ให้บริการและใช้การสนับสนุนสำหรับอินเทอร์เฟซนั้นจากภายในหน้าเว็บโดยตรง
ข้อกำหนดเฉพาะสำหรับอุปกรณ์เพื่อให้เข้าถึงผ่าน WebUSB ในแต่ละแพลตฟอร์มจะแตกต่างกันเล็กน้อยเนื่องจากระบบปฏิบัติการจัดการอุปกรณ์ USB แตกต่างกัน แต่ข้อกำหนดพื้นฐานคืออุปกรณ์ไม่ควรมีไดรเวอร์ที่อ้างสิทธิ์อินเทอร์เฟซที่หน้าเว็บต้องการควบคุมอยู่แล้ว ซึ่งอาจเป็นไดรเวอร์คลาสทั่วไปที่ผู้ให้บริการระบบปฏิบัติการมีให้ หรือไดรเวอร์อุปกรณ์ที่ผู้ให้บริการมีให้ก็ได้ เนื่องจากอุปกรณ์ USB สามารถให้อินเทอร์เฟซได้หลายแบบ ซึ่งแต่ละแบบอาจมีไดรเวอร์ของตัวเอง ดังนั้นจึงสามารถสร้างอุปกรณ์ที่ไดรเวอร์อ้างสิทธิ์อินเทอร์เฟซบางส่วน และอุปกรณ์อื่นๆ สามารถเข้าถึงได้โดยเบราว์เซอร์
เช่น แป้นพิมพ์ USB ระดับไฮเอนด์อาจมีอินเทอร์เฟซคลาส HID ซึ่งระบบจะอ้างสิทธิ์โดยระบบย่อยของระบบปฏิบัติการและอินเทอร์เฟซเฉพาะผู้ให้บริการ ซึ่งยังคงพร้อมใช้งานกับ WebUSB สำหรับให้เครื่องมือกำหนดค่าใช้งาน เครื่องมือนี้ใช้งานได้บนเว็บไซต์ของผู้ผลิต ซึ่งช่วยให้ผู้ใช้เปลี่ยนลักษณะการทํางานของอุปกรณ์ได้ เช่น มาโครคีย์และเอฟเฟกต์แสงโดยไม่ต้องติดตั้งซอฟต์แวร์เฉพาะแพลตฟอร์มใดๆ โดยข้อบ่งชี้การกำหนดค่าของอุปกรณ์จะมีลักษณะดังนี้
ค่า | ฟิลด์ | คำอธิบาย |
---|---|---|
ข้อบ่งชี้การกำหนดค่า | ||
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 (OUT) |
0b00000010 |
bmAttributes | เป็นกลุ่ม |
0x0040 |
wMaxPacketSize | แพ็กเก็ต 64 ไบต์ |
0x00 |
bInterval | ไม่มีสำหรับปลายทางจำนวนมาก |
ข้อบ่งชี้การกำหนดค่าประกอบด้วยข้อบ่งชี้หลายตัวที่ต่อกัน แต่ละช่องจะเริ่มต้นด้วย bLength
และ bDescriptorType
เพื่อให้ระบุได้ อินเทอร์เฟซแรกคืออินเทอร์เฟซ HID ที่มีข้อบ่งชี้ HID ที่เกี่ยวข้อง และปลายทางเดียวที่ใช้ส่งเหตุการณ์อินพุตไปยังระบบปฏิบัติการ อินเทอร์เฟซที่ 2 เป็นอินเทอร์เฟซที่เจาะจงผู้ให้บริการซึ่งมีปลายทาง 2 จุดเพื่อใช้ส่งคำสั่งไปยังอุปกรณ์และรับการตอบกลับ
ข้อบ่งชี้ WebUSB
แม้ว่า WebUSB จะใช้งานได้กับอุปกรณ์มากมายโดยไม่ต้องดัดแปลงเฟิร์มแวร์ แต่คุณก็เปิดใช้ฟังก์ชันการทำงานเพิ่มเติมได้ด้วยการทำเครื่องหมายอุปกรณ์ด้วยข้อบ่งชี้เฉพาะที่บ่งชี้ว่ารองรับ WebUSB ตัวอย่างเช่น คุณระบุ URL ของหน้า Landing Page ที่เบราว์เซอร์จะนำผู้ใช้ไปได้เมื่อเสียบปลั๊กอุปกรณ์
อุปกรณ์ไบนารี Object Store (BOS) เป็นแนวคิดที่นำมาใช้ใน USB 3.0 แต่ยังมีการย้ายพอร์ตไปยังอุปกรณ์ USB 2.0 โดยเป็นส่วนหนึ่งของเวอร์ชัน 2.1 อีกด้วย การประกาศการรองรับ 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 | GUID ของข้อบ่งชี้ความสามารถของแพลตฟอร์ม WebUSB ในรูปแบบ Little End |
0x0100 |
bcdVersion | WebUSB ข้อบ่งชี้ เวอร์ชัน 1.0 |
0x01 |
bVendorCode | ค่า bRequest สำหรับ WebUSB |
0x01 |
iLandingPage | URL สำหรับหน้า Landing Page |
UUID ความสามารถของแพลตฟอร์มจะระบุว่าเป็นข้อบ่งชี้ความสามารถของแพลตฟอร์ม WebUSB ซึ่งให้ข้อมูลพื้นฐานเกี่ยวกับอุปกรณ์ หากต้องการให้เบราว์เซอร์ดึงข้อมูลเพิ่มเติมเกี่ยวกับอุปกรณ์ เบราว์เซอร์จะใช้ค่า bVendorCode
ในการออกคำขอเพิ่มเติมไปยังอุปกรณ์ คำขอเดียวที่ระบุอยู่ในปัจจุบันคือ GET_URL
ซึ่งแสดงผล ข้อบ่งชี้ URL ซึ่งคล้ายกับข้อบ่งชี้สตริง แต่ออกแบบมาเพื่อเข้ารหัส URL ในจำนวนไบต์น้อยที่สุด โดยข้อบ่งชี้ URL สำหรับ "https://google.com"
จะมีลักษณะดังนี้
ค่า | ฟิลด์ | คำอธิบาย |
---|---|---|
ข้อบ่งชี้ URL | ||
0x0D |
bLength | ขนาดของข้อบ่งชี้นี้ |
0x03 |
bDescriptorType | ข้อบ่งชี้ URL |
0x01 |
bScheme | https:// |
"google.com" |
URL | เนื้อหา URL ที่เข้ารหัสแบบ UTF-8 |
เมื่อเสียบอุปกรณ์ในเบราว์เซอร์เป็นครั้งแรก จะอ่านข้อบ่งชี้ BOS ด้วยการออกการโอนการควบคุม GET_DESCRIPTOR
แบบมาตรฐานนี้
bmRequestType | bRequest | wValue | wIndex | wLength | ข้อมูล (คำตอบ) |
---|---|---|---|---|---|
0b10000000 |
0x06 |
0x0F00 |
0x0000 |
* | ข้อบ่งชี้ BOS |
คำขอนี้มักจะทำ 2 ครั้ง โดยครั้งแรกจะมี wLength
ที่มากพอ เพื่อให้โฮสต์พบค่าของช่อง wTotalLength
โดยไม่ต้องทำการโอนจำนวนมาก จากนั้นจะทำอีกครั้งเมื่อทราบความยาวของข้อบ่งชี้ทั้งหมดแล้ว
หากข้อบ่งชี้ความสามารถของแพลตฟอร์ม WebUSB ตั้งค่าช่อง iLandingPage
เป็นค่าที่ไม่ใช่ 0 เบราว์เซอร์จะส่งคำขอ GET_URL
สำหรับ WebUSB โดยเฉพาะด้วยการออกการโอนการควบคุมโดยตั้งค่า 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 สามารถเชื่อมต่อกับอุปกรณ์และอ้างสิทธิ์อินเทอร์เฟซใดๆ ที่ไม่ได้อ้างสิทธิ์โดยไดรเวอร์ Kernel หรือแอปพลิเคชันอื่น
Linux
Linux ก็เหมือนกับ macOS แต่โดยค่าเริ่มต้นแล้ว Linux ส่วนใหญ่จะไม่ได้ตั้งค่าบัญชีผู้ใช้ที่มีสิทธิ์เปิดอุปกรณ์ USB Daemon ของระบบที่เรียกว่า udev มีหน้าที่ในการกำหนดผู้ใช้และกลุ่มที่อนุญาตให้เข้าถึงอุปกรณ์ กฎเช่นนี้จะมอบหมายการเป็นเจ้าของอุปกรณ์ที่ตรงกับผู้ให้บริการและรหัสผลิตภัณฑ์ที่กำหนดกับกลุ่ม plugdev
ซึ่งเป็นกลุ่มทั่วไปสำหรับผู้ใช้ที่มีสิทธิ์เข้าถึงอุปกรณ์ต่อพ่วง
SUBSYSTEM=="usb", ATTR{idVendor}=="XXXX", ATTR{idProduct}=="XXXX", GROUP="plugdev"
แทนที่ XXXX
ด้วยผู้ให้บริการเลขฐาน 16 และรหัสผลิตภัณฑ์สำหรับอุปกรณ์ของคุณ เช่น ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e11"
จะตรงกับโทรศัพท์ Nexus One ค่าเหล่านี้ต้องเขียนโดยไม่มี "0x" นำหน้า และตัวพิมพ์เล็กทั้งหมดจึงจะเข้าใจได้อย่างถูกต้อง หากต้องการค้นหารหัสของอุปกรณ์ ให้เรียกใช้เครื่องมือ
บรรทัดคำสั่ง 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 เช่นกัน และไม่จำเป็นต้องแก้ไขการกำหนดค่าของระบบ บริการ permission_broker ควบคุมการเข้าถึงอุปกรณ์ USB และจะอนุญาตให้เบราว์เซอร์เข้าถึงได้ตราบใดที่มีอินเทอร์เฟซที่ไม่มีการอ้างสิทธิ์อย่างน้อย 1 รายการ
Windows
ไดรเวอร์ของรุ่น Windows มีข้อกำหนดเพิ่มเติม ความสามารถในการเปิดอุปกรณ์ USB จากแอปพลิเคชันของผู้ใช้จะแตกต่างจากแพลตฟอร์มอื่นๆ ที่เป็นค่าเริ่มต้น แม้จะไม่มีการโหลดไดรเวอร์ก็ตาม แต่จะต้องมีไดรเวอร์พิเศษ WinUSB ที่ต้องโหลดเพื่อให้แอปพลิเคชันอินเทอร์เฟซใช้ในการเข้าถึงอุปกรณ์ ซึ่งทำได้ด้วยไฟล์ข้อมูลไดรเวอร์ที่กำหนดเอง (INF) ที่ติดตั้งอยู่ในระบบ หรือโดยการแก้ไขเฟิร์มแวร์ของอุปกรณ์เพื่อระบุข้อบ่งชี้ความเข้ากันได้กับ Microsoft OS ในระหว่างการแจกแจง
ไฟล์ข้อมูลผู้ขับ (INF)
ไฟล์ข้อมูลไดรเวอร์จะบอก Windows ถึงสิ่งที่ต้องทำเมื่อพบอุปกรณ์เป็นครั้งแรก เนื่องจากระบบของผู้ใช้มีไดรเวอร์ WinUSB อยู่แล้ว
สิ่งที่จำเป็นต้องใช้ก็คือให้ไฟล์ INF เชื่อมโยงผู้ให้บริการและรหัสผลิตภัณฑ์กับกฎการติดตั้งใหม่นี้ ไฟล์ด้านล่างเป็นตัวอย่างเบื้องต้น บันทึกไฟล์ลงในไฟล์ที่มีส่วนขยาย .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 ได้ ใช้ PowerShell cmdlet ของ New-Guid
หรือเครื่องมือออนไลน์เพื่อสร้าง GUID แบบสุ่ม
เครื่องมือ Zadig มีอินเทอร์เฟซที่ใช้งานง่ายสำหรับแทนที่ไดรเวอร์ที่โหลดสำหรับอินเทอร์เฟซ USB ด้วยไดรเวอร์ WinUSB เพื่อจุดประสงค์ในการพัฒนา
ข้อบ่งชี้ความเข้ากันได้กับ Microsoft OS
ไฟล์ INF ข้างต้นค่อนข้างยุ่งยากเนื่องจากต้องกำหนดค่าเครื่องของผู้ใช้ทุกเครื่องล่วงหน้า Windows 8.1 ขึ้นไปจะมีทางเลือก ในการใช้ตัวบ่งชี้ USB ที่กำหนดเอง โดยข้อบ่งชี้เหล่านี้จะให้ข้อมูลแก่ระบบปฏิบัติการ Windows เมื่อเสียบปลั๊กอุปกรณ์เป็นครั้งแรก ซึ่งโดยปกติแล้วจะรวมอยู่ในไฟล์ INF
เมื่อตั้งค่าข้อบ่งชี้ WebUSB แล้ว คุณสามารถเพิ่มข้อบ่งชี้ความเข้ากันได้กับระบบปฏิบัติการของ Microsoft ได้ง่ายๆ ก่อนอื่นให้ขยายข้อบ่งชี้ 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 | GUID ของข้อบ่งชี้ความเข้ากันได้ของแพลตฟอร์ม Microsoft OS 2.0 ในรูปแบบ 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 ของอุปกรณ์ผสม โดยข้อบ่งชี้จะให้ข้อมูลที่สำคัญ 2 อย่างเกี่ยวกับอินเทอร์เฟซนี้สำหรับระบบปฏิบัติการ โดยข้อบ่งชี้รหัสที่เข้ากันได้จะบอก Windows ว่าอุปกรณ์นี้เข้ากันได้กับไดรเวอร์ WinUSB ข้อบ่งชี้พร็อพเพอร์ตี้รีจิสทรีทำงานคล้ายกับส่วน [Dev_AddReg]
ของตัวอย่าง INF ด้านบน โดยตั้งค่าพร็อพเพอร์ตี้รีจิสทรีเพื่อกำหนด 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 | ||
0x0014 |
wLength | ขนาดของข้อบ่งชี้นี้ |
0x0003 |
wDescriptorType | ข้อบ่งชี้รหัสที่เข้ากันได้ |
"WINUSB\0\0" |
CompatibileID | เพิ่มสตริง ASCII ไว้ที่ 8 ไบต์แล้ว |
"\0\0\0\0\0\0\0\0" |
SubCompatibleID | เพิ่มสตริง ASCII ไว้ที่ 8 ไบต์แล้ว |
ข้อบ่งชี้พร็อพเพอร์ตี้รีจิสทรีของ Microsoft OS 2.0 | ||
0x0084 |
wLength | ขนาดของข้อบ่งชี้นี้ |
0x0004 |
wDescriptorType | ข้อบ่งชี้พร็อพเพอร์ตี้รีจิสทรี |
0x0007 |
wPropertyDataType | REG_MULTI_SZ |
0x002A |
wPropertyNameLength | ความยาวของชื่อพร็อพเพอร์ตี้ |
"DeviceInterfaceGUIDs\0" |
PropertyName | ชื่อพร็อพเพอร์ตี้ที่มีตัวระบุค่า Null ซึ่งเข้ารหัสเป็น UTF-16LE |
0x0050 |
wPropertyDataLength | ความยาวของค่าพร็อพเพอร์ตี้ |
"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\0\0" |
PropertyData | GUID บวกตัวระบุค่า Null 2 รายการที่เข้ารหัสในรูปแบบ UTF-16LE |
Windows จะค้นหาข้อมูลนี้ในอุปกรณ์เพียงครั้งเดียว หากอุปกรณ์ไม่ตอบสนองด้วยข้อบ่งชี้ที่ถูกต้อง อุปกรณ์จะไม่ถามอีกในครั้งต่อไปที่เชื่อมต่ออุปกรณ์ Microsoft ได้ให้รายการ USB Device Registry ที่อธิบายรายการรีจิสทรีที่สร้างขึ้นเมื่อแจกแจงอุปกรณ์ เมื่อทดสอบ ให้ลบรายการที่สร้างขึ้นสำหรับอุปกรณ์เพื่อให้ Windows พยายามอ่านข้อบ่งชี้อีกครั้ง
ดูข้อมูลเพิ่มเติมได้ที่บล็อกโพสต์ของ Microsoft เกี่ยวกับวิธีใช้ข้อบ่งชี้เหล่านี้
ตัวอย่าง
ตัวอย่างโค้ดที่ใช้อุปกรณ์ที่รับรู้ถึง WebUSB ซึ่งมีทั้งข้อบ่งชี้ WebUSB และข้อบ่งชี้ Microsoft OS จะอยู่ในโปรเจ็กต์ต่อไปนี้