WebUSB के लिए डिवाइस बनाना

WebUSB API का पूरा फ़ायदा पाने के लिए, कोई डिवाइस बनाएं.

इस लेख में, WebUSB API का पूरा फ़ायदा पाने के लिए, डिवाइस बनाने का तरीका बताया गया है. एपीआई के बारे में खास जानकारी के लिए, वेब पर यूएसबी डिवाइसों को ऐक्सेस करना लेख पढ़ें.

बैकग्राउंड

यूनिवर्सल सीरियल बस (यूएसबी), डेस्कटॉप और मोबाइल कंप्यूटिंग डिवाइसों से पेरिफ़रल को कनेक्ट करने के लिए, सबसे सामान्य फ़िज़िकल इंटरफ़ेस बन गया है. यूएसबी की खास बातों में, बस की इलेक्ट्रिकल विशेषताओं और किसी डिवाइस के साथ कम्यूनिकेट करने के लिए सामान्य मॉडल के साथ-साथ, डिवाइस क्लास की खास बातों का एक सेट भी शामिल होता है. ये डिवाइसों की खास क्लास के लिए सामान्य मॉडल हैं. जैसे, स्टोरेज, ऑडियो, वीडियो, नेटवर्किंग वगैरह. डिवाइस बनाने वाली कंपनियां इन्हें लागू कर सकती हैं. डिवाइस क्लास की इन खास बातों का फ़ायदा यह है कि ऑपरेटिंग सिस्टम का कोई वेंडर, क्लास की खास बातों के आधार पर एक ड्राइवर लागू कर सकता है. इसे "क्लास ड्राइवर" कहा जाता है. इस क्लास को लागू करने वाले किसी भी डिवाइस पर, यह ड्राइवर काम करेगा. यह एक बेहतरीन बदलाव था, क्योंकि इससे हर मैन्युफ़ैक्चरर को अपने डिवाइस के लिए ड्राइवर लिखने की ज़रूरत नहीं पड़ती थी.

हालांकि, कुछ डिवाइस इनमें से किसी डिवाइस क्लास में नहीं आते. इसके बजाय, मैन्युफ़ैक्चरर अपने डिवाइस को, वेंडर के हिसाब से बनी क्लास को लागू करने के तौर पर लेबल कर सकता है. इस मामले में, ऑपरेटिंग सिस्टम यह चुनता है कि किस डिवाइस ड्राइवर को लोड करना है. यह विकल्प, वेंडर के ड्राइवर पैकेज में दी गई जानकारी के आधार पर चुना जाता है. आम तौर पर, यह वेंडर और प्रॉडक्ट आईडी का एक सेट होता है. इन आईडी से, वेंडर के हिसाब से प्रोटोकॉल लागू करने में मदद मिलती है.

यूएसबी की एक और सुविधा यह है कि डिवाइस, उस होस्ट को कई इंटरफ़ेस दे सकते हैं जिससे वे कनेक्ट हैं. हर इंटरफ़ेस, स्टैंडर्ड क्लास या वेंडर-स्पेसिफ़िक क्लास में से किसी एक को लागू कर सकता है. जब कोई ऑपरेटिंग सिस्टम, डिवाइस को मैनेज करने के लिए सही ड्राइवर चुनता है, तो हर इंटरफ़ेस पर किसी अलग ड्राइवर का दावा किया जा सकता है. उदाहरण के लिए, यूएसबी वेबकैम आम तौर पर दो इंटरफ़ेस उपलब्ध कराता है. पहला, कैमरे के लिए यूएसबी वीडियो क्लास और दूसरा, माइक्रोफ़ोन के लिए यूएसबी ऑडियो क्लास. ऑपरेटिंग सिस्टम, एक "वेबकैम ड्राइवर" नहीं लोड करता, बल्कि अलग-अलग वीडियो और ऑडियो क्लास के ड्राइवर लोड करता है. ये ड्राइवर, डिवाइस के अलग-अलग फ़ंक्शन की ज़िम्मेदारी लेते हैं. इंटरफ़ेस क्लास का यह कॉम्पोज़िशन, ज़्यादा सुविधाएं देता है.

एपीआई के बारे में बुनियादी जानकारी

