हेड ट्रैकर एचआईडी प्रोटोकॉल

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

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

इस पेज पर, इन संसाधनों के बारे में जानकारी दी गई है:

टॉप लेवल का स्ट्रक्चर

Android फ़्रेमवर्क, हेड ट्रैकर डिवाइस को एचआईडी डिवाइस के तौर पर पहचानता है.

मान्य HID डिस्क्रिप्टर का पूरा उदाहरण देखने के लिए, अनुबंध 1: HID डिस्क्रिप्टर का उदाहरण देखें.

सबसे ऊपर के लेवल पर, हेड ट्रैकर डिवाइस एक ऐप्लिकेशन कलेक्शन है, जिसमें Sensors पेज (0x20) और Other: Custom इस्तेमाल (0xE1) शामिल है. इस कलेक्शन में कई डेटा फ़ील्ड (इनपुट) और प्रॉपर्टी (सुविधाएं) हैं.

प्रॉपर्टी और डेटा फ़ील्ड

इस सेक्शन में, हेड ट्रैकर डिवाइस के ऐप्लिकेशन कलेक्शन में मौजूद प्रॉपर्टी और डेटा फ़ील्ड के बारे में बताया गया है.

प्रॉपर्टी: सेंसर की जानकारी (0x0308)

सेंसर की जानकारी (0x0308) प्रॉपर्टी, रीड-ओनली ASCII (8-बिट) स्ट्रिंग प्रॉपर्टी है. इसमें ये वैल्यू होनी चाहिए:

हेड ट्रैकर का वर्शन 1.0:

#AndroidHeadTracker#1.0

हेड ट्रैकर का वर्शन 2.0 (Android 15 या इसके बाद के वर्शन में उपलब्ध है), जिसमें LE Audio की सुविधा शामिल है:

#AndroidHeadTracker#2.0#x

x एक पूर्णांक (1, 2, 3) है, जो ट्रांसपोर्ट के लिए इस्तेमाल किए जा सकने वाले सिस्टम की जानकारी देता है:

  • 1: एसीएल
  • 2: आईएसओ
  • 3: ACL + ISO

कोई शून्य-टर्मिनेटर नहीं होना चाहिए. इसका मतलब है कि वर्शन 1.0 के लिए, इस प्रॉपर्टी का कुल साइज़ 23 8-बिट वर्ण है.

यह प्रॉपर्टी, अन्य कस्टम सेंसर के साथ होने वाली गड़बड़ियों से बचने के लिए, अलग-अलग सेंसर के बीच अंतर करने के तौर पर काम करती है.

प्रॉपर्टी: पर्सिस्टेंट यूनीक आईडी (0x0302)

पर्सिस्टेंट यूनीक आईडी (0x0302) प्रॉपर्टी, 16 एलिमेंट का रीड-ओनली कलेक्शन है. हर एलिमेंट 8 बिट का होता है (कुल 128 बिट). कोई शून्य टर्मिनेटर नहीं होना चाहिए. इस प्रॉपर्टी का इस्तेमाल करना ज़रूरी नहीं है.

इस प्रॉपर्टी की मदद से, ऑडियो डिवाइसों में इंटिग्रेट किए गए हेड-ट्रैकिंग डिवाइसों को उस ऑडियो डिवाइस का रेफ़रंस मिलता है जिससे वे कनेक्ट होते हैं. ये स्कीम काम करती हैं.

स्टैंडअलोन हेड ट्रैकर

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

ब्लूटूथ के मैक पते का इस्तेमाल करके रेफ़रंस

ऑक्टेट 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
वैल्यू 0 0 0 0 0 0 0 0 B T ब्लूटूथ मैक

