হেড ট্র্যাকার HID প্রোটোকল

Android 13 ও এর পরের যেকোনও ভার্সনে চলে এমন ডিভাইসের জন্য উপলভ্য হেড ট্র্যাকার হিউম্যান ইন্টারফেস ডিভাইস (HID) প্রোটোকল, USB বা ব্লুটুথের মাধ্যমে Android ডিভাইসের সাথে হেড-ট্র্যাকিং ডিভাইস কানেক্ট করার অনুমতি দেয় এবং সেন্সর ফ্রেমওয়ার্কের মাধ্যমে Android ফ্রেমওয়ার্ক ও অ্যাপের সাথে কানেক্ট করে। এই প্রোটোকলটি অডিও ভার্চুয়ালাইজার এফেক্ট (3D অডিও) কন্ট্রোল করার জন্য ব্যবহার করা হয়। এই পৃষ্ঠায় ডিভাইস ও হোস্ট শব্দগুলি ব্লুটুথ অর্থে ব্যবহার করা হয়েছে, যেখানে ডিভাইস বলতে হেড-ট্র্যাকিং ডিভাইস এবং হোস্ট বলতে Android হোস্ট বোঝানো হয়েছে।

হেড ট্র্যাকার HID প্রোটোকলের জন্য সহায়তা চালু করতে ডিভাইস প্রস্তুতকারকদের অবশ্যই তাদের Android ডিভাইস কনফিগার করতে হবে। কনফিগারেশন সম্পর্কে আরও বিস্তারিত তথ্য পেতে, ডায়নামিক সেন্সর README দেখুন।

এই পৃষ্ঠাটি নিম্নলিখিত রিসোর্স সম্পর্কে আপনার ধারণা আছে বলে ধরে নেয়:

টপ-লেভেল স্ট্রাকচার

Android ফ্রেমওয়ার্ক হেড ট্র্যাকার ডিভাইসকে HID ডিভাইস হিসেবে শনাক্ত করে।

সঠিক HID ডেসক্রিপ্টরের সম্পূর্ণ উদাহরণ দেখতে, পরিশিষ্ট ১: HID ডেসক্রিপ্টরের উদাহরণ দেখুন।

সবচেয়ে উপরের লেভেলে, হেড ট্র্যাকার ডিভাইস হল একটি অ্যাপ সংগ্রহ যেখানে Sensors পৃষ্ঠা (0x20) ও Other: Custom ব্যবহার (0xE1) রয়েছে। এই সংগ্রহের মধ্যে একাধিক ডেটা ফিল্ড (ইনপুট) ও প্রপার্টি (ফিচার) রয়েছে।

প্রপার্টি ও ডেটা ফিল্ড

এই বিভাগে হেড ট্র্যাকার ডিভাইসের অ্যাপ্লিকেশন সংগ্রহের প্রপার্টি ও ডেটা ফিল্ড বর্ণনা করা হয়েছে।

প্রপার্টি: সেন্সর বিবরণ (0x0308)

সেন্সর বিবরণ (0x0308) প্রপার্টি হল শুধুমাত্র পাঠযোগ্য ASCII (৮-বিট) স্ট্রিং প্রপার্টি যাতে নিম্নলিখিত ভ্যালু থাকতে হবে:

হেড ট্র্যাকার ভার্সন 1.0:

#AndroidHeadTracker#1.0

হেড ট্র্যাকার ভার্সন ২.০ (Android ১৫ বা তার পরবর্তী যেকোনও ভার্সনে উপলভ্য), যাতে LE অডিওর জন্য সহায়তা অন্তর্ভুক্ত:

#AndroidHeadTracker#2.0#x

x হল একটি পূর্ণসংখ্যা (1, 2, 3) যা সাপোর্টেড ট্রান্সপোর্ট নির্দেশ করে:

  • ১: ACL
  • ২: ISO
  • ৩: ACL + ISO

কোনও নাল-টারমিনেটর থাকার কথা নয়, অর্থাৎ ভার্সন ১.০-এর জন্য এই প্রপার্টির মোট সাইজ হল ২৩টি ৮-বিট অক্ষর।

অন্যান্য কাস্টম সেন্সরের সাথে সংঘর্ষ এড়াতে এই প্রপার্টিটি ডিসক্রিমিনেটর হিসেবে কাজ করে।

প্রপার্টি: পারসিস্টেন্ট ইউনিক আইডি (0x0302)