कई स्टैंडर्ड यूएसबी क्लास के लिए, वेब एपीआई उपलब्ध होते हैं. उदाहरण के लिए, कोई पेज getUserMedia() का इस्तेमाल करके, वीडियो क्लास डिवाइस से वीडियो कैप्चर कर सकता है. इसके अलावा, KeyboardEvents या PointerEvents को सुनकर या Gamepad या WebHID एपीआई का इस्तेमाल करके, किसी मानव इंटरफ़ेस (एचआईडी) क्लास डिवाइस से इनपुट इवेंट भी पा सकता है. जिस तरह सभी डिवाइसों पर स्टैंडर्ड क्लास की परिभाषा लागू नहीं होती, उसी तरह सभी डिवाइसों पर वे सुविधाएं भी लागू नहीं होतीं जो मौजूदा वेब प्लैटफ़ॉर्म एपीआई से जुड़ी होती हैं. ऐसे में, WebUSB API इस अंतर को भर सकता है. यह साइटों को वेंडर के हिसाब से इंटरफ़ेस पर दावा करने का तरीका उपलब्ध कराता है. साथ ही, अपने पेज से सीधे तौर पर इसके लिए सहायता लागू करता है.

किसी डिवाइस को WebUSB के ज़रिए ऐक्सेस करने के लिए, अलग-अलग प्लैटफ़ॉर्म पर अलग-अलग ज़रूरी शर्तें होती हैं. इसकी वजह यह है कि ऑपरेटिंग सिस्टम, यूएसबी डिवाइसों को अलग-अलग तरीके से मैनेज करते हैं. हालांकि, बुनियादी तौर पर यह ज़रूरी है कि डिवाइस में पहले से ही उस इंटरफ़ेस के लिए ड्राइवर मौजूद न हो जिसे पेज को कंट्रोल करना है. यह ओएस वेंडर की ओर से उपलब्ध कराया गया सामान्य क्लास ड्राइवर या वेंडर की ओर से उपलब्ध कराया गया डिवाइस ड्राइवर हो सकता है. यूएसबी डिवाइसों में एक से ज़्यादा इंटरफ़ेस हो सकते हैं. इनमें से हर इंटरफ़ेस का अपना ड्राइवर हो सकता है. इसलिए, ऐसा डिवाइस बनाया जा सकता है जिसके कुछ इंटरफ़ेस पर ड्राइवर का दावा हो और बाकी इंटरफ़ेस ब्राउज़र के लिए उपलब्ध हों.

उदाहरण के लिए, कोई हाई-एंड यूएसबी कीबोर्ड, एचआईडी क्लास इंटरफ़ेस दे सकता है. इस पर ऑपरेटिंग सिस्टम का इनपुट सबसिस्टम दावा करेगा. साथ ही, वेंडर के हिसाब से एक इंटरफ़ेस भी होगा, जो कॉन्फ़िगरेशन टूल के इस्तेमाल के लिए WebUSB के लिए उपलब्ध रहेगा. इस टूल को मैन्युफ़ैक्चरर की वेबसाइट पर उपलब्ध कराया जा सकता है. इससे उपयोगकर्ता, प्लैटफ़ॉर्म के हिसाब से किसी भी सॉफ़्टवेयर को इंस्टॉल किए बिना, डिवाइस के काम करने के तरीके में बदलाव कर सकता है. जैसे, मैक्रो बटन और लाइटिंग इफ़ेक्ट. ऐसे डिवाइस का कॉन्फ़िगरेशन डिस्क्रिप्टर कुछ ऐसा दिखेगा:

मान फ़ील्ड ब्यौरा
कॉन्फ़िगरेशन डिस्क्रिप्टर
0x09 bLength इस डिस्क्रिप्टर का साइज़
0x02 bDescriptorType कॉन्फ़िगरेशन डिस्क्रिप्टर
0x0039 wTotalLength डिस्क्रिप्टर की इस सीरीज़ की कुल लंबाई
0x02 bNumInterfaces इंटरफ़ेस की संख्या
0x01 bConfigurationValue पहला कॉन्फ़िगरेशन
0x00 iConfiguration कॉन्फ़िगरेशन का नाम (कोई नहीं)
0b1010000 bmAttributes रिमोट से चालू होने वाला, अपने-आप चार्ज होने वाला डिवाइस
0x32 bMaxPower ज़्यादा से ज़्यादा पावर को 2 एमए के इंक्रीमेंट में दिखाया जाता है
इंटरफ़ेस डिस्क्रिप्टर
0x09 bLength इस डिस्क्रिप्टर का साइज़
0x04 bDescriptorType इंटरफ़ेस डिस्क्रिप्टर
0x00 bInterfaceNumber इंटरफ़ेस 0
0x00 bAlternateSetting वैकल्पिक सेटिंग 0 (डिफ़ॉल्ट)
0x01 bNumEndpoints एक एंडपॉइंट
0x03 bInterfaceClass एचआईडी इंटरफ़ेस क्लास
0x01 bInterfaceSubClass बूट इंटरफ़ेस सब-क्लास
0x01 bInterfaceProtocol कीबोर्ड
0x00 iInterface इंटरफ़ेस का नाम (कोई नहीं)
एचआईडी डिस्क्रिप्टर
0x09 bLength इस डिस्क्रिप्टर का साइज़
0x21 bDescriptorType एचआईडी डिस्क्रिप्टर
0x0101 bcdHID एचआईडी वर्शन 1.1
0x00 bCountryCode हार्डवेयर के लिए टारगेट किया गया देश
0x01 bNumDescriptors फ़ॉलो करने के लिए एचआईडी क्लास डिस्क्रिप्टर की संख्या
0x22 bDescriptorType रिपोर्ट डिस्क्रिप्टर का टाइप
0x003F wDescriptorLength रिपोर्ट डिस्क्रिप्टर की कुल लंबाई
एंडपॉइंट डिस्क्रिप्टर
0x07 bLength इस डिस्क्रिप्टर का साइज़
0x05 bDescriptorType एंडपॉइंट डिस्क्रिप्टर
0b10000001 bEndpointAddress एंडपॉइंट 1 (भारत)
0b00000011 bmAttributes बातचीत को रोकें
0x0008 wMaxPacketSize आठ बाइट वाले पैकेट
0x0A bInterval 10 मिलीसेकंड का इंटरवल
इंटरफ़ेस डिस्क्रिप्टर
0x09 bLength इस डिस्क्रिप्टर का साइज़
0x04 bDescriptorType इंटरफ़ेस डिस्क्रिप्टर
0x01 bInterfaceNumber इंटरफ़ेस 1
0x00 bAlternateSetting वैकल्पिक सेटिंग 0 (डिफ़ॉल्ट)
0x02 bNumEndpoints दो एंडपॉइंट
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 तीसरा एंडपॉइंट (OUT)
0b00000010 bmAttributes बहुमात्रा
0x0040 wMaxPacketSize 64 बाइट के पैकेट
0x00 bInterval एक साथ कई एंडपॉइंट के लिए लागू नहीं

कॉन्फ़िगरेशन डिस्क्रिप्टर में एक साथ जोड़े गए कई डिस्क्रिप्टर होते हैं. हर फ़ील्ड bLength और bDescriptorType फ़ील्ड से शुरू होता है, ताकि उन्हें पहचाना जा सके. पहला इंटरफ़ेस, एचआईडी इंटरफ़ेस होता है. इसमें एचआईडी डिस्क्रिप्टर और एक एंडपॉइंट होता है. इसका इस्तेमाल, ऑपरेटिंग सिस्टम में इनपुट इवेंट डिलीवर करने के लिए किया जाता है. दूसरा इंटरफ़ेस, वेंडर के हिसाब से बनाया गया इंटरफ़ेस होता है. इसमें दो एंडपॉइंट होते हैं. इनका इस्तेमाल, डिवाइस को निर्देश भेजने और जवाब पाने के लिए किया जा सकता है.

WebUSB डिस्क्रिप्टर

WebUSB, फ़र्मवेयर में बदलाव किए बिना कई डिवाइसों के साथ काम कर सकता है. हालांकि, डिवाइस को खास डिस्क्रिप्टर के साथ मार्क करके, अतिरिक्त सुविधाएं चालू की जा सकती हैं. इससे, WebUSB के साथ काम करने की जानकारी मिलती है. उदाहरण के लिए, आपके पास लैंडिंग पेज का ऐसा यूआरएल तय करने का विकल्प होता है जिस पर ब्राउज़र, डिवाइस के प्लग इन होने पर उपयोगकर्ता को भेज सकता है.

Chrome में WebUSB की सूचना का स्क्रीनशॉट
WebUSB से जुड़ी सूचना.