इस स्कीम में, पहले आठ ऑक्टेट 0 होने चाहिए. आठवें और नौवें ऑक्टेट में, क्रमशः ASCII वैल्यू B और T होनी चाहिए. इसके बाद के छह ऑक्टेट को ब्लूटूथ मैक पते के तौर पर समझा जाता है. ऐसा तब माना जाता है, जब हेड ट्रैकर डिवाइस, इस मैक पते वाले किसी भी ऑडियो डिवाइस पर लागू होता है. यह पता, पहचान वाला पता होना चाहिए. भले ही, डिवाइस कनेक्टिविटी बनाने के लिए किसी भी क्रम में लगाए गए मैक पते का इस्तेमाल करता हो. ब्लूटूथ क्लासिक (v1.0 एचआईडी फ़ॉर्मैट) और ब्लूटूथ एलई (v2.0 एचआईडी फ़ॉर्मैट) से कनेक्ट होने वाले ड्यूअल-मोड डिवाइसों को, एक ही आइडेंटिटी पते वाले दो एचआईडी डिस्क्रिप्टर दिखाने चाहिए. अलग-अलग बाईं और दाईं ओर मौजूद डिवाइसों वाले ड्यूअल-मोड डिवाइसों को, सिर्फ़ LE वाले सेकंडरी डिवाइस के बजाय, ड्यूअल-मोड वाले प्राइमरी डिवाइस का इस्तेमाल करके, ब्लूटूथ LE एचआईडी को एक्सपोज़ करना होगा.

यूयूआईडी का इस्तेमाल करके रेफ़रंस

जब भी ऑक्टेट 8 का सबसे अहम बिट (एमएसबी) सेट (≥0x80) होता है, तो फ़ील्ड को यूयूआईडी के तौर पर समझा जाता है, जैसा कि आरएफ़सी-4122 में बताया गया है. इससे जुड़ा ऑडियो डिवाइस, वही यूनीक यूआईडी उपलब्ध कराता है जो Android फ़्रेमवर्क पर रजिस्टर किया गया है. यह यूनीक यूआईडी, ट्रांसपोर्ट के इस्तेमाल किए गए टाइप के हिसाब से तय किए गए किसी खास तरीके से मिलता है.

प्रॉपर्टी: रिपोर्टिंग की स्थिति (0x0316)

रिपोर्टिंग स्टेटस (0x0316) प्रॉपर्टी, रीड/राइट प्रॉपर्टी है. इसमें एचआईडी स्पेसिफ़िकेशन में बताए गए स्टैंडर्ड सेमेटिक्स होते हैं. होस्ट इस प्रॉपर्टी का इस्तेमाल करके, डिवाइस को यह बताता है कि किन इवेंट की रिपोर्ट करनी है. सिर्फ़ कोई इवेंट नहीं (0x0840) और सभी इवेंट (0x0841) वैल्यू का इस्तेमाल किया जाता है.

इस फ़ील्ड की शुरुआती वैल्यू, 'कोई इवेंट नहीं' होनी चाहिए. साथ ही, डिवाइस को कभी भी इस वैल्यू में बदलाव करने की अनुमति नहीं होनी चाहिए. इसे सिर्फ़ होस्ट बदल सकता है.

प्रॉपर्टी: पावर स्टेट (0x0319)

पावर स्टेटस (0x0319) प्रॉपर्टी, एक रीड/राइट प्रॉपर्टी है. इसमें, एचआईडी स्पेसिफ़िकेशन में बताए गए स्टैंडर्ड सेमेटिक्स होते हैं. होस्ट इस प्रॉपर्टी का इस्तेमाल करके, डिवाइस को यह बताता है कि उसे किस पावर स्टेटस में होना चाहिए. सिर्फ़ फ़ुल पावर (0x0851) और पावर बंद है (0x0855) वैल्यू का इस्तेमाल किया जाता है.

इस फ़ील्ड की शुरुआती वैल्यू, डिवाइस तय करता है. डिवाइस को कभी भी इस वैल्यू में बदलाव नहीं करना चाहिए. यह बदलाव सिर्फ़ होस्ट को करना चाहिए.

प्रॉपर्टी: रिपोर्ट का इंटरवल (0x030E)

रिपोर्ट इंटरवल (0x030E) प्रॉपर्टी, एक रीड/राइट प्रॉपर्टी है. इसमें एचआईडी स्पेसिफ़िकेशन में बताए गए स्टैंडर्ड सेमेटिक्स होते हैं. होस्ट इस प्रॉपर्टी का इस्तेमाल करके, डिवाइस को यह बताता है कि उसे डेटा रीडिंग की रिपोर्ट कितनी बार भेजनी है. यूनिट सेकंड में होती हैं. इस वैल्यू की मान्य रेंज, डिवाइस के हिसाब से तय की जाती है और इसे फ़िज़िकल मिन/मैक्स मैकेनिज्म का इस्तेमाल करके बताया जाता है. रिपोर्टिंग रेट कम से कम 50 हर्ट्ज़ होना चाहिए. साथ ही, सुझाई गई ज़्यादा से ज़्यादा रिपोर्टिंग रेट 100 हर्ट्ज़ है. इसलिए, रिपोर्ट का कम से कम इंटरवल 20 मिलीसेकंड से कम या उसके बराबर होना चाहिए. साथ ही, हमारा सुझाव है कि यह 10 मिलीसेकंड से ज़्यादा या उसके बराबर हो.

