Descriptor: что это, Client Characteristic Configuration и примеры

Автор: IT Sectr Опубликовано: 2026-07-15 Время чтения: 8 мин

Descriptor — это вспомогательный атрибут BLE-характеристики, который предоставляет метаданные или конфигурацию для её значения. Bluetooth Core Specification 5.4 определяет дескрипторы как неотъемлемую часть GATT-профиля: они описывают единицы измерения, диапазоны значений, текстовые имена и управляют подпиской на уведомления. Наиболее известный дескриптор — Client Characteristic Configuration Descriptor (CCCD, 0x2902), который позволяет Central подписываться на уведомления от характеристики. По данным Bluetooth SIG, специфицировано 8 стандартных дескрипторов, а кастомные дескрипторы могут создаваться разработчиком для любых дополнительных метаданных.

Главное

  • Descriptor — вспомогательный атрибут характеристики, который содержит метаданные или конфигурацию значения.
  • CCCD (0x2902) — самый важный дескриптор: через него Central подписывается на уведомления об изменении характеристики.
  • Стандартные дескрипторы включают User Description (0x2901) для текстового имени и Presentation Format (0x2904) для формата данных.
  • Каждая характеристика может иметь несколько дескрипторов, но не более одного каждого стандартного типа.
  • Дескрипторы автоматически создаются Core Bluetooth, но могут быть кастомизированы для специфических метаданных.

Что такое Descriptor в BLE?

Descriptor — это атрибут GATT-протокола, который прикрепляется к Characteristic и предоставляет дополнительную информацию о её значении или способе использования. В терминологии GATT, характеристика — это данные, а дескриптор — это метаданные этих данных.

Каждая Characteristic может иметь ноль или более дескрипторов. Дескрипторы определяются как отдельные атрибуты в GATT-таблице и имеют собственные 16-битные UUID в пространстве Bluetooth SIG. Дескрипторы не могут существовать самостоятельно — они всегда привязаны к конкретной характеристике.

По данным Bluetooth Core Specification 5.4 (2023), дескрипторы делятся на две категории: стандартные (определённые Bluetooth SIG) и кастомные (определяемые разработчиком). Стандартные дескрипторы имеют UUID в диапазоне 0x2900–0x2908 и выполняют строго определённые функции. Кастомные дескрипторы используют 128-битные UUID, аналогично кастомным сервисам и характеристикам.

Дескрипторы — это ключевой механизм для конфигурации поведения BLE-соединения. Без CCCD (0x2902) невозможно подписаться на уведомления, без Presentation Format (0x2904) Central не узнает, как интерпретировать сырые байты характеристики.

Client Characteristic Configuration Descriptor (CCCD)

CCCD с UUID 0x2902 — самый важный и широко используемый дескриптор в BLE. Он управляет подпиской Central на уведомления (Notify) и подтверждённые уведомления (Indicate) от характеристики. Без записи в CCCD характеристика не будет отправлять уведомления, даже если у неё есть свойство Notify.

CCCD — это 16-битное значение, в котором младший бит (0x0001) включает Notify, а второй бит (0x0002) включает Indicate. Central записывает нужное значение в CCCD, тем самым подписываясь на уведомления. Если Central записывает 0x0000 — подписка отменяется.

Механизм работы CCCD выглядит так: когда Central обнаруживает характеристику с поддержкой Notify, он находит её CCCD-дескриптор и записывает 0x0001. После этого, каждый раз когда Peripheral обновляет значение характеристики, оно автоматически отправляется подписанному Central через Handle Value Notification (без запроса от Central).

По данным Apple Core Bluetooth Programming Guide, CCCD автоматически управляется системой при вызове setNotifyValue для характеристики. Разработчику не нужно вручную искать и записывать CCCD — Core Bluetooth делает это самостоятельно при активации уведомлений.

Программная подписка на уведомления

В iOS подписка выполняется через метод setNotifyValue на объекте CBPeripheral.

swift
import CoreBluetooth

// Subscribe to characteristic notifications
peripheral.setNotifyValue(true, for: characteristic)

// Delegate receives updated values
func peripheral(
    _ peripheral: CBPeripheral,
    didUpdateValueFor characteristic: CBCharacteristic,
    error: Error?
) {
    // characteristic.value has new data
    guard let data = characteristic.value else { return }
}

На Android подписка на уведомления выполняется через BluetoothGatt.setCharacteristicNotification. Разработчик также должен записать значение 0x0001 в CCCD вручную.

java
import android.bluetooth.*;

// Enable notifications
bluetoothGatt.setCharacteristicNotification(characteristic, true);

// Write 0x0001 to CCCD
BluetoothGattDescriptor descriptor = characteristic
    .getDescriptor(
        UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
    );
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);

Стандартные дескрипторы Bluetooth SIG

Bluetooth SIG определил 8 стандартных дескрипторов для распространённых задач конфигурации характеристик. Каждый дескриптор имеет строго определённый UUID и формат значения.

UUIDИмя дескриптораНазначениеТип значения
0x2900Characteristic Extended PropertiesДополнительные свойства характеристикиuint16 (битовая маска)
0x2901Characteristic User DescriptionТекстовое имя характеристикиUTF-8 string
0x2902Client Characteristic ConfigurationУправление уведомлениямиuint16
0x2903Server Characteristic ConfigurationКонфигурация сервера для broadcastuint16
0x2904Characteristic Presentation FormatФормат представления данныхСтруктура (7 байт)
0x2905Characteristic Aggregate FormatОбъединение нескольких характеристикСписок UUID
0x2906Valid RangeДиапазон допустимых значенийuint16 × 2 (min, max)
0x2907External Report ReferenceСсылка на внешний отчётuint16
0x2908Report 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) и единицей измерения "градус Цельсия".

Как использовать Descriptor в iOS и Android

Доступ к дескрипторам отличается на iOS и Android. Core Bluetooth автоматически управляет CCCD при включении уведомлений, а Android требует ручной записи значения в дескриптор. Рассмотрим оба подхода.

iOS: автоматическое управление CCCD

В iOS разработчик обычно не взаимодействует с дескрипторами напрямую. Core Bluetooth автоматически находит CCCD и записывает в него нужное значение при вызове setNotifyValue. Для чтения дескрипторов используется метод discoverDescriptors.

swift
// Discover descriptors
peripheral.discoverDescriptors(for: characteristic)

// Read User Description value
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

На Android разработчик должен сам найти CCCD-дескриптор характеристики и записать в него значение для включения уведомлений. Это дополнительный шаг по сравнению с iOS.

java
// Read User Description descriptor value
BluetoothGattDescriptor userDesc = characteristic
    .getDescriptor(
        UUID.fromString("00002901-0000-1000-8000-00805F9B34FB")
    );

if (userDesc != null) {
    bluetoothGatt.readDescriptor(userDesc);
}

Создание кастомных дескрипторов

Кастомные дескрипторы используются, когда стандартных дескрипторов Bluetooth SIG недостаточно. Например, производитель медицинского датчика может добавить дескриптор с информацией о калибровке сенсора или дескриптор с логом ошибок.

Кастомный дескриптор создаётся с 128-битным UUID, как и кастомная характеристика. На стороне Peripheral разработчик добавляет его к характеристике через соответствующий API. На стороне Central дескриптор обнаруживается автоматически при вызове discoverDescriptors.

При создании кастомного дескриптора соблюдайте правила: длина значения должна соответствовать ожидаемому типу данных, права доступа (read/write) должны быть явно указаны. Не используйте UUID из диапазона стандартных дескрипторов Bluetooth SIG (0x2900–0x2908) для кастомных целей.

Отличие Descriptor от Characteristic

Характеристика и дескриптор — это разные уровни GATT-атрибутов. Характеристика — это точка данных, а дескриптор — это её метаданные или конфигурация. Разница проявляется в нескольких аспектах: назначении, UUID и правилах доступа.

Характеристика имеет обязательное объявление (declaration), которое всегда находится в GATT-таблице. Дескриптор опционален — характеристика может не иметь дескрипторов. Характеристика может быть прочитана, записана или отправлять уведомления независимо. Дескриптор всегда привязан к характеристике и не существует отдельно.

По данным Bluetooth Core Specification 5.4, в GATT-таблице порядок атрибутов следующий: объявление сервиса, объявление характеристики, значение характеристики, дескрипторы характеристики (если есть), затем следующий сервис. Этот порядок обязателен для корректной работы GATT-клиентов.

Часто задаваемые вопросы

Зачем нужен CCCD, если у характеристики есть свойство Notify?

CCCD нужен для управления подпиской: свойство Notify только говорит, что характеристика может отправлять уведомления, но не включает их. Central должен явно подписаться, записав 0x0001 в CCCD. Это предотвращает нежелательную отправку данных на неподготовленный Central.

Сколько дескрипторов может быть у одной характеристики?

Спецификация не ограничивает количество дескрипторов. На практике каждая характеристика обычно имеет 1–3 дескриптора: CCCD (для характеристик с Notify/Indicate), опционально User Description и Presentation Format. Слишком много дескрипторов увеличивает размер GATT-таблицы.

Нужно ли создавать дескрипторы вручную на Peripheral?

В большинстве случаев не нужно. Core Bluetooth на iOS и Android автоматически добавляют CCCD к характеристикам, у которых есть свойства Notify или Indicate. Кастомные дескрипторы создаются вручную только для специфических метаданных.

Можно ли записать кастомные данные в CCCD?

Нет, CCCD имеет строго определённый формат (uint16) и назначение — управление уведомлениями. Запись других значений нарушает спецификацию Bluetooth и может привести к неработоспособности подписки. Для кастомных данных используйте кастомные дескрипторы с 128-битным UUID.

Чем Characteristic User Description полезен для приложения?

User Description содержит человекочитаемое имя характеристики — например, "Температура корпуса" вместо UUID 0x2A6E. Приложение может отображать это имя в интерфейсе, делая взаимодействие с BLE-устройством понятным для пользователя без жёстко закодированных строк.

Итоги

  • Descriptor — вспомогательный GATT-атрибут, прикреплённый к характеристике для хранения метаданных или конфигурации.
  • CCCD (0x2902) — ключевой дескриптор, управляющий подпиской Central на уведомления и подтверждённые уведомления характеристики.
  • Bluetooth SIG специфицировал 8 стандартных дескрипторов (0x2900–0x2908) для типовых задач — описания, форматирования и конфигурации.
  • В iOS CCCD управляется автоматически, в Android требуется ручная запись значения 0x0001 для включения уведомлений.
  • Кастомные дескрипторы создаются с 128-битным UUID для уникальных метаданных, не покрытых стандартными дескрипторами.
  • Дескрипторы не существуют самостоятельно — они всегда привязаны к характеристике и следуют за ней в GATT-таблице.
  • Правильное использование дескрипторов обеспечивает корректную конфигурацию BLE-соединения и понятность данных для приложения.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также