बाइनरी डिवाइस ऑब्जेक्ट स्टोर (बीओएस) एक ऐसा कॉन्सेप्ट है जिसे यूएसबी 3.0 में पेश किया गया था. हालांकि, इसे वर्शन 2.1 के हिस्से के तौर पर, यूएसबी 2.0 डिवाइसों में भी बैकपोर्ट किया गया है. WebUSB के साथ काम करने की सुविधा का एलान करने के लिए, BOS डिस्क्रिप्टर में प्लैटफ़ॉर्म की क्षमता का यह डिस्क्रिप्टर शामिल करें:

मान फ़ील्ड ब्यौरा
बाइनरी डिवाइस ऑब्जेक्ट स्टोर डिस्क्रिप्टर
0x05 bLength इस डिस्क्रिप्टर का साइज़
0x0F bDescriptorType बाइनरी डिवाइस ऑब्जेक्ट स्टोर डिस्क्रिप्टर
0x001D wTotalLength डिस्क्रिप्टर की इस सीरीज़ की कुल लंबाई
0x01 bNumDeviceCaps बीओएस में डिवाइस की क्षमता के ब्यौरे की संख्या
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 प्लैटफ़ॉर्म की सुविधाओं के ब्यौरे का जीयूआईडी
0x0100 bcdVersion WebUSB डिस्क्रिप्टर का वर्शन 1.0
0x01 bVendorCode WebUSB के लिए bRequest वैल्यू
0x01 iLandingPage लैंडिंग पेज का यूआरएल

प्लैटफ़ॉर्म की क्षमता का यूनीक आइडेंटिफ़ायर (यूयूआईडी), इसे WebUSB प्लैटफ़ॉर्म की क्षमता के बारे में जानकारी देने वाले एलिमेंट के तौर पर पहचानता है. इससे डिवाइस के बारे में बुनियादी जानकारी मिलती है. ब्राउज़र, डिवाइस के बारे में ज़्यादा जानकारी पाने के लिए, bVendorCode वैल्यू का इस्तेमाल करता है. इससे, वह डिवाइस से अतिरिक्त अनुरोध कर पाता है. फ़िलहाल, सिर्फ़ एक अनुरोध तय किया गया है, वह है GET_URL, जो यूआरएल डिस्क्रिप्टर दिखाता है. ये स्ट्रिंग डिस्क्रिप्टर से मिलते-जुलते हैं, लेकिन इन्हें यूआरएल को कम से कम बाइट में एन्कोड करने के लिए डिज़ाइन किया गया है. "https://google.com" के लिए यूआरएल के ब्यौरे का स्ट्रिंग फ़ॉर्मैट कुछ ऐसा दिखेगा:

मान फ़ील्ड ब्यौरा
यूआरएल डिस्क्रिप्टर
0x0D bLength इस डिस्क्रिप्टर का साइज़
0x03 bDescriptorType यूआरएल डिस्क्रिप्टर
0x01 bScheme https://
"google.com" URL UTF-8 कोड में बदला गया यूआरएल कॉन्टेंट

जब आपका डिवाइस पहली बार प्लग इन किया जाता है, तो ब्राउज़र इस स्टैंडर्ड GET_DESCRIPTOR कंट्रोल ट्रांसफ़र को जारी करके, बीओएस डिस्क्रिप्टर को पढ़ता है:

bmRequestType bRequest wValue wIndex wLength डेटा (रिस्पॉन्स)
0b10000000 0x06 0x0F00 0x0000 * BOS डिस्क्रिप्टर

आम तौर पर, यह अनुरोध दो बार किया जाता है. पहली बार, wLength के लिए काफ़ी बड़ी वैल्यू दी जाती है, ताकि होस्ट को wTotalLength फ़ील्ड की वैल्यू पता चल सके. ऐसा, बड़े डेटा ट्रांसफ़र के लिए कमिट किए बिना किया जाता है. इसके बाद, जब डिस्क्रिप्टर की पूरी लंबाई पता चल जाती है, तब फिर से यह अनुरोध किया जाता है.