प्रॉपर्टी: वेंडर के लिए रिज़र्व किया गया LE ट्रांसपोर्ट (0xF410)

वेंडर के लिए रिज़र्व की गई LE ट्रांसपोर्ट (0xF410) प्रॉपर्टी, एक रीड/राइट प्रॉपर्टी है. इसमें HID स्पेसिफ़िकेशन में बताए गए स्टैंडर्ड सेमेटिक्स होते हैं. होस्ट, चुने गए ट्रांसपोर्ट (एसीएल या आईएसओ) को दिखाने के लिए इस प्रॉपर्टी का इस्तेमाल करता है. सिर्फ़ वैल्यू ACL (0xF800) और ISO (0xF801) का इस्तेमाल किया जाता है. साथ ही, दोनों को लॉजिकल कलेक्शन में शामिल करना ज़रूरी है.

यह प्रॉपर्टी, पावर या रिपोर्टिंग की स्थितियों से पहले कॉन्फ़िगर की जाती है.

डेटा फ़ील्ड: कस्टम वैल्यू 1 (0x0544)

कस्टम वैल्यू 1 (0x0544) फ़ील्ड एक इनपुट फ़ील्ड है. इसका इस्तेमाल, सिर के मूवमेंट की असल जानकारी को रिपोर्ट करने के लिए किया जाता है. यह तीन एलिमेंट वाला कलेक्शन है. इसे HID स्पेसिफ़िकेशन के सेक्शन 6.2.2.7 में बताए गए, फ़िज़िकल वैल्यू के लिए सामान्य HID नियमों के मुताबिक समझा जाता है. हर एलिमेंट के लिए मान्य रेंज [-π, π] रेडियन है. यूनिट हमेशा रेडियन होती हैं.

एलिमेंट को इस तरह समझा जाता है: [rx, ry, rz], जैसे कि [rx, ry, rz] एक रोटेशन वेक्टर है, जो रेफ़रंस फ़्रेम से हेड फ़्रेम में ट्रांसफ़ॉर्म को दिखाता है. मैग्नीट्यूड [0..π] रेंज में होना चाहिए.

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

  • बाएं कान से दाएं कान तक X
  • Y, सिर के पिछले हिस्से से नाक तक (पीछे से आगे)
  • Z, गर्दन से लेकर सिर के ऊपर तक

डेटा फ़ील्ड: कस्टम वैल्यू 2 (0x0545)

कस्टम वैल्यू 2 (0x0545) फ़ील्ड एक इनपुट फ़ील्ड है. इसका इस्तेमाल, सिर के मूवमेंट की असल जानकारी को रिपोर्ट करने के लिए किया जाता है. यह तीन एलिमेंट वाला फ़िक्स्ड-पॉइंट कलेक्शन है. इसे भौतिक वैल्यू के लिए, सामान्य HID नियमों के हिसाब से समझा जाता है. यूनिट हमेशा रेडियन/सेकंड में होती हैं.

एलिमेंट को इस तरह समझा जाता है: [vx, vy, vz], जैसे कि [vx, vy, vz] एक रोटेशन वेक्टर है, जो हेड फ़्रेम के कोणीय वेग को दिखाता है (अपने आप के हिसाब से).

डेटा फ़ील्ड: कस्टम वैल्यू 3 (0x0546)