পার্সিস্টেন্ট অনন্য আইডি (0x0302) প্রপার্টি হল ১৬ এলিমেন্টের একটি রিড-অনলি অ্যারে, প্রতিটি ৮ বিট (মোট ১২৮ বিট)। কোনও নাল টার্মিনেটর প্রত্যাশিত নয়। এই প্রপার্টি ঐচ্ছিক।

এই প্রপার্টি, অডিও ডিভাইসে ইন্টিগ্রেট করা হেড-ট্র্যাকিং ডিভাইসকে সেই অডিও ডিভাইসকে রেফারেন্স করার অনুমতি দেয়, যেটির সাথে এটি অ্যাটাচ করা আছে। নিম্নলিখিত স্কিম কাজ করে।

স্ট্যান্ডঅ্যালোন হেড ট্র্যাকার

পারসিস্টেন্ট অনন্য আইডি (0x0302) প্রপার্টি না থাকলে বা সব শূন্যে সেট করা থাকলে, এর অর্থ হল হেড ট্র্যাকার ডিভাইসটি কোনও অডিও ডিভাইসের সাথে স্থায়ীভাবে অ্যাটাচ করা নেই এবং এটি আলাদাভাবে ব্যবহার করা যেতে পারে, যেমন, ব্যবহারকারীকে আলাদা অডিও ডিভাইসের সাথে হেড ট্র্যাকার ডিভাইস ম্যানুয়ালি অ্যাসোসিয়েট করতে দেওয়া।

ব্লুটুথ MAC অ্যাড্রেস ব্যবহার করে রেফারেন্স

অক্টেট 0 1 ২ ৩ 4 5 6 7 ৮ 9 10 ১১ ১২ 13 14 15
মান 0 0 0 0 0 0 0 0 B T ব্লুটুথ MAC

এই স্কিমে, প্রথম ৮টি অক্টেট 0 হতে হবে, ৮ ও ৯ নম্বর অক্টেটে যথাক্রমে ASCII ভ্যালু B ও T থাকতে হবে এবং পরবর্তী ৬টি অক্টেটকে ব্লুটুথ MAC অ্যাড্রেস হিসেবে ব্যাখ্যা করা হয়, ধরে নেওয়া হয় যে হেড ট্র্যাকার ডিভাইস এই MAC অ্যাড্রেস আছে এমন যেকোনও অডিও ডিভাইসে প্রযোজ্য। এই অ্যাড্রেসটি অবশ্যই পরিচয় অ্যাড্রেস হতে হবে, এমনকি ডিভাইস কানেকশন প্রতিষ্ঠা করার জন্য র‍্যান্ডম MAC অ্যাড্রেস ব্যবহার করলেও। ব্লুটুথ ক্লাসিক (v1.0 HID ফর্ম্যাট) এবং ব্লুটুথ LE (v2.0 HID ফর্ম্যাট)-এর মাধ্যমে কানেক্ট করা ডুয়াল-মোড ডিভাইসকে একই আইডেন্টিটি অ্যাড্রেস সহ দুটি HID ডেসক্রিপ্টর দেখাতে হবে। আলাদা করা লেফট ও রাইট ডিভাইস সহ ডুয়াল-মোড ডিভাইসকে অবশ্যই LE-অনলি সেকেন্ডারি ডিভাইসের পরিবর্তে প্রাইমারি ডুয়াল মোড ডিভাইস ব্যবহার করে ব্লুটুথ LE HID এক্সপোজ করতে হবে।

UUID ব্যবহার করে রেফারেন্স

অকটেট ৮-এর সবচেয়ে গুরুত্বপূর্ণ বিট (MSB) সেট করা হলে (≥0x80), ফিল্ডটিকে UUID হিসেবে ব্যাখ্যা করা হয়, যেমনটি RFC-4122-এ উল্লেখ করা হয়েছে। সংশ্লিষ্ট অডিও ডিভাইস একই UUID প্রদান করে, যা Android ফ্রেমওয়ার্কে রেজিস্টার করা হয়। এটি এমন একটি অনির্দিষ্ট মেকানিজমের মাধ্যমে করা হয় যা ব্যবহৃত ট্রান্সপোর্টের ধরনের জন্য নির্দিষ্ট।

প্রপার্টি: রিপোর্টিং স্টেট (0x0316)

