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

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

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

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

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

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

मान्य एचआईडी डिस्क्रिप्टर के पूरे उदाहरण के लिए, अपेंडिक्स 1: एचआईडी डिस्क्रिप्टर का उदाहरण देखें.

सबसे ऊपर, हेड ट्रैकर डिवाइस एक ऐप्लिकेशन कलेक्शन होता है. इसमें 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) प्रॉपर्टी मौजूद नहीं है या इसे सभी शून्य पर सेट किया गया है, तो इसका मतलब है कि हेड ट्रैकर डिवाइस, ऑडियो डिवाइस से स्थायी तौर पर अटैच नहीं है. इसका इस्तेमाल अलग से किया जा सकता है. उदाहरण के लिए, उपयोगकर्ता को हेड ट्रैकर डिवाइस को किसी दूसरे ऑडियो डिवाइस से मैन्युअल तरीके से जोड़ने की अनुमति देकर.

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

ऑक्टेट 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 ब्लूटूथ MAC

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

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

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

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

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

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

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

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

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

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

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

प्रॉपर्टी: वेंडर के लिए आरक्षित एलई ट्रांसपोर्ट (0xF410)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • पावर की स्थिति वाली प्रॉपर्टी को फुल पावर पर सेट किया गया है.
  • रिपोर्टिंग की स्थिति वाली प्रॉपर्टी को सभी इवेंट पर सेट किया गया हो.
  • Reporting Interval प्रॉपर्टी की वैल्यू शून्य नहीं है.

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

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

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

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

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

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

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

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

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,
};

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

अपेंडिक्स: एचआईडी डिस्क्रिप्टर का उदाहरण

यहाँ एक मान्य एचआईडी डिस्क्रिप्टर का उदाहरण दिया गया है. यह 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 डिस्क्रिप्टर का उदाहरण

यहां दिए गए उदाहरण में, सिर्फ़ ब्लूटूथ स्मार्ट एसीएल ट्रांसपोर्ट की सुविधा देने वाले डिवाइस के लिए, 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,
};