कस्टम वैल्यू 3 (0x0546) फ़ील्ड एक इनपुट फ़ील्ड है. इसका इस्तेमाल, रेफ़रंस फ़्रेम में रुकावटों को ट्रैक करने के लिए किया जाता है. यह स्केलर इंटिजर है, जिसका साइज़ 8 बिट होता है. हर बार फ़्रेम ऑफ़ रेफ़रंस बदलने पर, डिवाइस को इसे बढ़ाना चाहिए (रैपअराउंड के साथ). उदाहरण के लिए, अगर ओरिएंटेशन तय करने के लिए इस्तेमाल किए गए ओरिएंटेशन फ़िल्टर एल्गोरिदम की स्थिति रीसेट हो गई है. इस वैल्यू को, एचआईडी के सामान्य नियमों के हिसाब से, फ़िज़िकल वैल्यू के तौर पर समझा जाता है. हालांकि, असल वैल्यू और यूनिट से कोई फ़र्क़ नहीं पड़ता. होस्ट के लिए सिर्फ़ बदली गई वैल्यू ही काम की होती है. लॉजिकल यूनिट से फ़िज़िकल यूनिट में बदलने के दौरान, सटीक वैल्यू न दिखने से जुड़ी संख्या से जुड़ी समस्याओं से बचने के लिए, हमारा सुझाव है कि इस फ़ील्ड के लिए, फ़िज़िकल यूनिट की कम से कम वैल्यू, ज़्यादा से ज़्यादा वैल्यू, और यूनिट एक्सपोनेंट की वैल्यू को शून्य पर सेट करें.

रिपोर्ट का स्ट्रक्चर

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

डेटा फ़ील्ड के लिए, कस्टम वैल्यू 1, 2, और 3 फ़ील्ड एक ही रिपोर्ट में होने चाहिए. साथ ही, किसी डिवाइस (ऐप्लिकेशन कलेक्शन) के लिए, ये फ़ील्ड सिर्फ़ एक रिपोर्ट में होने चाहिए.

इनपुट रिपोर्ट भेजना

इन सभी शर्तों के पूरा होने पर, डिवाइस को समय-समय पर और अलग-अलग समय पर (HID इनपुट मैसेज के ज़रिए) इनपुट रिपोर्ट भेजनी चाहिए:

  • पावर स्टेटस प्रॉपर्टी, 'पूरी पावर' पर सेट है.
  • रिपोर्टिंग स्टेटस प्रॉपर्टी को 'सभी इवेंट' पर सेट किया गया है.
  • रिपोर्टिंग इंटरवल प्रॉपर्टी की वैल्यू शून्य से ज़्यादा हो.

रिपोर्टिंग इंटरवल प्रॉपर्टी से यह तय होता है कि रिपोर्ट कितनी बार भेजी जाएंगी. अगर ऊपर बताई गई कोई भी शर्त पूरी नहीं होती है, तो डिवाइस को कोई रिपोर्ट नहीं भेजनी चाहिए.

नए और पुराने सिस्टम के साथ काम करने की सुविधा

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

किसी डिवाइस पर काम करने वाले वर्शन का पता लगाने के लिए, उसके सेंसर के ब्यौरे (0x0308) की प्रॉपर्टी की जांच करें.

माइनर वर्शन के साथ काम करने की सुविधा

माइनर वर्शन में किए गए बदलाव, उसी मेजर वर्शन पर आधारित पुराने माइनर वर्शन के साथ काम करते हैं. माइनर वर्शन के अपडेट में, होस्ट अतिरिक्त डेटा फ़ील्ड और प्रॉपर्टी को अनदेखा करता है. उदाहरण के लिए, प्रोटोकॉल के वर्शन 1.6 का इस्तेमाल करने वाला डिवाइस, ऐसे होस्ट के साथ काम करता है जो प्रोटोकॉल के वर्शन 1.x के साथ काम करता है. इसमें वर्शन 1.5 भी शामिल है.

मेजर वर्शन के साथ काम करने की सुविधा

पुराने वर्शन के साथ काम न करने वाले बदलाव, मुख्य वर्शन में किए जा सकते हैं. डिवाइसों के report descriptor में, एक से ज़्यादा ऐप्लिकेशन कलेक्शन की जानकारी दी जा सकती है. इससे, पुराने और नए होस्ट के साथ इंटरऑपरेबिलिटी के लिए, एक से ज़्यादा मुख्य वर्शन का इस्तेमाल किया जा सकता है. उदाहरण के लिए:

const unsigned char ReportDescriptor[] = {
    HID_USAGE_PAGE_SENSOR,
    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,

    HID_COLLECTION(HID_APPLICATION),
        // Feature report 2 (read-only).
        HID_REPORT_ID(2),

        // Magic value: "#AndroidHeadTracker#1.5"
        HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(0xFF),
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(23),
        HID_FEATURE(HID_CONST_VAR_ABS),

      ...

    HID_END_COLLECTION,

    HID_COLLECTION(HID_APPLICATION),
        // Feature report 12 (read-only).
        HID_REPORT_ID(12),

        // Magic value: "#AndroidHeadTracker#2.4"
        HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(0xFF),
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(23),
        HID_FEATURE(HID_CONST_VAR_ABS),

      ...

    HID_END_COLLECTION,
};

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