রিপোর্টিং স্টেট (0x0316) প্রপার্টি হল একটি রিড/রাইট প্রপার্টি যার HID স্পেসিফিকেশনে সংজ্ঞায়িত স্ট্যান্ডার্ড শব্দার্থবিদ্যা রয়েছে। কোন ইভেন্ট সম্পর্কে রিপোর্ট করতে হবে তা ডিভাইসকে জানানোর জন্য হোস্ট এই প্রপার্টি ব্যবহার করে। শুধুমাত্র মান No Events (0x0840) এবং All Events (0x0841) ব্যবহার করা হয়।

এই ফিল্ডের প্রাথমিক মান অবশ্যই কোনও ইভেন্ট নয় এবং এটি কখনই ডিভাইস দ্বারা পরিবর্তন করা যাবে না, শুধুমাত্র হোস্ট দ্বারা পরিবর্তন করা যাবে।

প্রপার্টি: পাওয়ার স্ট্যাটাস (0x0319)

পাওয়ার স্টেট (0x0319) প্রপার্টি হল একটি রিড/রাইট প্রপার্টি যার মধ্যে HID স্পেসিফিকেশনে সংজ্ঞায়িত স্ট্যান্ডার্ড সিম্যান্টিক্স থাকে। হোস্ট এই প্রপার্টি ব্যবহার করে ডিভাইসকে জানায় যে সেটি কোন পাওয়ার স্টেটে থাকতে হবে। শুধুমাত্র ভ্যালু ফুল পাওয়ার (0x0851) এবং পাওয়ার অফ (0x0855) ব্যবহার করা হয়।

এই ফিল্ডের প্রাথমিক মান ডিভাইস দ্বারা নির্ধারিত হয় এবং ডিভাইস দ্বারা কখনই পরিবর্তন করা উচিত নয়, শুধুমাত্র হোস্টের মাধ্যমে।

প্রপার্টি: রিপোর্ট ইন্টারভ্যাল (0x030E)

রিপোর্ট ইন্টারভ্যাল (0x030E) প্রপার্টি হল একটি রিড/রাইট প্রপার্টি, যার মধ্যে HID স্পেসিফিকেশনে সংজ্ঞায়িত স্ট্যান্ডার্ড সিম্যান্টিক্স থাকে। ডিভাইসকে কত ঘনঘন ডেটা রিডিং রিপোর্ট করতে হবে তা বোঝানোর জন্য হোস্ট এই প্রপার্টি ব্যবহার করে। একক হল সেকেন্ড। এই ভ্যালুর সঠিক রেঞ্জ ডিভাইস দ্বারা নির্ধারিত হয় এবং ফিজিক্যাল মিনিমাম/ম্যাক্সিমাম মেকানিজম ব্যবহার করে বর্ণনা করা হয়। অন্তত ৫০ Hz রিপোর্টিং রেট কাজ করতে হবে এবং সাজেস্ট করা সর্বাধিক রিপোর্টিং রেট হল ১০০ Hz. তাই, ন্যূনতম রিপোর্ট ইন্টারভ্যাল ২০ ms-এর সমান বা তার কম হতে হবে এবং ১০ ms-এর সমান বা তার বেশি হলে ভাল হয়।

প্রপার্টি: ভেন্ডর-রিজার্ভড LE ট্রান্সপোর্ট (0xF410)

Vendor-reserved LE Transport (0xF410) প্রপার্টি হল একটি রিড/রাইট প্রপার্টি যেটিতে HID স্পেসিফিকেশনে সংজ্ঞায়িত স্ট্যান্ডার্ড সিম্যান্টিক থাকে। হোস্ট বেছে নেওয়া ট্রান্সপোর্ট (ACL বা ISO) নির্দেশ করতে এই প্রপার্টি ব্যবহার করে। শুধুমাত্র ACL (0xF800) এবং ISO (0xF801) ভ্যালু ব্যবহার করা হয় এবং দুটিই লজিক্যাল সংগ্রহে অন্তর্ভুক্ত থাকতে হবে।

এই প্রপার্টি পাওয়ার বা রিপোর্টিং স্ট্যাটাসের আগে কনফিগার করা হয়।

ডেটা ফিল্ড: কাস্টম ভ্যালু ১ (0x0544)

কাস্টম ভ্যালু ১ (0x0544) ফিল্ড হল একটি ইনপুট ফিল্ড যা প্রকৃত হেড-ট্র্যাকিং তথ্য রিপোর্ট করার জন্য ব্যবহৃত হয়। এটি ৩-এলিমেন্ট অ্যারে, যা HID স্পেসিফিকেশনের ৬.২.২.৭ বিভাগে উল্লিখিত ভৌত মানের জন্য সাধারণ HID নিয়ম অনুসারে ব্যাখ্যা করা হয়। প্রতিটি এলিমেন্টের জন্য সঠিক রেঞ্জ হল [-π, π] rad। ইউনিট সবসময় রেডিয়ান হয়।

