สร้างอุปกรณ์เพื่อใช้ประโยชน์จาก WebUSB API อย่างเต็มที่
บทความนี้อธิบายวิธีสร้างอุปกรณ์เพื่อใช้ประโยชน์จาก WebUSB API อย่างเต็มที่ สำหรับข้อมูลเบื้องต้นเกี่ยวกับ API เอง โปรดดูเข้าถึงอุปกรณ์ USB บนเว็บ
ข้อมูลเบื้องต้น
Universal Serial Bus (USB) กลายเป็นอินเทอร์เฟซที่พบบ่อยที่สุดสำหรับการเชื่อมต่ออุปกรณ์ต่อพ่วงกับอุปกรณ์คอมพิวเตอร์เดสก์ท็อปและอุปกรณ์เคลื่อนที่ นอกจากการกำหนดลักษณะทางไฟฟ้าของบัสและรูปแบบทั่วไปในการสื่อสารกับอุปกรณ์แล้ว ข้อกำหนดของ USB ยังมีชุดข้อกำหนดของคลาสอุปกรณ์ด้วย โมเดลเหล่านี้เป็นโมเดลทั่วไปสำหรับอุปกรณ์บางคลาส เช่น อุปกรณ์จัดเก็บข้อมูล เสียง วิดีโอ เครือข่าย ฯลฯ ที่ผู้ผลิตอุปกรณ์สามารถนำมาใช้งาน ข้อดีของข้อกําหนดเฉพาะระดับคลาสของอุปกรณ์เหล่านี้คือผู้ให้บริการระบบปฏิบัติการสามารถใช้ไดรเวอร์เดียวตามข้อกําหนดเฉพาะระดับคลาส ("ไดรเวอร์ระดับคลาส") และอุปกรณ์ใดก็ตามที่ใช้คลาสนั้นก็จะรองรับ นี่เป็นการพัฒนาที่ยอดเยี่ยมกว่าการที่ผู้ผลิตทุกรายต้องเขียนโปรแกรมควบคุมอุปกรณ์ของตนเอง
แต่อุปกรณ์บางเครื่องไม่เข้ากับคลาสอุปกรณ์มาตรฐานเหล่านี้ ผู้ผลิตอาจเลือกติดป้ายกำกับอุปกรณ์ว่าใช้คลาสเฉพาะผู้ให้บริการแทน ในกรณีนี้ ระบบปฏิบัติการจะเลือกโปรแกรมควบคุมอุปกรณ์ที่จะโหลดตามข้อมูลที่ระบุไว้ในแพ็กเกจโปรแกรมควบคุมอุปกรณ์ของผู้ให้บริการ โดยปกติแล้วจะเป็นชุดรหัสผู้ให้บริการและผลิตภัณฑ์ที่ทราบว่าใช้โปรโตคอลเฉพาะของผู้ให้บริการรายนั้นๆ
ฟีเจอร์อีกอย่างของ USB คืออุปกรณ์อาจมีอินเทอร์เฟซหลายรายการสำหรับโฮสต์ที่เชื่อมต่ออยู่ อินเทอร์เฟซแต่ละรายการสามารถใช้คลาสมาตรฐานหรือเป็นคลาสเฉพาะของผู้ให้บริการก็ได้ เมื่อระบบปฏิบัติการเลือกไดรเวอร์ที่เหมาะสมเพื่อจัดการอุปกรณ์ อินเทอร์เฟซแต่ละรายการจะอ้างสิทธิ์โดยไดรเวอร์อื่นได้ ตัวอย่างเช่น โดยทั่วไปแล้วเว็บแคม USB จะมีอินเทอร์เฟซ 2 รายการ ได้แก่ อินเทอร์เฟซที่ใช้ USB Video Class (สำหรับกล้อง) และอินเทอร์เฟซที่ใช้ USB Audio Class (สำหรับไมโครโฟน) ระบบปฏิบัติการไม่ได้โหลด "ไดรเวอร์เว็บแคม" รายการเดียว แต่โหลดไดรเวอร์คลาสวิดีโอและเสียงแยกต่างหาก ซึ่งจะรับผิดชอบฟังก์ชันแยกต่างหากของอุปกรณ์ องค์ประกอบของคลาสอินเทอร์เฟซนี้มีความยืดหยุ่นมากกว่า
ข้อมูลเบื้องต้นเกี่ยวกับ API
คลาส USB มาตรฐานหลายคลาสมี Web API ที่สอดคล้องกัน ตัวอย่างเช่น หน้าเว็บสามารถจับภาพวิดีโอจากอุปกรณ์คลาสวิดีโอได้โดยใช้ getUserMedia()
หรือรับเหตุการณ์อินพุตจากอุปกรณ์คลาสอินเทอร์เฟซที่โต้ตอบกับมนุษย์ (HID) โดยการฟัง KeyboardEvents หรือ PointerEvents หรือใช้ Gamepad หรือ WebHID API
เช่นเดียวกับอุปกรณ์บางประเภทที่ใช้คำจำกัดความคลาสมาตรฐาน ไม่ใช่อุปกรณ์บางเครื่องเท่านั้นที่ใช้ฟีเจอร์ที่สอดคล้องกับ 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 ที่เบราว์เซอร์จะนําผู้ใช้ไปเมื่อเสียบอุปกรณ์
The Branch Device Object Store (BOS) เป็นแนวคิดที่นำเสนอใน USB 3.0 แต่ก็มีการพอร์ตย้อนกลับไปยังอุปกรณ์ USB 2.0 ในฐานะส่วนหนึ่งของเวอร์ชัน 2.1 การประกาศการรองรับ WebUSB เริ่มต้นด้วยการใส่ข้อบ่งชี้ความสามารถของแพลตฟอร์มต่อไปนี้ในข้อบ่งชี้ BOS
ค่า | ช่อง | คำอธิบาย |
---|---|---|
ข้อบ่งชี้ที่เก็บออบเจ็กต์ของอุปกรณ์แบบไบนารี | ||
0x05 |
bLength | ขนาดของข้อบ่งชี้นี้ |
0x0F |
bDescriptorType | ข้อบ่งชี้ Object Store ของอุปกรณ์ไบนารี |
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-endian |
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 สามารถเชื่อมต่อกับอุปกรณ์และอ้างสิทธิ์อินเทอร์เฟซที่ไม่ได้อ้างสิทธิ์โดยไดรเวอร์เคอร์เนลหรือแอปพลิเคชันอื่น
Linux
Linux คล้ายกับ macOS แต่โดยค่าเริ่มต้นแล้วการกระจายส่วนใหญ่จะไม่ได้ตั้งค่าบัญชีผู้ใช้ที่มีสิทธิ์เปิดอุปกรณ์ USB เดมอนของระบบที่เรียกว่า udev จะเป็นผู้รับผิดชอบในการกำหนดผู้ใช้และกลุ่มที่ได้รับอนุญาตให้เข้าถึงอุปกรณ์ กฎเช่นนี้จะกำหนดการเป็นเจ้าของอุปกรณ์ที่ตรงกับรหัสผู้ให้บริการและรหัสผลิตภัณฑ์ที่ระบุให้กับกลุ่ม plugdev
ซึ่งเป็นกลุ่มทั่วไปสำหรับผู้ใช้ที่มีสิทธิ์เข้าถึงอุปกรณ์ต่อพ่วง
SUBSYSTEM=="usb", ATTR{idVendor}=="XXXX", ATTR{idProduct}=="XXXX", GROUP="plugdev"
แทนที่ XXXX
ด้วยผู้ให้บริการฐานสิบหกและรหัสผลิตภัณฑ์สำหรับอุปกรณ์ของคุณ เช่น 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 เป็นอนุกรม เนื่องจากไม่มี API ใน Android SDK สําหรับการสื่อสารกับอุปกรณ์ซีเรียล
ChromeOS
ChromeOS ทำงานบนพื้นฐานของ Linux เช่นกัน และไม่จำเป็นต้องแก้ไขการกําหนดค่าระบบ บริการ permission_broker จะควบคุมการเข้าถึงอุปกรณ์ USB และจะอนุญาตให้เบราว์เซอร์เข้าถึงอุปกรณ์ดังกล่าว ตราบใดที่มีอินเทอร์เฟซที่ไม่มีการอ้างสิทธิ์อย่างน้อย 1 รายการ
Windows
รูปแบบไดรเวอร์ Windows มีข้อกำหนดเพิ่มเติม ต่างจากแพลตฟอร์มอื่นๆ ที่มีความสามารถในการเปิดอุปกรณ์ USB จากแอปพลิเคชันของผู้ใช้ไม่ได้เป็นค่าเริ่มต้น แม้ว่าจะไม่มีไดรเวอร์ที่โหลดไว้ก็ตาม แต่จะใช้ไดรเวอร์พิเศษอย่าง WinUSB แทน ซึ่งต้องโหลดเพื่อให้อินเทอร์เฟซที่แอปพลิเคชันใช้เข้าถึงอุปกรณ์ ซึ่งทำได้ด้วยไฟล์ข้อมูลโปรแกรมควบคุม (INF) ที่กําหนดเองซึ่งติดตั้งในระบบ หรือโดยการแก้ไขเฟิร์มแวร์ของอุปกรณ์เพื่อให้ตัวระบุความเข้ากันได้ของระบบปฏิบัติการ Microsoft ในระหว่างการแจกแจง
ไฟล์ข้อมูลไดรเวอร์ (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 ได้ ใช้ New-Guid
PowerShell
cmdlet หรือเครื่องมือออนไลน์เพื่อสร้าง 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 ซึ่งอธิบายรายการรีจิสทรีที่สร้างเมื่อระบุอุปกรณ์ เมื่อทดสอบ ให้ลบรายการที่สร้างสำหรับอุปกรณ์เพื่อบังคับให้ Windows พยายามอ่านตัวบ่งชี้อีกครั้ง
ดูข้อมูลเพิ่มเติมได้ที่บล็อกโพสต์ของ Microsoft เกี่ยวกับวิธีใช้ข้อบ่งชี้เหล่านี้
ตัวอย่าง
ตัวอย่างโค้ดที่ใช้อุปกรณ์ที่รับรู้ WebUSB ซึ่งมีทั้งข้อบ่งชี้ WebUSB และข้อบ่งชี้ Microsoft OS จะอยู่ในโปรเจ็กต์ต่อไปนี้