परिशिष्ट: एचआईडी डिस्क्रिप्टर का उदाहरण

नीचे दिए गए उदाहरण में, मान्य HID डिस्क्रिप्टर के बारे में बताया गया है. यह एचआईडी सेंसर के इस्तेमाल (सेक्शन 4.1) में दिए गए, आम तौर पर इस्तेमाल होने वाले C मैक्रो का इस्तेमाल करता है.

const unsigned char ReportDescriptor[] = {
    HID_USAGE_PAGE_SENSOR,
    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,
    HID_COLLECTION(HID_APPLICATION),
        // Feature report 2 (read-only).
        HID_REPORT_ID(2),

        // Magic value: "#AndroidHeadTracker#1.0"
        HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(0xFF),
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(23),
        HID_FEATURE(HID_CONST_VAR_ABS),

        // UUID.
        HID_USAGE_SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(0xFF),
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(16),
        HID_FEATURE(HID_CONST_VAR_ABS),

        // Feature report 1 (read/write).
        HID_REPORT_ID(1),

        // 1-bit on/off reporting state.
        HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(1),
        HID_REPORT_SIZE(1),
        HID_REPORT_COUNT(1),
        HID_COLLECTION(HID_LOGICAL),
            HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS,
            HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS,
            HID_FEATURE(HID_DATA_ARR_ABS),
        HID_END_COLLECTION,

        // 1-bit on/off power state.
        HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(1),
        HID_REPORT_SIZE(1),
        HID_REPORT_COUNT(1),
        HID_COLLECTION(HID_LOGICAL),
            HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF,
            HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER,
            HID_FEATURE(HID_DATA_ARR_ABS),
        HID_END_COLLECTION,

        // 6-bit reporting interval, with values [0x00..0x3F] corresponding to [10ms..100ms].
        HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
        HID_LOGICAL_MIN_8(0x00),
        HID_LOGICAL_MAX_8(0x3F),
        HID_PHYSICAL_MIN_8(10),
        HID_PHYSICAL_MAX_8(100),
        HID_REPORT_SIZE(6),
        HID_REPORT_COUNT(1),
        HID_USAGE_SENSOR_UNITS_SECOND,
        HID_UNIT_EXPONENT(0xD),  // 10^-3
        HID_FEATURE(HID_DATA_VAR_ABS),

        // Input report 1

        // Orientation as rotation vector (scaled to [-pi..pi] rad).
        HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
        HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
        HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
        HID_PHYSICAL_MIN_32(0x60, 0x4F, 0x46, 0xED),  // -314159265
        HID_PHYSICAL_MAX_32(0xA1, 0xB0, 0xB9, 0x12),  // 314159265
        HID_UNIT_EXPONENT(0x08),  // 10^-8
        HID_REPORT_SIZE(16),
        HID_REPORT_COUNT(3),
        HID_INPUT(HID_DATA_VAR_ABS),

        // Angular velocity as rotation vector (scaled to [-32..32] rad/sec).
        HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
        HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
        HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
        HID_PHYSICAL_MIN_8(0xE0),
        HID_PHYSICAL_MAX_8(0x20),
        HID_UNIT_EXPONENT(0x00),  // 10^0
        HID_REPORT_SIZE(16),
        HID_REPORT_COUNT(3),
        HID_INPUT(HID_DATA_VAR_ABS),

        // Reference frame reset counter.
        HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
        HID_LOGICAL_MIN_16(0x00, 0x00), // LOGICAL_MINIMUM (0)
        HID_LOGICAL_MAX_16(0xFF, 0x00), // LOGICAL_MAXIMUM (255)
        HID_PHYSICAL_MIN_8(0x00),
        HID_PHYSICAL_MAX_8(0x00),
        HID_UNIT_EXPONENT(0x00),  // 10^0
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(1),
        HID_INPUT(HID_DATA_VAR_ABS),

    HID_END_COLLECTION,
};

अपेंडिक्स 2: v2.0 HID डिस्क्रिप्टर का उदाहरण

