دسکریپتور — یک ویژگی کمکی ویژگی BLE است که اطلاعات توصیفی یا پیکربندی را برای مقدار آن فراهم میکند. Bluetooth Core Specification 5.4 دسکریپتورها را به عنوان جزء جداییناپذیر پروفایل GATT تعریف میکند: آنها واحدهای اندازهگیری، محدوده مقادیر، نامهای متنی را توصیف میکنند و اشتراک در اعلانها را مدیریت میکنند. معروفترین دسکریپتور Client Characteristic Configuration Descriptor (CCCD, 0x2902) است که به Central اجازه میدهد در اعلانهای ویژگی مشترک شود. به گزارش Bluetooth SIG، 8 دسکریپتور استاندارد مشخص شدهاند و دسکریپتورهای سفارشی میتوانند توسط توسعهدهنده برای هر اطلاعات توصیفی اضافی ایجاد شوند.
نکات کلیدی
دسکریپتور — یک ویژگی پروتکل GATT است که به ویژگی متصل میشود و اطلاعات اضافی درباره مقدار یا روش استفاده آن ارائه میدهد. در اصطلاحات GATT، ویژگی داده است و دسکریپتور اطلاعات توصیفی آن دادههاست.
هر ویژگی میتواند صفر یا چندین دسکریپتور داشته باشد. دسکریپتورها به عنوان ویژگیهای جداگانه در جدول GATT تعریف میشوند و UUID ۱۶-بیتی خود را در فضای Bluetooth SIG دارند. دسکریپتورها نمیتوانند به صورت مستقل وجود داشته باشند — آنها همیشه به یک ویژگی خاص متصل هستند.
بر اساس Bluetooth Core Specification 5.4 (2023)، دسکریپتورها به دو دسته تقسیم میشوند: استاندارد (تعریف شده توسط Bluetooth SIG) و سفارشی (تعریف شده توسط توسعهدهنده). دسکریپتورهای استاندارد UUID در محدوده 0x2900–0x2908 دارند و کارکردهای مشخصی را انجام میدهند. دسکریپتورهای سفارشی از UUID ۱۲۸-بیتی استفاده میکنند، مانند خدمات و ویژگیهای سفارشی.
دسکریپتورها مکانیسم کلیدی برای پیکربندی برخورد اتصال BLE هستند. بدون CCCD (0x2902) نمیتوان در اعلانها مشترک شد، بدون Presentation Format (0x2904) Central نمیداند چگونه بایتهای خام ویژگی را تفسیر کند.
CCCD با UUID 0x2902 مهمترین و پرکاربردترین دسکریپتور در BLE است. آن اشتراک Central در اعلانها (Notify) و اعلانهای تأیید شده (Indicate) از ویژگی را مدیریت میکند. بدون نوشتن در CCCD، ویژگی اعلانها را ارسال نمیکند، حتی اگر ویژگی Notify را داشته باشد.
CCCD یک مقدار ۱۶-بیتی است که در آن کمترین بیت (0x0001) Notify را فعال میکند و بیت دوم (0x0002) Indicate را فعال میکند. Central مقدار مورد نیاز را در CCCD مینویسد و بدین ترتیب در اعلانها مشترک میشود. اگر Central 0x0000 بنویسد — اشتراک لغو میشود.
مکانیسم کار CCCD به این صورت است: وقتی Central یک ویژگی با پشتیبانی Notify را کشف میکند، دسکریپتور CCCD آن را پیدا کرده و 0x0001 را مینویسد. پس از آن، هر بار که Peripheral مقدار ویژگی را بهروز میکند، آن به طور خودکار از طریق Handle Value Notification به Central مشترک ارسال میشود (بدون درخواست از Central).
بر اساس Apple Core Bluetooth Programming Guide، CCCD به طور خودکار توسط سیستم هنگام فراخوانی setNotifyValue برای ویژگی مدیریت میشود. توسعهدهنده نیازی به جستجو و نوشتن دستی CCCD ندارد — Core Bluetooth با فعالسازی اعلانها این کار را خودکار انجام میدهد.
در iOS، اشتراک از طریق روش setNotifyValue بر شیئ CBPeripheral انجام میشود.
import CoreBluetooth
// در اعلانهای ویژگی مشترک شو
peripheral.setNotifyValue(true, for: characteristic)
// Delegate مقادیر بهروز شده را دریافت میکند
func peripheral(
_ peripheral: CBPeripheral,
didUpdateValueFor characteristic: CBCharacteristic,
error: Error?
) {
// characteristic.value داده جدید دارد
guard let data = characteristic.value else { return }
}
در Android، اشتراک در اعلانها از طریق BluetoothGatt.setCharacteristicNotification انجام میشود. توسعهدهنده باید مقدار 0x0001 را دستی در CCCD بنویسد.
import android.bluetooth.*;
// فعالسازی اعلانها
bluetoothGatt.setCharacteristicNotification(characteristic, true);
// نوشتن 0x0001 در CCCD
BluetoothGattDescriptor descriptor = characteristic
.getDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);
Bluetooth SIG ۸ دسکریپتور استاندارد برای کارهای رایج پیکربندی ویژگیها تعریف کرده است. هر دسکریپتور UUID و فرمت مقدار مشخصی دارد.
| UUID | نام دسکریپتور | کاربرد | نوع مقدار |
|---|---|---|---|
| 0x2900 | Characteristic Extended Properties | ویژگیهای اضافی ویژگی | uint16 (ماسک بیتی) |
| 0x2901 | Characteristic User Description | نام متنی ویژگی | UTF-8 string |
| 0x2902 | Client Characteristic Configuration | مدیریت اعلانها | uint16 |
| 0x2903 | Server Characteristic Configuration | پیکربندی سرور برای پخش همگانی | uint16 |
| 0x2904 | Characteristic Presentation Format | فرمت ارائه داده | ساختار (۷ بایت) |
| 0x2905 | Characteristic Aggregate Format | ترکیب چند ویژگی | فهرست UUID |
| 0x2906 | Valid Range | محدوده مقادیر مجاز | uint16 × 2 (min, max) |
| 0x2907 | External Report Reference | ارجاع به گزارش خارجی | uint16 |
| 0x2908 | Report Reference | ارجاع به گزارش داخلی | uint8 + uint16 |
Characteristic User Description (0x2901) بهویژه برای UI مفید است: آن شامل نام قابل خواندن ویژگی است که میتوان در رابط برنامه نمایش داد. مثلاً، ویژگی Battery Level میتواند دسکریپتور User Description با مقدار «سطح شارژ باتری» داشته باشد.
Characteristic Presentation Format (0x2904) شامل اطلاعاتی درباره چگونگی تفسیر مقدار ویژگی است: فرمات (uint8، uint16، float)، نمایه، واحد اندازهگیری (از طریق UUID از ثبت Bluetooth SIG)، فضای نام و توصیف. به عنوان مثال، دما میتواند int16 با نمایه -2 (مقدار تقسیم 0.01°C) و واحد اندازهگیری «درجه سانتیگراد» باشد.
دسترسی به دسکریپتورها در iOS و Android متفاوت است. Core Bluetooth به طور خودکار CCCD را هنگام فعالسازی اعلانها مدیریت میکند، اما Android نیاز به نوشتن دستی مقدار در دسکریپتور دارد. هر دو روش را بررسی میکنیم.
در iOS، توسعهدهنده معمولاً مستقیماً با دسکریپتورها ارتباط برقرار نمیکند. Core Bluetooth به طور خودکار CCCD را پیدا کرده و هنگام فراخوانی setNotifyValue مقدار مورد نیاز را در آن مینویسد. برای خواندن دسکریپتورها از روش discoverDescriptors استفاده میشود.
// کشف دسکریپتورها
peripheral.discoverDescriptors(for: characteristic)
// خواندن مقدار User Description
func peripheral(
_ peripheral: CBPeripheral,
didDiscoverDescriptorsFor characteristic: CBCharacteristic,
error: Error?
) {
for descriptor in characteristic.descriptors ?? [] {
if descriptor.uuid == CBUUID("2901") {
peripheral.readValue(for: descriptor)
}
}
}
در Android، توسعهدهنده باید خود دسکریپتور CCCD ویژگی را پیدا کرده و برای فعالسازی اعلانها مقداری را در آن بنویسد. این یک مرحله اضافی در مقایسه با iOS است.
// خواندن مقدار دسکریپتور User Description
BluetoothGattDescriptor userDesc = characteristic
.getDescriptor(
UUID.fromString("00002901-0000-1000-8000-00805F9B34FB")
);
if (userDesc != null) {
bluetoothGatt.readDescriptor(userDesc);
}
دسکریپتورهای سفارشی زمانی استفاده میشوند که دسکریپتورهای استاندارد Bluetooth SIG کافی نباشند. به عنوان مثال، سازنده حسگر پزشکی میتواند دسکریپتوری با اطلاعات کالیبراسیون حسگر یا دسکریپتوری با گزارش خطاها اضافه کند.
دسکریپتور سفارشی با UUID ۱۲۸-بیتی ایجاد میشود، مانند ویژگی سفارشی. در طرف Peripheral، توسعهدهنده آن را از طریق API مربوطه به ویژگی اضافه میکند. در طرف Central، دسکریپتور به طور خودکار با فراخوانی discoverDescriptors کشف میشود.
هنگام ایجاد دسکریپتور سفارشی قوانین را رعایت کنید: طول مقدار باید مناسب نوع داده مورد انتظار باشد، حقوق دسترسی (read/write) باید صریحاً مشخص شوند. از UUID های محدوده دسکریپتورهای استاندارد Bluetooth SIG (0x2900–0x2908) برای اهداف سفارشی استفاده نکنید.
ویژگی و دسکریپتور — سطح مختلفی از ویژگیهای GATT هستند. ویژگی یک نقطه داده است و دسکریپتور اطلاعات توصیفی یا پیکربندی آن است. تفاوت در چند جنبه آشکار میشود: کاربرد، UUID و قوانین دسترسی.
ویژگی یک اعلان اجباری (declaration) دارد که همیشه در جدول GATT وجود دارد. دسکریپتور اختیاری است — ویژگی میتواند دسکریپتور نداشته باشد. ویژگی میتواند به طور مستقل خوانده، نوشته شود یا اعلان ارسال کند. دسکریپتور همیشه به ویژگی متصل است و به صورت جداگانه وجود ندارد.
بر اساس Bluetooth Core Specification 5.4، در جدول GATT ترتیب ویژگیها به شرح زیر است: اعلان خدمت، اعلان ویژگی، مقدار ویژگی، دسکریپتورهای ویژگی (اگر وجود داشته باشند)، سپس خدمت بعدی. این ترتیب برای عملکرد صحیح مشتریان GATT اجباری است.
سوالات متداول
CCCD برای مدیریت اشتراک لازم است: ویژگی Notify فقط میگوید که ویژگی میتواند اعلان ارسال کند، اما آنها را فعال نمیکند. Central باید با نوشتن 0x0001 در CCCD به صورت صریح مشترک شود. این از ارسال دادههای نامطلوب به Central آماده نشده جلوگیری میکند.
مشخصات تعداد دسکریپتورها را محدود نمیکند. در عمل، هر ویژگی معمولاً ۱–۳ دسکریپتور دارد: CCCD (برای ویژگیهای با Notify/Indicate)، اختیاری User Description و Presentation Format. دسکریپتورهای بیش از حد اندازه جدول GATT را افزایش میدهند.
در اکثر موارد لازم نیست. Core Bluetooth در iOS و Android به طور خودکار CCCD را به ویژگیهایی که ویژگیهای Notify یا Indicate دارند اضافه میکند. دسکریپتورهای سفارشی فقط برای اطلاعات توصیفی مخصوص به صورت دستی ایجاد میشوند.
خیر، CCCD فرمت (uint16) و کاربرد مشخصی دارد — مدیریت اعلانها. نوشتن مقادیر دیگر مشخصات Bluetooth را نقض میکند و میتواند منجر به اشتراک نامعتبر شود. برای دادههای سفارشی از دسکریپتورهای سفارشی با UUID ۱۲۸-بیتی استفاده کنید.
User Description شامل نام قابل خواندن ویژگی است — به عنوان مثال، «دمای بدنه» به جای UUID 0x2A6E. برنامه میتواند این نام را در رابط نمایش دهد و تعامل با دستگاه BLE را بدون رشتههای سخت کدشده برای کاربر قابل فهم کند.
نتایج
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.