Deskryptor: co to jest, Client Characteristic Configuration i przykłady

Autor: IT Sectr Opublikowano: 2026-07-15 Czas czytania: 8 min

Deskryptor — to pomocniczy atrybut cechy BLE, który dostarcza metadane lub konfigurację dla jej wartości. Bluetooth Core Specification 5.4 definiuje deskryptory jako integralną część profilu GATT: opisują one jednostki miary, zakresy wartości, nazwy tekstowe i zarządzają subskrypcją powiadomień. Najbardziej znanym deskryptorem jest Client Characteristic Configuration Descriptor (CCCD, 0x2902), który umożliwia Central subskrypcję powiadomień z cechy. Według Bluetooth SIG, określono 8 standardowych deskryptorów, a niestandardowe deskryptory mogą być tworzone przez programistę dla dowolnych dodatkowych metadanych.

Najważniejsze

  • Deskryptor — pomocniczy atrybut cechy, który zawiera metadane lub konfigurację wartości.
  • CCCD (0x2902) — najważniejszy deskryptor: przez niego Central subskrybuje powiadomienia o zmianie cechy.
  • Standardowe deskryptory obejmują User Description (0x2901) dla nazwy tekstowej i Presentation Format (0x2904) dla formatu danych.
  • Każda cecha może mieć wiele deskryptorów, ale nie więcej niż jeden każdego standardowego typu.
  • Deskryptory są automatycznie tworzone przez Core Bluetooth, ale mogą być dostosowane dla specyficznych metadanych.

Czym jest deskryptor w BLE?

Deskryptor — to atrybut protokołu GATT, który dołącza się do cechy i dostarcza dodatkowych informacji o jej wartości lub sposobie użycia. W terminologii GATT cecha to dane, a deskryptor to metadane tych danych.

Każda cecha może mieć zero lub więcej deskryptorów. Deskryptory są definiowane jako oddzielne atrybuty w tabeli GATT i mają własne 16-bitowe UUID w przestrzeni Bluetooth SIG. Deskryptory nie mogą istnieć samodzielnie — są zawsze powiązane z konkretną cechą.

Według Bluetooth Core Specification 5.4 (2023), deskryptory dzielą się na dwie kategorie: standardowe (określone przez Bluetooth SIG) i niestandardowe (definiowane przez programistę). Standardowe deskryptory mają UUID w zakresie 0x2900–0x2908 i pełnią ściśle określone funkcje. Niestandardowe deskryptory używają 128-bitowych UUID, podobnie jak niestandardowe usługi i cechy.

Deskryptory to kluczowy mechanizm konfiguracji zachowania połączenia BLE. Bez CCCD (0x2902) nie można subskrybować powiadomień, bez Presentation Format (0x2904) Central nie dowie się, jak interpretować surowe bajty cechy.

Client Characteristic Configuration Descriptor (CCCD)

CCCD z UUID 0x2902 to najważniejszy i najszerzej używany deskryptor w BLE. Zarządza on subskrypcją Central na powiadomienia (Notify) i potwierdzone powiadomienia (Indicate) z cechy. Bez zapisu w CCCD cecha nie będzie wysyłać powiadomień, nawet jeśli ma właściwość Notify.

CCCD to 16-bitowa wartość, w której najmłodszy bit (0x0001) włącza Notify, a drugi bit (0x0002) włącza Indicate. Central zapisuje odpowiednią wartość w CCCD, subskrybując w ten sposób powiadomienia. Jeśli Central zapisze 0x0000 — subskrypcja jest anulowana.

Mechanizm działania CCCD wygląda następująco: gdy Central wykryje cechę z obsługą Notify, znajduje jej deskryptor CCCD i zapisuje 0x0001. Następnie, za każdym razem gdy Peripheral aktualizuje wartość cechy, jest ona automatycznie wysyłana do zasubskrybowanego Central przez Handle Value Notification (bez zapytania od Central).

Według Apple Core Bluetooth Programming Guide, CCCD jest automatycznie zarządzany przez system przy wywołaniu setNotifyValue dla cechy. Programista nie musi ręcznie szukać i zapisywać CCCD — Core Bluetooth robi to automatycznie przy aktywacji powiadomień.

Programowa subskrypcja powiadomień

W iOS subskrypcja odbywa się przez metodę setNotifyValue na obiekcie CBPeripheral.

