Descriptor — är ett hjälpattribut för BLE-karakteristiken som tillhandahåller metadata eller konfiguration för dess värde. Bluetooth Core Specification 5.4 definierar deskriptorer som en integrerad del av GATT-profilen: de beskriver mättenheter, värdeintervall, textnamn och hanterar prenumeration på notifikationer. Den mest kända deskriptorn är Client Characteristic Configuration Descriptor (CCCD, 0x2902), som gör det möjligt för Central att prenumerera på notifikationer från karakteristiken. Enligt Bluetooth SIG är 8 standarddeskriptorer specificerade, och anpassade deskriptorer kan skapas av utvecklaren för eventuella extra metadata.
Huvudpunkter
Descriptor — är ett attribut i GATT-protokollet som kopplas till en karakteristik och ger ytterligare information om dess värde eller användningssätt. I GATT-terminologi är karakteristiken data och deskriptorn är metadata för dessa data.
Varje karakteristik kan ha noll eller fler deskriptorer. Deskriptorer definieras som separata attribut i GATT-tabellen och har egna 16-bitars UUID i Bluetooth SIG-rymden. Deskriptorer kan inte existera självständigt — de är alltid bundna till en specifik karakteristik.
Enligt Bluetooth Core Specification 5.4 (2023) delas deskriptorer in i två kategorier: standard (definierade av Bluetooth SIG) och anpassade (definierade av utvecklaren). Standarddeskriptorer har UUID i intervallet 0x2900–0x2908 och utför strikt definierade funktioner. Anpassade deskriptorer använder 128-bitars UUID, likt anpassade tjänster och karakteristiker.
Deskriptorer är den viktigaste mekanismen för beteendekonfiguration av BLE-anslutningen. Utan CCCD (0x2902) kan man inte prenumerera på notifikationer, utan Presentation Format (0x2904) vet Central inte hur den ska tolka karakteristikens råa byte.
CCCD med UUID 0x2902 är den viktigaste och mest använda deskriptorn i BLE. Den hanterar Centralens prenumeration på notifikationer (Notify) och bekräftade notifikationer (Indicate) från karakteristiken. Utan skrivning till CCCD kommer karakteristiken inte att skicka notifikationer, även om den har egenskapen Notify.
CCCD är ett 16-bitars värde där den minst signifikanta biten (0x0001) aktiverar Notify och den andra biten (0x0002) aktiverar Indicate. Central skriver önskat värde till CCCD och prenumererar därmed på notifikationer. Om Central skriver 0x0000 — avbryts prenumerationen.
Mekanismen för CCCD är följande: när Central upptäcker en karakteristik med Notify-stöd, hittar den dess CCCD-deskriptor och skriver 0x0001. Därefter, varje gång Peripheral uppdaterar karakteristikens värde, skickas det automatiskt till den prenumererande Central via Handle Value Notification (utan förfrågan från Central).
Enligt Apple Core Bluetooth Programming Guide hanteras CCCD automatiskt av systemet vid anrop av setNotifyValue för karakteristiken. Utvecklaren behöver inte manuellt söka efter och skriva CCCD — Core Bluetooth gör detta automatiskt vid aktivering av notifikationer.
I iOS utförs prenumeration via metoden setNotifyValue på CBPeripheral-objektet.
import CoreBluetooth
// Prenumerera på karakteristiknotifikationer
peripheral.setNotifyValue(true, for: characteristic)
// Delegate tar emot uppdaterade värden
func peripheral(
_ peripheral: CBPeripheral,
didUpdateValueFor characteristic: CBCharacteristic,
error: Error?
) {
// characteristic.value har ny data
guard let data = characteristic.value else { return }
}
På Android utförs prenumeration på notifikationer via BluetoothGatt.setCharacteristicNotification. Utvecklaren måste även manuellt skriva värdet 0x0001 till CCCD.
import android.bluetooth.*;
// Aktivera notifikationer
bluetoothGatt.setCharacteristicNotification(characteristic, true);
// Skriv 0x0001 till CCCD
BluetoothGattDescriptor descriptor = characteristic
.getDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);
Bluetooth SIG har definierat 8 standarddeskriptorer för vanliga konfigurationsuppgifter för karakteristiker. Varje deskriptor har en strikt definierad UUID och värdesformat.
| UUID | Deskriptornamn | Syfte | Värdetyp |
|---|---|---|---|
| 0x2900 | Characteristic Extended Properties | Ytterligare egenskaper för karakteristiken | uint16 (bitmask) |
| 0x2901 | Characteristic User Description | Textnamn på karakteristiken | UTF-8-sträng |
| 0x2902 | Client Characteristic Configuration | Hantera notifikationer | uint16 |
| 0x2903 | Server Characteristic Configuration | Serverkonfiguration för broadcast | uint16 |
| 0x2904 | Characteristic Presentation Format | Datapresentationsformat | Struktur (7 byte) |
| 0x2905 | Characteristic Aggregate Format | Sammanfoga flera karakteristiker | Lista över UUID |
| 0x2906 | Valid Range | Intervall för tillåtna värden | uint16 × 2 (min, max) |
| 0x2907 | External Report Reference | Referens till extern rapport | uint16 |
| 0x2908 | Report Reference | Referens till intern rapport | uint8 + uint16 |
Characteristic User Description (0x2901) är särskilt användbart för UI: det innehåller ett mänskligt läsbart namn på karakteristiken som kan visas i applikationsgränssnittet. Till exempel kan karakteristiken Battery Level ha en User Description-deskriptor med värdet „Batteriladdningsnivå”.
Characteristic Presentation Format (0x2904) innehåller information om hur man tolkar karakteristikens värde: format (uint8, uint16, float), exponent, mättenhet (via UUID från Bluetooth SIG-registret), namnrymd och beskrivning. Till exempel kan temperaturen vara int16 med exponent -2 (delvärde 0.01°C) och mättenheten „grader Celsius”.
Åtkomst till deskriptorer skiljer sig mellan iOS och Android. Core Bluetooth hanterar CCCD automatiskt när notifikationer aktiveras, medan Android kräver manuell skrivning av värdet till deskriptorn. Låt oss titta på båda metoderna.
I iOS interagerar utvecklaren vanligtvis inte direkt med deskriptorer. Core Bluetooth hittar automatiskt CCCD och skriver det nödvändiga värdet vid anrop av setNotifyValue. För att läsa deskriptorer används metoden discoverDescriptors.
// Upptäck deskriptorer
peripheral.discoverDescriptors(for: characteristic)
// Läs User Description-värde
func peripheral(
_ peripheral: CBPeripheral,
didDiscoverDescriptorsFor characteristic: CBCharacteristic,
error: Error?
) {
for descriptor in characteristic.descriptors ?? [] {
if descriptor.uuid == CBUUID("2901") {
peripheral.readValue(for: descriptor)
}
}
}
På Android måste utvecklaren själv hitta karakteristikens CCCD-deskriptor och skriva värdet för att aktivera notifikationer. Detta är ett extra steg jämfört med iOS.
// Läs värdet för User Description-deskriptorn
BluetoothGattDescriptor userDesc = characteristic
.getDescriptor(
UUID.fromString("00002901-0000-1000-8000-00805F9B34FB")
);
if (userDesc != null) {
bluetoothGatt.readDescriptor(userDesc);
}
Anpassade deskriptorer används när standarddeskriptorerna för Bluetooth SIG inte räcker. Till exempel kan en tillverkare av medicinska sensorer lägga till en deskriptor med information om sensorns kalibrering eller en deskriptor med fellogg.
En anpassad deskriptor skapas med ett 128-bitars UUID, precis som en anpassad karakteristik. På Peripheral-sidan lägger utvecklaren till den till karakteristiken via lämpligt API. På Central-sidan upptäcks deskriptorn automatiskt vid anrop av discoverDescriptors.
När du skapar en anpassad deskriptor, följ reglerna: längden på värdet måste motsvara den förväntade datatypen, åtkomsträttigheter (read/write) måste anges explicit. Använd inte UUID från intervallet för standarddeskriptorer för Bluetooth SIG (0x2900–0x2908) för anpassade ändamål.
Karakteristik och descriptor — är olika nivåer av GATT-attribut. Karakteristiken är en datapunkt och deskriptorn är dess metadata eller konfiguration. Skillnaden visar sig i flera aspekter: syfte, UUID och åtkomsträttigheter.
Karakteristiken har en obligatorisk deklaration (declaration) som alltid finns i GATT-tabellen. Deskriptorn är valfri — karakteristiken kan sakna deskriptorer. Karakteristiken kan läsas, skrivas eller skicka notifikationer oberoende. Deskriptorn är alltid bunden till karakteristiken och existerar inte separat.
Enligt Bluetooth Core Specification 5.4 är ordningen på attribut i GATT-tabellen följande: tjänstedeklaration, karakteristikdeklaration, karakteristikvärde, karakteristikdeskriptorer (om sådana finns), sedan nästa tjänst. Denna ordning är obligatorisk för korrekt funktion av GATT-klienter.
Vanliga frågor
CCCD behövs för att hantera prenumerationen: egenskapen Notify säger bara att karakteristiken kan skicka notifikationer, men aktiverar dem inte. Central måste explicit prenumerera genom att skriva 0x0001 till CCCD. Detta förhindrar oönskad dataöverföring till en oförberedd Central.
Specifikationen begränsar inte antalet deskriptorer. I praktiken har varje karakteristik vanligtvis 1–3 deskriptorer: CCCD (för karakteristiker med Notify/Indicate), eventuellt User Description och Presentation Format. För många deskriptorer ökar storleken på GATT-tabellen.
I de flesta fall nej. Core Bluetooth på iOS och Android lägger automatiskt till CCCD till karakteristiker som har egenskaperna Notify eller Indicate. Anpassade deskriptorer skapas manuellt endast för specifik metadata.
Nej, CCCD har ett strikt definierat format (uint16) och syfte — hantering av notifikationer. Att skriva andra värden bryter mot Bluetooth-specifikationen och kan leda till att prenumerationen inte fungerar. För anpassad data, använd anpassade deskriptorer med 128-bitars UUID.
User Description innehåller ett mänskligt läsbart namn på karakteristiken — till exempel „Chassitemperatur” istället för UUID 0x2A6E. Applikationen kan visa detta namn i gränssnittet, vilket gör interaktionen med BLE-enheten begriplig för användaren utan hårdkodade strängar.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också