Descriptorul este un atribut auxiliar al caracteristicii BLE care furnizează metadate sau configurație pentru valoarea sa. Bluetooth Core Specification 5.4 definește descriptorii ca parte integrantă a profilului GATT: aceștia descriu unități de măsură, domenii de valori, nume text și gestionează abonarea la notificări. Cel mai cunoscut descriptor este Client Characteristic Configuration Descriptor (CCCD, 0x2902), care permite Central să se aboneze la notificări de la caracteristică. Potrivit Bluetooth SIG, sunt specificați 8 descriptori standard, iar descriptorii personalizați pot fi creați de dezvoltator pentru orice metadate suplimentare.
Puncte cheie
Descriptorul este un atribut al protocolului GATT care se atașează la caracteristică și oferă informații suplimentare despre valoarea sau modul de utilizare al acesteia. În terminologia GATT, caracteristica este datele, iar descriptorul este metadatele acestor date.
Fiecare caracteristică poate avea zero sau mai mulți descriptori. Descriptorii sunt definiți ca atribute separate în tabela GATT și au propriile UUID-uri de 16 biți în spațiul Bluetooth SIG. Descriptorii nu pot exista independent — sunt întotdeauna legați de o caracteristică specifică.
Conform Bluetooth Core Specification 5.4 (2023), descriptorii se împart în două categorii: standard (definiți de Bluetooth SIG) și personalizați (definiți de dezvoltator). Descriptorii standard au UUID-uri în intervalul 0x2900–0x2908 și îndeplinesc funcții strict definite. Descriptorii personalizați folosesc UUID-uri de 128 de biți, similar serviciilor și caracteristicilor personalizate.
Descriptorii sunt mecanismul cheie pentru configurarea comportamentului conexiunii BLE. Fără CCCD (0x2902) nu se poate abona la notificări, fără Presentation Format (0x2904) Central nu știe cum să interpreteze octeții bruti ai caracteristicii.
CCCD cu UUID 0x2902 este cel mai important și mai utilizat descriptor în BLE. Acesta gestionează abonarea Central la notificări (Notify) și notificări confirmate (Indicate) de la caracteristică. Fără scrierea în CCCD, caracteristica nu va trimite notificări, chiar dacă are proprietatea Notify.
CCCD este o valoare de 16 biți în care bitul cel mai puțin semnificativ (0x0001) activează Notify, iar al doilea bit (0x0002) activează Indicate. Central scrie valoarea dorită în CCCD, abonându-se astfel la notificări. Dacă Central scrie 0x0000 — abonamentul este anulat.
Mecanismul de funcționare al CCCD este următorul: când Central detectează o caracteristică cu suport Notify, găsește descriptorul CCCD al acesteia și scrie 0x0001. După aceea, de fiecare dată când Peripheral actualizează valoarea caracteristicii, aceasta este trimisă automat Centralului abonat prin Handle Value Notification (fără cerere din partea Central).
Conform Apple Core Bluetooth Programming Guide, CCCD este gestionat automat de sistem la apelarea setNotifyValue pentru caracteristică. Dezvoltatorul nu trebuie să caute și să scrie manual CCCD — Core Bluetooth face acest lucru automat la activarea notificărilor.
În iOS, abonarea se realizează prin metoda setNotifyValue pe obiectul CBPeripheral.
import CoreBluetooth
// Abonează-te la notificările caracteristicii
peripheral.setNotifyValue(true, for: characteristic)
// Delegate primește valori actualizate
func peripheral(
_ peripheral: CBPeripheral,
didUpdateValueFor characteristic: CBCharacteristic,
error: Error?
) {
// characteristic.value are date noi
guard let data = characteristic.value else { return }
}
Pe Android, abonarea la notificări se realizează prin BluetoothGatt.setCharacteristicNotification. Dezvoltatorul trebuie să scrie manual valoarea 0x0001 în CCCD.
import android.bluetooth.*;
// Activează notificările
bluetoothGatt.setCharacteristicNotification(characteristic, true);
// Scrie 0x0001 în CCCD
BluetoothGattDescriptor descriptor = characteristic
.getDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);
Bluetooth SIG a definit 8 descriptori standard pentru sarcini comune de configurare a caracteristicilor. Fiecare descriptor are un UUID și un format de valoare strict definite.
| UUID | Numele descriptorului | Scop | Tipul valorii |
|---|---|---|---|
| 0x2900 | Characteristic Extended Properties | Proprietăți suplimentare ale caracteristicii | uint16 (mască de biți) |
| 0x2901 | Characteristic User Description | Numele text al caracteristicii | Șir UTF-8 |
| 0x2902 | Client Characteristic Configuration | Gestionarea notificărilor | uint16 |
| 0x2903 | Server Characteristic Configuration | Configurarea serverului pentru broadcast | uint16 |
| 0x2904 | Characteristic Presentation Format | Formatul de prezentare a datelor | Structură (7 octeți) |
| 0x2905 | Characteristic Aggregate Format | Combinarea mai multor caracteristici | Listă de UUID-uri |
| 0x2906 | Valid Range | Domeniul valorilor valide | uint16 × 2 (min, max) |
| 0x2907 | External Report Reference | Referință la raport extern | uint16 |
| 0x2908 | Report Reference | Referință la raport intern | uint8 + uint16 |
Characteristic User Description (0x2901) este util în special pentru UI: conține numele lizibil al caracteristicii care poate fi afișat în interfața aplicației. De exemplu, caracteristica Battery Level poate avea un descriptor User Description cu valoarea „Nivel de încărcare a bateriei”.
Characteristic Presentation Format (0x2904) conține informații despre cum să se interpreteze valoarea caracteristicii: format (uint8, uint16, float), exponent, unitate de măsură (prin UUID din registrul Bluetooth SIG), spațiu de nume și descriere. De exemplu, temperatura poate fi int16 cu exponent -2 (valoarea diviziunii 0.01°C) și unitatea de măsură „grade Celsius”.
Accesul la descriptori diferă între iOS și Android. Core Bluetooth gestionează automat CCCD la activarea notificărilor, iar Android necesită scrierea manuală a valorii în descriptor. Să analizăm ambele abordări.
În iOS, dezvoltatorul de obicei nu interacționează direct cu descriptorii. Core Bluetooth găsește automat CCCD și scrie valoarea necesară la apelarea setNotifyValue. Pentru citirea descriptorilor se folosește metoda discoverDescriptors.
// Descoperă descriptorii
peripheral.discoverDescriptors(for: characteristic)
// Citește valoarea 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)
}
}
}
Pe Android, dezvoltatorul trebuie să găsească singur descriptorul CCCD al caracteristicii și să scrie valoarea pentru activarea notificărilor. Acesta este un pas suplimentar față de iOS.
// Citește valoarea descriptorului User Description
BluetoothGattDescriptor userDesc = characteristic
.getDescriptor(
UUID.fromString("00002901-0000-1000-8000-00805F9B34FB")
);
if (userDesc != null) {
bluetoothGatt.readDescriptor(userDesc);
}
Descriptorii personalizați sunt folosiți când descriptorii standard Bluetooth SIG nu sunt suficienți. De exemplu, un producător de senzori medicali poate adăuga un descriptor cu informații despre calibrarea senzorului sau un descriptor cu jurnalul de erori.
Un descriptor personalizat este creat cu un UUID de 128 de biți, similar unei caracteristici personalizate. De partea Peripheral, dezvoltatorul îl adaugă la caracteristică prin API-ul corespunzător. De partea Central, descriptorul este detectat automat la apelarea discoverDescriptors.
La crearea unui descriptor personalizat, respectați regulile: lungimea valorii trebuie să corespundă tipului de date așteptat, drepturile de acces (read/write) trebuie specificate explicit. Nu folosiți UUID-uri din intervalul descriptorilor standard Bluetooth SIG (0x2900–0x2908) în scopuri personalizate.
Caracteristica și descriptorul sunt niveluri diferite ale atributelor GATT. Caracteristica este un punct de date, iar descriptorul este metadatele sau configurația acestuia. Diferența se manifestă în mai multe aspecte: scop, UUID și reguli de acces.
Caracteristica are o declarație obligatorie (declaration) care se află întotdeauna în tabela GATT. Descriptorul este opțional — caracteristica poate să nu aibă descriptori. Caracteristica poate fi citită, scrisă sau poate trimite notificări independent. Descriptorul este întotdeauna legat de caracteristică și nu există separat.
Conform Bluetooth Core Specification 5.4, în tabela GATT ordinea atributelor este următoarea: declarația serviciului, declarația caracteristicii, valoarea caracteristicii, descriptorii caracteristicii (dacă există), apoi următorul serviciu. Această ordine este obligatorie pentru funcționarea corectă a clienților GATT.
Întrebări frecvente
CCCD este necesar pentru gestionarea abonamentului: proprietatea Notify spune doar că caracteristica poate trimite notificări, dar nu le activează. Central trebuie să se aboneze explicit, scriind 0x0001 în CCCD. Aceasta previne trimiterea nedorită de date către un Central nepregătit.
Specificația nu limitează numărul de descriptori. în practică, fiecare caracteristică are de obicei 1–3 descriptori: CCCD (pentru caracteristici cu Notify/Indicate), opțional User Description și Presentation Format. Prea mulți descriptori măresc dimensiunea tabelei GATT.
în majoritatea cazurilor nu. Core Bluetooth pe iOS și Android adaugă automat CCCD la caracteristicile care au proprietățile Notify sau Indicate. Descriptorii personalizați sunt creați manual doar pentru metadate specifice.
Nu, CCCD are un format strict definit (uint16) și un scop — gestionarea notificărilor. Scrierea altor valori încalcă specificația Bluetooth și poate duce la nefuncționarea abonamentului. Pentru date personalizate, folosiți descriptori personalizați cu UUID de 128 de biți.
User Description conține numele lizibil al caracteristicii — de exemplu, „Temperatură carcasă” în loc de UUID 0x2A6E. Aplicația poate afișa acest nume în interfață, făcând interacțiunea cu dispozitivul BLE inteligibilă pentru utilizator, fără șiruri codificate fix.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și