swift
import CoreBluetooth

// Subskrybuj powiadomienia cechy
peripheral.setNotifyValue(true, for: characteristic)

// Delegate otrzymuje zaktualizowane wartości
func peripheral(
    _ peripheral: CBPeripheral,
    didUpdateValueFor characteristic: CBCharacteristic,
    error: Error?
) {
    // characteristic.value ma nowe dane
    guard let data = characteristic.value else { return }
}

Na Android subskrypcja powiadomień odbywa się przez BluetoothGatt.setCharacteristicNotification. Programista musi ręcznie zapisać wartość 0x0001 w CCCD.

java
import android.bluetooth.*;

// Włącz powiadomienia
bluetoothGatt.setCharacteristicNotification(characteristic, true);

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

Standardowe deskryptory Bluetooth SIG

Bluetooth SIG określił 8 standardowych deskryptorów dla typowych zadań konfiguracji cech. Każdy deskryptor ma ściśle określony UUID i format wartości.

UUIDNazwa deskryptoraPrzeznaczenieTyp wartości
0x2900Characteristic Extended PropertiesDodatkowe właściwości cechyuint16 (maska bitowa)
0x2901Characteristic User DescriptionTekstowa nazwa cechyUTF-8 string
0x2902Client Characteristic ConfigurationZarządzanie powiadomieniamiuint16
0x2903Server Characteristic ConfigurationKonfiguracja serwera dla broadcastuint16
0x2904Characteristic Presentation FormatFormat prezentacji danychStruktura (7 bajtów)
0x2905Characteristic Aggregate FormatŁączenie wielu cechLista UUID
0x2906Valid RangeZakres dozwolonych wartościuint16 × 2 (min, max)
0x2907External Report ReferenceOdnośnik do zewnętrznego raportuuint16
0x2908Report ReferenceOdnośnik do wewnętrznego raportuuint8 + uint16

Characteristic User Description (0x2901) jest szczególnie przydatny dla UI: zawiera czytelną dla człowieka nazwę cechy, którą można wyświetlić w interfejsie aplikacji. Na przykład cecha Battery Level może mieć deskryptor User Description z wartością „Poziom naładowania baterii”.

Characteristic Presentation Format (0x2904) zawiera informacje o tym, jak interpretować wartość cechy: format (uint8, uint16, float), eksponenta, jednostka miary (przez UUID z rejestru Bluetooth SIG), przestrzeń nazw i opis. Na przykład temperatura może być int16 z eksponentą -2 (wartość podziałki 0.01°C) i jednostką miary „stopnie Celsjusza”.

Jak używać deskryptora w iOS i Android

Dostęp do deskryptorów różni się na iOS i Android. Core Bluetooth automatycznie zarządza CCCD przy włączaniu powiadomień, a Android wymaga ręcznego zapisu wartości w deskryptorze. Rozważmy oba podejścia.

iOS: automatyczne zarządzanie CCCD

W iOS programista zwykle nie wchodzi w interakcję z deskryptorami bezpośrednio. Core Bluetooth automatycznie znajduje CCCD i zapisuje w nim odpowiednią wartość przy wywołaniu setNotifyValue. Do odczytu deskryptorów używa się metody discoverDescriptors.

swift
// Odkryj deskryptory
peripheral.discoverDescriptors(for: characteristic)

// Odczytaj wartość 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: ręczne zarządzanie CCCD

Na Android programista musi sam znaleźć deskryptor CCCD cechy i zapisać w nim wartość, aby włączyć powiadomienia. To dodatkowy krok w porównaniu do iOS.

java
// Odczytaj wartość deskryptora User Description
BluetoothGattDescriptor userDesc = characteristic
    .getDescriptor(
        UUID.fromString("00002901-0000-1000-8000-00805F9B34FB")
    );

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

Tworzenie niestandardowych deskryptorów

Niestandardowe deskryptory są używane, gdy standardowe deskryptory Bluetooth SIG są niewystarczające. Na przykład producent czujnika medycznego może dodać deskryptor z informacją o kalibracji sensora lub deskryptor z dziennikiem błędów.

Niestandardowy deskryptor jest tworzony z 128-bitowym UUID, podobnie jak niestandardowa cecha. Po stronie Peripheral programista dodaje go do cechy przez odpowiednie API. Po stronie Central deskryptor jest wykrywany automatycznie przy wywołaniu discoverDescriptors.