यहां दिए गए उदाहरण में, सिर्फ़ ब्लूटूथ LE ACL ट्रांसपोर्ट की सुविधा वाले डिवाइस के लिए, v2.0 एचआईडी डिस्क्रिप्टर दिखाया गया है.

const unsigned char ReportDescriptor[] = {
    HID_USAGE_PAGE_SENSOR,
    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,
    HID_COLLECTION(HID_APPLICATION),
        // Feature report 2 (read-only).
        HID_REPORT_ID(2),

        // Magic value: "#AndroidHeadTracker#2.0#1"
        HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(0xFF),
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(25),
        HID_FEATURE(HID_CONST_VAR_ABS),

        // UUID.
        HID_USAGE_SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(0xFF),
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(16),
        HID_FEATURE(HID_CONST_VAR_ABS),

        // Feature report 1 (read/write).
        HID_REPORT_ID(1),

        // 1-bit on/off reporting state.
        HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(1),
        HID_REPORT_SIZE(1),
        HID_REPORT_COUNT(1),
        HID_COLLECTION(HID_LOGICAL),
            HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS,
            HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS,
            HID_FEATURE(HID_DATA_ARR_ABS),
        HID_END_COLLECTION,

        // 1-bit on/off power state.
        HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(1),
        HID_REPORT_SIZE(1),
        HID_REPORT_COUNT(1),
        HID_COLLECTION(HID_LOGICAL),
            HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF,
            HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER,
            HID_FEATURE(HID_DATA_ARR_ABS),
        HID_END_COLLECTION,

        // 6-bit reporting interval, with values [0x00..0x3F] corresponding to [10ms..100ms].
        HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
        HID_LOGICAL_MIN_8(0x00),
        HID_LOGICAL_MAX_8(0x3F),
        HID_PHYSICAL_MIN_8(10),
        HID_PHYSICAL_MAX_8(100),
        HID_REPORT_SIZE(6),
        HID_REPORT_COUNT(1),
        HID_USAGE_SENSOR_UNITS_SECOND,
        HID_UNIT_EXPONENT(0xD),  // 10^-3
        HID_FEATURE(HID_DATA_VAR_ABS),

        // 1-bit transport selection
        HID_USAGE_SENSOR_PROPERTY_VENDOR_LE_TRANSPORT,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(1),
        HID_REPORT_SIZE(1),
        HID_REPORT_COUNT(1),
        HID_COLLECTION(HID_LOGICAL),
            HID_USAGE_SENSOR_PROPERTY_VENDOR_LE_TRANSPORT_ACL,
            HID_USAGE_SENSOR_PROPERTY_VENDOR_LE_TRANSPORT_ISO,
            HID_FEATURE(HID_DATA_ARR_ABS),
        HID_END_COLLECTION,

        // Input report 1

        // Orientation as rotation vector (scaled to [-pi..pi] rad).
        HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
        HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
        HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
        HID_PHYSICAL_MIN_32(0x60, 0x4F, 0x46, 0xED),  // -314159265
        HID_PHYSICAL_MAX_32(0xA1, 0xB0, 0xB9, 0x12),  // 314159265
        HID_UNIT_EXPONENT(0x08),  // 10^-8
        HID_REPORT_SIZE(16),
        HID_REPORT_COUNT(3),
        HID_INPUT(HID_DATA_VAR_ABS),

        // Angular velocity as rotation vector (scaled to [-32..32] rad/sec).
        HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
        HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
        HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
        HID_PHYSICAL_MIN_8(0xE0),
        HID_PHYSICAL_MAX_8(0x20),
        HID_UNIT_EXPONENT(0x00),  // 10^0
        HID_REPORT_SIZE(16),
        HID_REPORT_COUNT(3),
        HID_INPUT(HID_DATA_VAR_ABS),

        // Reference frame reset counter.
        HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
        HID_LOGICAL_MIN_16(0x00, 0x00), // LOGICAL_MINIMUM (0)
        HID_LOGICAL_MAX_16(0xFF, 0x00), // LOGICAL_MAXIMUM (255)
        HID_PHYSICAL_MIN_8(0x00),
        HID_PHYSICAL_MAX_8(0x00),
        HID_UNIT_EXPONENT(0x00),  // 10^0
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(1),
        HID_INPUT(HID_DATA_VAR_ABS),

    HID_END_COLLECTION,
};