এলিমেন্টগুলিকে এইভাবে ব্যাখ্যা করা হয়: [rx, ry, rz], যেখানে [rx, ry, rz] হল একটি রোটেশন ভেক্টর, যা রেফারেন্স ফ্রেম থেকে হেড ফ্রেমে ট্রান্সফর্মেশনকে উপস্থাপন করে। ম্যাগনিটিউড অবশ্যই [0..π] রেঞ্জের মধ্যে হতে হবে।

রেফারেন্স ফ্রেমটি স্বেচ্ছামত বেছে নেওয়া হয়, তবে এটি সাধারণত ফিক্সড থাকে এবং অবশ্যই ডানহাতে হতে হবে। সামান্য পরিমাণ ড্রাফ্ট গ্রহণযোগ্য। হেড অ্যাক্সিস হল:

  • বাঁ কান থেকে ডান কানে X
  • Y মাথার পিছন থেকে নাকের ডগা পর্যন্ত (পিছন থেকে সামনের দিকে)
  • ঘাড় থেকে মাথার উপরের অংশ পর্যন্ত Z

ডেটা ফিল্ড: কাস্টম ভ্যালু ২ (0x0545)

কাস্টম ভ্যালু ২ (0x0545) ফিল্ড হল একটি ইনপুট ফিল্ড যা প্রকৃত হেড-ট্র্যাকিং তথ্য রিপোর্ট করার জন্য ব্যবহার করা হয়। এটি ৩-এলিমেন্ট ফিক্সড-পয়েন্ট অ্যারে, যা ভৌত ভ্যালুর জন্য সাধারণ HID নিয়ম অনুযায়ী ব্যাখ্যা করা হয়। ইউনিট সবসময় রেডিয়ান/সেকেন্ডে থাকে।

এলিমেন্টগুলিকে এইভাবে ব্যাখ্যা করা হয়: [vx, vy, vz], যেখানে [vx, vy, vz] হল একটি রোটেট করা ভেক্টর, যা হেড ফ্রেমের কৌণিক বেগ (সেটির সাপেক্ষে) দেখায়।

ডেটা ফিল্ড: কাস্টম ভ্যালু ৩ (0x0546)

কাস্টম ভ্যালু ৩ (0x0546) ফিল্ড হল একটি ইনপুট ফিল্ড যা রেফারেন্স ফ্রেমে ডিসকন্টিনিউটি ট্র্যাক করার জন্য ব্যবহার করা হয়। এটি স্কেলার ইন্টিজার, সাইজে ৮ বিট। রেফারেন্স ফ্রেম পরিবর্তন করা হলে, ডিভাইসটিকে অবশ্যই এটি ইনক্রিমেন্ট করতে হবে (র‍্যাপ-আউন্ড সহ)। যেমন, যদি ওরিয়েন্টেশন নির্ধারণের জন্য ব্যবহৃত ওরিয়েন্টেশন ফিল্টার অ্যালগরিদমের স্টেট রিসেট করা হয়। এই ভ্যালুকে ফিজিক্যাল ভ্যালুর জন্য সাধারণ HID নিয়ম অনুযায়ী ব্যাখ্যা করা হয়। তবে, ফিজিক্যাল ভ্যালু ও ইউনিট গুরুত্বপূর্ণ নয়। হোস্টের জন্য প্রাসঙ্গিক একমাত্র তথ্য হল পরিবর্তিত ভ্যালু। লজিক্যাল থেকে ফিজিক্যাল ইউনিটে কনভার্ট করার সময় নির্ভুলতা কমে যাওয়ার কারণে সংখ্যাগত সমস্যা এড়াতে, এই ফিল্ডের জন্য ফিজিক্যাল সর্বনিম্ন, ফিজিক্যাল সর্বোচ্চ এবং ইউনিট এক্সপোনেন্টের মান শূন্যে সেট করার সাজেশন দেওয়া হয়।

রিপোর্টের গঠন

রিপোর্টে প্রপার্টি গ্রুপ করা (রিপোর্ট আইডি অ্যাসাইন করার মাধ্যমে) ফ্লেক্সিবল। কার্যকারিতা বাড়াতে, আমরা রিড-অনলি প্রপার্টিকে রিড/রাইট প্রপার্টি থেকে আলাদা করার সাজেশন দিই।