अगर WebUSB प्लैटफ़ॉर्म की क्षमता के ब्यौरे में iLandingPage फ़ील्ड को शून्य से ज़्यादा वैल्यू पर सेट किया गया है, तो ब्राउज़र WebUSB के लिए खास GET_URL अनुरोध करता है. इसके लिए, वह प्लैटफ़ॉर्म की क्षमता के ब्यौरे से bVendorCode वैल्यू पर सेट किए गए bRequest और iLandingPage वैल्यू पर सेट किए गए wValue के साथ कंट्रोल ट्रांसफ़र जारी करता है. GET_URL (0x02) के लिए अनुरोध कोड, wIndex में जाता है:

bmRequestType bRequest wValue wIndex wLength डेटा (रिस्पॉन्स)
0b11000000 0x01 0x0001 0x0002 * यूआरएल डिस्क्रिप्टर

फिर से, यह अनुरोध दो बार जारी किया जा सकता है, ताकि पहले पढ़े जा रहे डिस्क्रिप्टर की लंबाई का पता लगाया जा सके.

प्लैटफ़ॉर्म के हिसाब से ध्यान रखने वाली बातें

WebUSB API, यूएसबी डिवाइसों को ऐक्सेस करने के लिए एक जैसा इंटरफ़ेस उपलब्ध कराने की कोशिश करता है. हालांकि, डेवलपर को ऐप्लिकेशन पर लागू होने वाली ज़रूरी शर्तों के बारे में पता होना चाहिए. जैसे, डिवाइसों को ऐक्सेस करने के लिए वेब ब्राउज़र की ज़रूरी शर्तें.

macOS

macOS के लिए, कुछ खास करने की ज़रूरत नहीं है. WebUSB का इस्तेमाल करने वाली वेबसाइट, डिवाइस से कनेक्ट कर सकती है और उन इंटरफ़ेस पर दावा कर सकती है जिन पर किसी कर्नेल ड्राइवर या किसी दूसरे ऐप्लिकेशन ने दावा नहीं किया है.

Linux

Linux, macOS की तरह ही है. हालांकि, ज़्यादातर डिस्ट्रिब्यूशन में डिफ़ॉल्ट रूप से, उपयोगकर्ता खातों को यूएसबी डिवाइसों को खोलने की अनुमति नहीं दी जाती. 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() को कॉल करती है.

इसके अलावा, डेस्कटॉप Linux की तुलना में Android पर ज़्यादा डिवाइसों को ऐक्सेस किया जा सकेगा, क्योंकि डिफ़ॉल्ट रूप से इसमें कम ड्राइवर शामिल होते हैं. उदाहरण के लिए, यूएसबी सीडीसी-एसीएम क्लास को शामिल नहीं किया गया है. आम तौर पर, इसे यूएसबी-टू-सीरियल अडैप्टर लागू करते हैं. ऐसा इसलिए है, क्योंकि सीरियल डिवाइस के साथ कम्यूनिकेट करने के लिए, Android SDK में कोई एपीआई नहीं है.

ChromeOS

ChromeOS भी Linux पर आधारित है. साथ ही, इसके लिए सिस्टम कॉन्फ़िगरेशन में किसी तरह का बदलाव करने की ज़रूरत नहीं होती. permission_broker सेवा, यूएसबी डिवाइसों के ऐक्सेस को कंट्रोल करती है. साथ ही, जब तक कम से कम एक ऐसा इंटरफ़ेस मौजूद रहेगा जिस पर दावा नहीं किया गया है, तब तक ब्राउज़र को इन डिवाइसों को ऐक्सेस करने की अनुमति देगी.

Windows

Windows ड्राइवर मॉडल में एक और ज़रूरी शर्त शामिल की गई है. ऊपर बताए गए प्लैटफ़ॉर्म के मुकाबले, उपयोगकर्ता के ऐप्लिकेशन से यूएसबी डिवाइस को खोलने की सुविधा डिफ़ॉल्ट रूप से उपलब्ध नहीं होती. भले ही, कोई ड्राइवर लोड न किया गया हो. इसके बजाय, एक खास ड्राइवर, 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] सेक्शन, डिवाइस के लिए DeviceInterfaceGUIDs के सेट को कॉन्फ़िगर करता है. हर डिवाइस इंटरफ़ेस में GUID होना चाहिए, ताकि कोई ऐप्लिकेशन Windows API की मदद से उसे ढूंढ सके और उससे कनेक्ट कर सके. रैंडम GUID जनरेट करने के लिए, New-Guid PowerShell कमांड या किसी ऑनलाइन टूल का इस्तेमाल करें.

