Deskriptor — je pomocný atribut BLE charakteristiky, který poskytuje metadata nebo konfiguraci pro její hodnotu. Bluetooth Core Specification 5.4 definuje deskriptory jako nedílnou součást profilu GATT: popisují jednotky měření, rozsahy hodnot, textová jména a řídí odběr odebírání oznámení. Nejznámějším deskriptorem je Client Characteristic Configuration Descriptor (CCCD, 0x2902), který umožňuje Centralu přihlásit se k odběru oznámení z charakteristiky. Podle Bluetooth SIG je specifikováno 8 standardních deskriptorů a vlastní deskriptory může vytvořit vývojář pro jakákoli další metadata.
Hlavní body
Deskriptor — je atribut protokolu GATT, který se připojuje k charakteristice a poskytuje další informace o její hodnotě nebo způsobu použití. V terminologii GATT je charakteristika data a deskriptor jsou metadata těchto dat.
Každá charakteristika může mít nula nebo více deskriptorů. Deskriptory jsou definovány jako samostatné atributy v tabulce GATT a mají vlastní 16bitové UUID v prostoru Bluetooth SIG. Deskriptory nemohou existovat samostatně — jsou vždy vázány na konkrétní charakteristiku.
Podle Bluetooth Core Specification 5.4 (2023) se deskriptory dělí do dvou kategorií: standardní (definované Bluetooth SIG) a vlastní (definované vývojářem). Standardní deskriptory mají UUID v rozsahu 0x2900–0x2908 a plní přesně definované funkce. Vlastní deskriptory používají 128bitová UUID, podobně jako vlastní služby a charakteristiky.
Deskriptory jsou klíčovým mechanismem pro konfiguraci chování spojení BLE. Bez CCCD (0x2902) se nelze přihlásit k odběru oznámení, bez Presentation Format (0x2904) Central nebude vědět, jak interpretovat surové bajty charakteristiky.
CCCD s UUID 0x2902 je nejdůležitější a nejpoužívanější deskriptor v BLE. Řídí odběr Centralu k oznámením (Notify) a potvrzeným oznámením (Indicate) z charakteristiky. Bez zápisu do CCCD nebude charakteristika odesílat oznámení, ani když má vlastnost Notify.
CCCD je 16bitová hodnota, ve které nejnižší bit (0x0001) zapíná Notify a druhý bit (0x0002) zapíná Indicate. Central zapisuje požadovanou hodnotu do CCCD, čímž se přihlašuje k odběru oznámení. Pokud Central zapíše 0x0000 — odběr se ruší.
Mechanismus fungování CCCD je následující: když Central objeví charakteristiku s podporou Notify, najde její CCCD deskriptor a zapíše 0x0001. Poté, pokaždé když Peripheral aktualizuje hodnotu charakteristiky, je automaticky odeslána přihlášenému Centralu prostřednictvím Handle Value Notification (bez požadavku od Centralu).
Podle Apple Core Bluetooth Programming Guide je CCCD automaticky spravován systémem při volání setNotifyValue pro charakteristiku. Vývojář nemusí ručně hledat a zapisovat CCCD — Core Bluetooth to dělá automaticky při aktivaci oznámení.
V iOS se přihlášení prováDí pomocí metody setNotifyValue na objektu CBPeripheral.
import CoreBluetooth
// Přihlásit se k oznámením charakteristiky
peripheral.setNotifyValue(true, for: characteristic)
// Delegate obdrží aktualizované hodnoty
func peripheral(
_ peripheral: CBPeripheral,
didUpdateValueFor characteristic: CBCharacteristic,
error: Error?
) {
// characteristic.value má nová data
guard let data = characteristic.value else { return }
}
Na Androidu se přihlášení k odběru oznámení prováDí pomocí BluetoothGatt.setCharacteristicNotification. Vývojář také musí ručně zapsat hodnotu 0x0001 do CCCD.
import android.bluetooth.*;
// Povolit oznámení
bluetoothGatt.setCharacteristicNotification(characteristic, true);
// Zapsat 0x0001 do CCCD
BluetoothGattDescriptor descriptor = characteristic
.getDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);
Bluetooth SIG definoval 8 standardních deskriptorů pro běžné úkoly konfigurace charakteristik. Každý deskriptor má přesně definované UUID a formát hodnoty.
| UUID | Název deskriptoru | Účel | Typ hodnoty |
|---|---|---|---|
| 0x2900 | Characteristic Extended Properties | Další vlastnosti charakteristiky | uint16 (bitová maska) |
| 0x2901 | Characteristic User Description | Textové jméno charakteristiky | Řetězec UTF-8 |
| 0x2902 | Client Characteristic Configuration | Správa oznámení | uint16 |
| 0x2903 | Server Characteristic Configuration | Konfigurace serveru pro broadcast | uint16 |
| 0x2904 | Characteristic Presentation Format | Formát prezentace dat | Struktura (7 bajtů) |
| 0x2905 | Characteristic Aggregate Format | Slučování více charakteristik | Seznam UUID |
| 0x2906 | Valid Range | Rozsah povolených hodnot | uint16 × 2 (min, max) |
| 0x2907 | External Report Reference | Odkaz na externí zprávu | uint16 |
| 0x2908 | Report Reference | Odkaz na interní zprávu | uint8 + uint16 |
Characteristic User Description (0x2901) je zvláště užitečný pro UI: obsahuje lidsky čitelné jméno charakteristiky, které lze zobrazit v rozhraní aplikace. Například charakteristika Battery Level může mít deskriptor User Description s hodnotou „Úroveň nabití baterie“.
Characteristic Presentation Format (0x2904) obsahuje informace o tom, jak interpretovat hodnotu charakteristiky: formát (uint8, uint16, float), exponent, jednotku měření (prostřednictvím UUID z registru Bluetooth SIG), jmenný prostor a popis. Například teplota může být int16 s exponentem -2 (hodnota dělení 0.01°C) a jednotkou měření „stupně Celsia“.
Přístup k deskriptorům se liší na iOS a Androidu. Core Bluetooth automaticky spravuje CCCD při zapnutí oznámení, zatímco Android vyžaduje ruční zápis hodnoty do deskriptoru. Podívejme se na oba přístupy.
V iOS vývojář obvykle nepřichází do přímého kontaktu s deskriptory. Core Bluetooth automaticky najde CCCD a zapíše potřebnou hodnotu při volání setNotifyValue. Pro čtení deskriptorů se používá metoda discoverDescriptors.
// Objevit deskriptory
peripheral.discoverDescriptors(for: characteristic)
// Přečíst hodnotu 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)
}
}
}
Na Androidu musí vývojář sám najít CCCD deskriptor charakteristiky a zapsat hodnotu pro zapnutí oznámení. To je další krok ve srovnání s iOS.
// Přečíst hodnotu deskriptoru User Description
BluetoothGattDescriptor userDesc = characteristic
.getDescriptor(
UUID.fromString("00002901-0000-1000-8000-00805F9B34FB")
);
if (userDesc != null) {
bluetoothGatt.readDescriptor(userDesc);
}
Vlastní deskriptory se používají, když standardní deskriptory Bluetooth SIG nestačí. Například výrobce lékařského senzoru může přidat deskriptor s informacemi o kalibraci senzoru nebo deskriptor s protokolem chyb.
Vlastní deskriptor se vytváří s 128bitovým UUID, stejně jako vlastní charakteristika. Na straně Peripheral jej vývojář přidá k charakteristice prostřednictvím příslušného API. Na straně Central je deskriptor automaticky objeven při volání discoverDescriptors.
Při vytváření vlastního deskriptoru dodržujte pravidla: délka hodnoty musí odpovídat očekávanému typu dat, přístupová práva (read/write) musí být výslovně uvedena. Nepoužívejte UUID z rozsahu standardních deskriptorů Bluetooth SIG (0x2900–0x2908) pro vlastní účely.
Charakteristika a deskriptor — to jsou různé úRovně atributů GATT. Charakteristika je datový bod a deskriptor jsou její metadata nebo konfigurace. Rozdíl se projevuje v několika aspektech: účelu, UUID a přístupových právech.
Charakteristika má povinné prohlášení (declaration), které je vždy v tabulce GATT. Deskriptor je volitelný — charakteristika nemusí mít deskriptory. Charakteristika může být čtena, zapisována nebo odesílat oznámení nezávisle. Deskriptor je vždy vázán na charakteristiku a neexistuje samostatně.
Podle Bluetooth Core Specification 5.4 je v tabulce GATT pořadí atributů následující: prohlášení služby, prohlášení charakteristiky, hodnota charakteristiky, deskriptory charakteristiky (pokud existují), poté další služba. Toto pořadí je povinné pro správnou funkci klientů GATT.
Časté dotazy
CCCD je potřeba pro správu odběru: vlastnost Notify pouze říká, že charakteristika může odesílat oznámení, ale nezapíná je. Central se musí výslovně přihlásit zápisem 0x0001 do CCCD. To brání nežádoucímu odesílání dat nepřipravenému Centralu.
Specifikace neomezuje počet deskriptorů. V praxi má každá charakteristika obvykle 1–3 deskriptory: CCCD (pro charakteristiky s Notify/Indicate), volitelně User Description a Presentation Format. Příliš mnoho deskriptorů zvětšuje velikost tabulky GATT.
Ve většině případů ne. Core Bluetooth na iOS a Androidu automaticky přidává CCCD k charakteristikám, které mají vlastnosti Notify nebo Indicate. Vlastní deskriptory se vytvářejí ručně pouze pro specifická metadata.
Ne, CCCD má přesně definovaný formát (uint16) a účel — správu oznámení. Zápis jiných hodnot porušuje specifikaci Bluetooth a může způsobit nefunkčnost odběru. Pro vlastní data použijte vlastní deskriptory s 128bitovým UUID.
User Description obsahuje lidsky čitelné jméno charakteristiky — například „Teplota skříně“ místo UUID 0x2A6E. Aplikace může toto jméno zobrazit v rozhraní, díky čemuž je interakce se zařízením BLE srozumitelná pro uživatele bez pevně zakódovaných řetězců.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také