ডেটা ফিল্ডের জন্য, কাস্টম ভ্যালু ১, ২ ও ৩ ফিল্ড একই রিপোর্টে থাকতে হবে এবং কোনও নির্দিষ্ট ডিভাইসের (অ্যাপ সংগ্রহ) জন্য শুধুমাত্র একটি রিপোর্টে থাকতে হবে।

ইনপুট রিপোর্ট পাঠানো

এইসব শর্ত পূরণ হলে, ডিভাইসকে পর্যায়ক্রমে এবং অ্যাসিঙ্ক্রোনাসভাবে (HID INPUT মেসেজের মাধ্যমে) ইনপুট রিপোর্ট পাঠাতে হবে:

  • পাওয়ার স্টেট প্রপার্টি 'সম্পূর্ণ পাওয়ার' হিসেবে সেট করা আছে।
  • Reporting State প্রপার্টি 'সব ইভেন্ট' হিসেবে সেট করা আছে।
  • রিপোর্টিং ইন্টারভ্যাল প্রপার্টি শূন্য নয়।

কত ঘনঘন রিপোর্ট পাঠাতে হবে তা রিপোর্টিং ইন্টারভ্যাল প্রপার্টি নির্ধারণ করে। উপরের শর্তগুলির মধ্যে কোনও একটি পূরণ না হলে, ডিভাইস কোনও রিপোর্ট পাঠাতে পারবে না।

পুরনো ও নতুন ভার্সনের সাথে মানানসই

হেড ট্র্যাকার HID প্রোটোকল একটি ভার্সনিং স্কিম ব্যবহার করে যা আপডেট করার অনুমতি দেয়, একই সাথে হোস্ট এবং ডিভাইসের মধ্যে ইন্টারঅপারেবিলিটি প্রদান করে যা প্রোটোকলের বিভিন্ন ভার্সন ব্যবহার করে। প্রোটোকলের ভার্সন দুটি সংখ্যা, মেজর ও মাইনর দ্বারা চিহ্নিত করা হয়, যেগুলির আলাদা আলাদা শব্দার্থ আছে। এগুলি নিম্নলিখিত বিভাগে বর্ণনা করা হয়েছে।

কোনও ডিভাইসে কাজ করে এমন ভার্সনগুলি সেটির সেন্সর বিবরণ (0x0308) প্রপার্টি পরীক্ষা করে নির্ধারণ করা যেতে পারে।

মাইনর ভার্সন কম্প্যাটিবিলিটি

মাইনর ভার্সনে করা পরিবর্তনগুলি একই মেজর ভার্সনের উপর ভিত্তি করে তৈরি আগের মাইনর ভার্সনের সাথে ব্যাকওয়ার্ড কম্প্যাটিবল। মাইনর ভার্সনের আপডেটে, হোস্ট অতিরিক্ত ডেটা ফিল্ড ও প্রপার্টি উপেক্ষা করে। যেমন, প্রোটোকল ভার্সন ১.৬ ব্যবহার করা ডিভাইস এমন হোস্টের সাথে মানানসই যা ভার্সন ১.৫ সহ প্রোটোকল ভার্সন ১.x-এ কাজ করে।

মেজর ভার্সন মানানসই

মেজর ভার্সনে পরিবর্তনের জন্য নন-ব্যাকওয়ার্ড-কম্প্যাটিবল পরিবর্তন করার অনুমতি দেওয়া হয়। পুরনো ও নতুন হোস্টের সাথে ইন্টার-অপারেবিলিটির জন্য একাধিক মেজর ভার্সন কাজ করে এমন সুবিধা দিতে, ডিভাইস তার রিপোর্ট ডেসক্রিপ্টরে একাধিক অ্যাপ সংগ্রহ নির্দিষ্ট করতে পারে। যেমন:

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 ডেসক্রিপ্টরের উদাহরণ

নিচের উদাহরণটি একটি সাধারণ বৈধ HID ডেসক্রিপ্টরকে ব্যাখ্যা করে। এটি HID Sensor Usages (বিভাগ ৪.১)-এ দেওয়া সাধারণত ব্যবহৃত 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,
};

পরিশিষ্ট ২: v2.0 HID ডেসক্রিপ্টরের উদাহরণ

নিম্নলিখিত উদাহরণে v2.0 HID ডেসক্রিপ্টর দেখানো হয়েছে যা শুধুমাত্র ব্লুটুথ LE ACL ট্রান্সপোর্ট কাজ করে এমন ডিভাইসের জন্য প্রযোজ্য।

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