डेवलपमेंट के मकसद से, Zadig टूल एक आसान इंटरफ़ेस उपलब्ध कराता है. इसकी मदद से, यूएसबी इंटरफ़ेस के लिए लोड किए गए ड्राइवर को WinUSB ड्राइवर से बदला जा सकता है.

Microsoft OS के साथ काम करने की जानकारी देने वाले डिस्क्रिप्टर

ऊपर दिया गया INF फ़ाइल का तरीका मुश्किल है, क्योंकि इसके लिए हर उपयोगकर्ता की मशीन को पहले से कॉन्फ़िगर करना ज़रूरी है. Windows 8.1 और उसके बाद के वर्शन में, कस्टम यूएसबी डिस्क्रिप्टर का इस्तेमाल करके, एक और विकल्प उपलब्ध है. ये डिस्क्रिप्टर, डिवाइस को पहली बार प्लग इन करने पर, Windows ऑपरेटिंग सिस्टम को ऐसी जानकारी देते हैं जो आम तौर पर INF फ़ाइल में शामिल होती है.

WebUSB डिस्क्रिप्टर सेट अप करने के बाद, Microsoft के ओएस के साथ काम करने वाले डिस्क्रिप्टर को भी आसानी से जोड़ा जा सकता है. सबसे पहले, इस प्लैटफ़ॉर्म की अतिरिक्त सुविधाओं के ब्यौरे की मदद से, बीओएस डिस्क्रिप्टर को बड़ा करें. इसकी जानकारी देने के लिए, 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 चुना है. 0x07, wIndex में डाला गया, डिवाइस से Microsoft OS 2.0 डिस्क्रिप्टर सेट को वापस पाने का निर्देश है.

bmRequestType bRequest wValue wIndex wLength डेटा (रिस्पॉन्स)
0b11000000 0x02 0x0000 0x0007 * MS OS 2.0 डिस्क्रिप्टर सेट

किसी यूएसबी डिवाइस में कई फ़ंक्शन हो सकते हैं. इसलिए, डिस्क्रिप्टर सेट के पहले हिस्से में बताया जाता है कि उसके बाद की प्रॉपर्टी किस फ़ंक्शन से जुड़ी हैं. यहां दिए गए उदाहरण में, कॉम्पोज़िट डिवाइस के इंटरफ़ेस 1 को कॉन्फ़िगर किया गया है. डिस्क्रिप्टर, ओएस को इस इंटरफ़ेस के बारे में दो अहम जानकारी देता है. काम करने वाले डिवाइस का आईडी डिस्क्रिप्टर, 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 पर लागू होता है (कॉन्फ़िगरेशन आम तौर पर 1 से इंडेक्स किए जाते हैं, फिर भी इसे 0 से इंडेक्स किया जाता है)
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 स्ट्रिंग को आठ बाइट तक पैड किया गया
"\0\0\0\0\0\0\0\0" SubCompatibleID 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 UTF-16LE में एन्कोड किया गया जीयूआईडी और दो शून्य टर्मिनेटर

Windows, इस जानकारी के लिए डिवाइस से सिर्फ़ एक बार क्वेरी करेगा. अगर डिवाइस, मान्य डिस्क्रिप्टर के साथ जवाब नहीं देता है, तो अगली बार डिवाइस कनेक्ट होने पर, यह फिर से नहीं पूछेगा. Microsoft ने यूएसबी डिवाइस रजिस्ट्री एंट्री की सूची दी है. इसमें, किसी डिवाइस की जानकारी देते समय बनाई गई रजिस्ट्री एंट्री के बारे में बताया गया है. जांच करते समय, किसी डिवाइस के लिए बनाई गई एंट्री मिटाएं, ताकि Windows डिस्क्रिप्टर को फिर से पढ़ने की कोशिश कर सके.

ज़्यादा जानकारी के लिए, इन डिस्क्रिप्टर का इस्तेमाल करने के तरीके के बारे में Microsoft की ब्लॉग पोस्ट देखें.

उदाहरण

WebUSB के बारे में जानकारी रखने वाले डिवाइसों को लागू करने वाले कोड का उदाहरण, इन प्रोजेक्ट में देखा जा सकता है. इनमें WebUSB और Microsoft OS, दोनों डिस्क्रिप्टर शामिल हैं: