สร้างอุปกรณ์เพื่อใช้ประโยชน์จาก WebUSB API อย่างเต็มที่
บทความนี้อธิบายวิธีสร้างอุปกรณ์เพื่อใช้ประโยชน์จาก WebUSB API อย่างเต็มที่ ดูข้อมูลเบื้องต้นเกี่ยวกับ API ได้ที่เข้าถึงอุปกรณ์ USB บนเว็บ
ข้อมูลเบื้องต้น
Universal Serial Bus (USB) กลายเป็นอินเทอร์เฟซที่พบบ่อยที่สุดสำหรับการเชื่อมต่ออุปกรณ์ต่อพ่วงกับอุปกรณ์คอมพิวเตอร์เดสก์ท็อปและอุปกรณ์เคลื่อนที่ นอกจากการกำหนดลักษณะทางไฟฟ้าของบัสและรูปแบบทั่วไปในการสื่อสารกับอุปกรณ์แล้ว ข้อกำหนดของ USB ยังมีชุดข้อกำหนดของคลาสอุปกรณ์ด้วย โมเดลเหล่านี้เป็นโมเดลทั่วไปสำหรับอุปกรณ์บางคลาส เช่น อุปกรณ์จัดเก็บข้อมูล เสียง วิดีโอ เครือข่าย ฯลฯ ที่ผู้ผลิตอุปกรณ์สามารถนำมาใช้งาน ข้อดีของข้อกําหนดเฉพาะระดับคลาสของอุปกรณ์เหล่านี้คือผู้ให้บริการระบบปฏิบัติการสามารถใช้ไดรเวอร์เดียวตามข้อกําหนดเฉพาะระดับคลาส ("ไดรเวอร์ระดับคลาส") และอุปกรณ์ใดก็ตามที่ใช้คลาสนั้นก็จะรองรับ นี่เป็นการพัฒนาที่ยอดเยี่ยมกว่าการที่ผู้ผลิตทุกรายต้องเขียนโปรแกรมควบคุมอุปกรณ์ของตนเอง
อย่างไรก็ตาม อุปกรณ์บางเครื่องไม่ตรงกับคลาสอุปกรณ์มาตรฐานเหล่านี้ ผู้ผลิตอาจเลือกติดป้ายกำกับอุปกรณ์ของตนว่าใช้คลาสที่เจาะจงผู้ให้บริการแทน ในกรณีนี้ ระบบปฏิบัติการจะเลือกโปรแกรมควบคุมอุปกรณ์ที่จะโหลดตามข้อมูลที่ระบุไว้ในแพ็กเกจโปรแกรมควบคุมอุปกรณ์ของผู้ให้บริการ ซึ่งโดยทั่วไปจะเป็นชุดรหัสผู้ให้บริการและผลิตภัณฑ์ที่ทราบว่าใช้โปรโตคอลเฉพาะของผู้ให้บริการรายนั้น
ฟีเจอร์อีกอย่างของ USB คืออุปกรณ์อาจมีอินเทอร์เฟซหลายรายการสำหรับโฮสต์ที่เชื่อมต่ออยู่ อินเทอร์เฟซแต่ละรายการสามารถใช้คลาสมาตรฐานหรือเป็นคลาสเฉพาะของผู้ให้บริการก็ได้ เมื่อระบบปฏิบัติการเลือกไดรเวอร์ที่เหมาะสมเพื่อจัดการอุปกรณ์ อินเทอร์เฟซแต่ละรายการจะอ้างสิทธิ์โดยไดรเวอร์อื่นได้ ตัวอย่างเช่น เว็บแคม USB มักจะมีอินเทอร์เฟซ 2 แบบ โดย 1 แบบจะใช้ 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 (อินเดีย) |
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 ที่เชื่อมโยงและปลายทางเดียวที่ใช้ส่งเหตุการณ์อินพุตไปยังระบบปฏิบัติการ อินเทอร์เฟซที่ 2 คืออินเทอร์เฟซเฉพาะของผู้ให้บริการที่มีปลายทาง 2 รายการ ซึ่งสามารถใช้ส่งคําสั่งไปยังอุปกรณ์และรับคําตอบกลับ
ข้อบ่งชี้ WebUSB
แม้ว่า WebUSB จะใช้งานได้กับอุปกรณ์หลายเครื่องโดยไม่ต้องแก้ไขเฟิร์มแวร์ แต่คุณก็เปิดใช้ฟังก์ชันการทำงานเพิ่มเติมได้โดยการทำเครื่องหมายอุปกรณ์ด้วยข้อบ่งชี้ที่เฉพาะเจาะจงซึ่งระบุว่ารองรับ WebUSB เช่น คุณสามารถระบุ URL ของหน้า Landing Page ที่เบราว์เซอร์จะนําผู้ใช้ไปเมื่อเสียบอุปกรณ์
อุปกรณ์ Binary 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-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
ด้วยรหัสผู้ให้บริการและรหัสผลิตภัณฑ์ในรูปแบบเลขฐาน 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 เป็นอนุกรม เนื่องจากไม่มี 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
วิธีการไฟล์ 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 อยู่ในโปรเจ็กต์เหล่านี้