Przy tworzeniu niestandardowego deskryptora przestrzegaj zasad: długość wartości musi odpowiadać oczekiwanemu typowi danych, prawa dostępu (read/write) muszą być jawnie określone. Nie używaj UUID z zakresu standardowych deskryptorów Bluetooth SIG (0x2900–0x2908) do niestandardowych celów.

Różnica między deskryptorem a cechą

Cecha i deskryptor — to różne poziomy atrybutów GATT. Cecha to punkt danych, a deskryptor to jej metadane lub konfiguracja. Różnica przejawia się w kilku aspektach: przeznaczeniu, UUID i zasadach dostępu.

Cecha ma obowiązkową deklarację (declaration), która zawsze znajduje się w tabeli GATT. Deskryptor jest opcjonalny — cecha może nie mieć deskryptorów. Cecha może być odczytana, zapisana lub wysyłać powiadomienia niezależnie. Deskryptor jest zawsze powiązany z cechą i nie istnieje osobno.

Według Bluetooth Core Specification 5.4, w tabeli GATT kolejność atrybutów jest następująca: deklaracja usługi, deklaracja cechy, wartość cechy, deskryptory cechy (jeśli są), następna usługa. Ta kolejność jest obowiązkowa dla prawidłowego działania klientów GATT.

Często zadawane pytania

Po co jest CCCD, skoro cecha ma właściwość Notify?

CCCD jest potrzebny do zarządzania subskrypcją: właściwość Notify tylko mówi, że cecha może wysyłać powiadomienia, ale ich nie włącza. Central musi jawnie zasubskrybować, zapisując 0x0001 w CCCD. Zapobiega to niepożądanemu wysyłaniu danych do nieprzygotowanego Central.

Ile deskryptorów może mieć jedna cecha?

Specyfikacja nie ogranicza liczby deskryptorów. W praktyce każda cecha zwykle ma 1–3 deskryptory: CCCD (dla cech z Notify/Indicate), opcjonalnie User Description i Presentation Format. Zbyt wiele deskryptorów zwiększa rozmiar tabeli GATT.

Czy trzeba ręcznie tworzyć deskryptory po stronie Peripheral?

W większości przypadków nie trzeba. Core Bluetooth na iOS i Android automatycznie dodaje CCCD do cech, które mają właściwości Notify lub Indicate. Niestandardowe deskryptory są tworzone ręcznie tylko dla specyficznych metadanych.

Czy można zapisać niestandardowe dane w CCCD?

Nie, CCCD ma ściśle określony format (uint16) i przeznaczenie — zarządzanie powiadomieniami. Zapis innych wartości narusza specyfikację Bluetooth i może spowodować niesprawność subskrypcji. Do niestandardowych danych używaj niestandardowych deskryptorów z 128-bitowym UUID.

Jak Characteristic User Description jest przydatny dla aplikacji?

User Description zawiera czytelną dla człowieka nazwę cechy — na przykład „Temperatura obudowy” zamiast UUID 0x2A6E. Aplikacja może wyświetlić tę nazwę w interfejsie, czyniąc interakcję z urządzeniem BLE zrozumiałą dla użytkownika bez sztywno zakodowanych ciągów znaków.

Podsumowanie

  • Deskryptor — pomocniczy atrybut GATT dołączony do cechy do przechowywania metadanych lub konfiguracji.
  • CCCD (0x2902) — kluczowy deskryptor zarządzający subskrypcją Central na powiadomienia i potwierdzone powiadomienia cechy.
  • Bluetooth SIG określił 8 standardowych deskryptorów (0x2900–0x2908) dla typowych zadań — opisu, formatowania i konfiguracji.
  • W iOS CCCD jest zarządzany automatycznie, w Android wymagany jest ręczny zapis wartości 0x0001 w celu włączenia powiadomień.
  • Niestandardowe deskryptory są tworzone z 128-bitowym UUID dla unikalnych metadanych nieobjętych standardowymi deskryptorami.
  • Deskryptory nie istnieją samodzielnie — są zawsze powiązane z cechą i podążają za nią w tabeli GATT.
  • Prawidłowe używanie deskryptorów zapewnia poprawną konfigurację połączenia BLE i zrozumiałość danych dla aplikacji.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również