Descriptor est un attribut auxiliaire d'une caractéristique BLE qui fournit des métadonnées ou une configuration pour sa valeur. La Bluetooth Core Specification 5.4 définit les descripteurs comme une partie intégrante du profil GATT : ils décrivent les unités de mesure, les plages de valeurs, les noms textuels et gèrent l'abonnement aux notifications. Le descripteur le plus connu est le Client Characteristic Configuration Descriptor (CCCD, 0x2902), qui permet au Central de s'abonner aux notifications de la caractéristique. Selon Bluetooth SIG, 8 descripteurs standard sont spécifiés, et des descripteurs personnalisés peuvent être créés par le développeur pour toutes métadonnées supplémentaires.
Points clés
Descriptor est un attribut du protocole GATT qui se rattache à une Characteristic et fournit des informations supplémentaires sur sa valeur ou son mode d'utilisation. Dans la terminologie GATT, la caractéristique est la donnée, et le descripteur est la métadonnée de cette donnée.
Chaque Characteristic peut avoir zéro ou plusieurs descripteurs. Les descripteurs sont définis comme des attributs séparés dans la table GATT et ont leurs propres UUID 16 bits dans l'espace Bluetooth SIG. Les descripteurs ne peuvent pas exister indépendamment — ils sont toujours liés à une caractéristique spécifique.
Selon la Bluetooth Core Specification 5.4 (2023), les descripteurs sont divisés en deux catégories : standard (définis par Bluetooth SIG) et personnalisés (définis par le développeur). Les descripteurs standard ont des UUID dans la plage 0x2900–0x2908 et exécutent des fonctions strictement définies. Les descripteurs personnalisés utilisent des UUID 128 bits, similaires aux services et caractéristiques personnalisés.
Les descripteurs sont un mécanisme clé pour configurer le comportement d'une connexion BLE. Sans CCCD (0x2902), il est impossible de s'abonner aux notifications ; sans Presentation Format (0x2904), le Central ne saura pas comment interpréter les octets bruts de la caractéristique.
CCCD avec l'UUID 0x2902 est le descripteur le plus important et le plus utilisé en BLE. Il gère l'abonnement du Central aux notifications Notify et Indicate de la caractéristique. Sans écriture dans le CCCD, la caractéristique n'enverra pas de notifications, même si elle possède la propriété Notify.
CCCD est une valeur 16 bits où le bit de poids faible (0x0001) active Notify, et le second bit (0x0002) active Indicate. Le Central écrit la valeur souhaitée dans le CCCD, s'abonnant ainsi aux notifications. Si le Central écrit 0x0000 — l'abonnement est annulé.
Le mécanisme du CCCD fonctionne ainsi : lorsque le Central découvre une caractéristique prenant en charge Notify, il trouve son descripteur CCCD et écrit 0x0001. Ensuite, chaque fois que le Peripheral met à jour la valeur de la caractéristique, elle est automatiquement envoyée au Central abonné via Handle Value Notification (sans demande du Central).
Selon le Apple Core Bluetooth Programming Guide, le CCCD est géré automatiquement par le système lors de l'appel à setNotifyValue pour une caractéristique. Le développeur n'a pas besoin de chercher et d'écrire manuellement le CCCD — Core Bluetooth le fait automatiquement lors de l'activation des notifications.
Sous iOS, l'abonnement se fait via la méthode setNotifyValue sur l'objet CBPeripheral.
import CoreBluetooth
// S'abonner aux notifications de la caractéristique
peripheral.setNotifyValue(true, for: characteristic)
// Le délégué reçoit les valeurs mises à jour
func peripheral(
_ peripheral: CBPeripheral,
didUpdateValueFor characteristic: CBCharacteristic,
error: Error?
) {
// characteristic.value contient de nouvelles données
guard let data = characteristic.value else { return }
}
Sous Android, l'abonnement aux notifications se fait via BluetoothGatt.setCharacteristicNotification. Le développeur doit également écrire manuellement la valeur 0x0001 dans le CCCD.
import android.bluetooth.*;
// Activer les notifications
bluetoothGatt.setCharacteristicNotification(characteristic, true);
// Écrire 0x0001 dans CCCD
BluetoothGattDescriptor descriptor = characteristic
.getDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);
Bluetooth SIG a défini 8 descripteurs standard pour les tâches courantes de configuration des caractéristiques. Chaque descripteur a un UUID et un format de valeur strictement définis.
| UUID | Nom du descripteur | Objectif | Type de valeur |
|---|---|---|---|
| 0x2900 | Characteristic Extended Properties | Propriétés supplémentaires de la caractéristique | uint16 (masque de bits) |
| 0x2901 | Characteristic User Description | Nom textuel de la caractéristique | Chaîne UTF-8 |
| 0x2902 | Client Characteristic Configuration | Gestion des notifications | uint16 |
| 0x2903 | Server Characteristic Configuration | Configuration serveur pour broadcast | uint16 |
| 0x2904 | Characteristic Presentation Format | Format de présentation des données | Structure (7 octets) |
| 0x2905 | Characteristic Aggregate Format | Combinaison de plusieurs caractéristiques | Liste d'UUID |
| 0x2906 | Valid Range | Plage de valeurs valides | uint16 × 2 (min, max) |
| 0x2907 | External Report Reference | Référence de rapport externe | uint16 |
| 0x2908 | Report Reference | Référence de rapport interne | uint8 + uint16 |
Characteristic User Description (0x2901) est particulièrement utile pour l'interface utilisateur : il contient un nom lisible de la caractéristique qui peut être affiché dans l'interface de l'application. Par exemple, une caractéristique Battery Level peut avoir un descripteur User Description avec la valeur « Niveau de charge de la batterie ».
Characteristic Presentation Format (0x2904) contient des informations sur la façon d'interpréter la valeur de la caractéristique : format (uint8, uint16, float), exposant, unité de mesure (via UUID du registre Bluetooth SIG), espace de noms et description. Par exemple, la température peut être un int16 avec exposant -2 (valeur de division 0,01 °C) et l'unité de mesure « degré Celsius ».
L'accès aux descripteurs diffère sous iOS et Android. Core Bluetooth gère automatiquement le CCCD lorsque les notifications sont activées, tandis qu'Android nécessite une écriture manuelle de la valeur dans le descripteur. Examinons les deux approches.
Sous iOS, le développeur n'interagit généralement pas directement avec les descripteurs. Core Bluetooth trouve automatiquement le CCCD et écrit la valeur requise lors de l'appel à setNotifyValue. Pour lire les descripteurs, on utilise la méthode discoverDescriptors.
// Découvrir les descripteurs
peripheral.discoverDescriptors(for: characteristic)
// Lire la valeur de 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)
}
}
}
Sous Android, le développeur doit trouver le descripteur CCCD de la caractéristique et écrire la valeur pour activer les notifications. Il s'agit d'une étape supplémentaire par rapport à iOS.
// Lire la valeur du descripteur User Description
BluetoothGattDescriptor userDesc = characteristic
.getDescriptor(
UUID.fromString("00002901-0000-1000-8000-00805F9B34FB")
);
if (userDesc != null) {
bluetoothGatt.readDescriptor(userDesc);
}
Les descripteurs personnalisés sont utilisés lorsque les descripteurs standard Bluetooth SIG ne suffisent pas. Par exemple, un fabricant de capteurs médicaux peut ajouter un descripteur avec des informations d'étalonnage du capteur ou un descripteur avec un journal d'erreurs.
Un descripteur personnalisé est créé avec un UUID 128 bits, comme une caractéristique personnalisée. Côté Peripheral, le développeur l'ajoute à la caractéristique via l'API appropriée. Côté Central, le descripteur est découvert automatiquement lors de l'appel à discoverDescriptors.
Lors de la création d'un descripteur personnalisé, suivez ces règles : la longueur de la valeur doit correspondre au type de données attendu, et les droits d'accès (lecture/écriture) doivent être explicitement spécifiés. N'utilisez pas d'UUID de la plage des descripteurs standard Bluetooth SIG (0x2900–0x2908) à des fins personnalisées.
Caractéristique et descripteur sont des niveaux différents d'attributs GATT. Une caractéristique est un point de données, tandis qu'un descripteur est ses métadonnées ou sa configuration. La différence se manifeste à plusieurs égards : l'objectif, l'UUID et les règles d'accès.
Une caractéristique a une déclaration obligatoire qui est toujours présente dans la table GATT. Un descripteur est facultatif — une caractéristique peut n'avoir aucun descripteur. Une caractéristique peut être lue, écrite ou envoyer des notifications indépendamment. Un descripteur est toujours lié à une caractéristique et n'existe pas séparément.
Selon la Bluetooth Core Specification 5.4, l'ordre des attributs dans la table GATT est le suivant : déclaration de service, déclaration de caractéristique, valeur de caractéristique, descripteurs de caractéristique (le cas échéant), puis le service suivant. Cet ordre est obligatoire pour le bon fonctionnement des clients GATT.
Foire aux questions
CCCD est nécessaire pour la gestion des abonnements : la propriété Notify indique seulement que la caractéristique peut envoyer des notifications, mais ne les active pas. Le Central doit s'abonner explicitement en écrivant 0x0001 dans le CCCD. Cela évite l'envoi non désiré de données à un Central non préparé.
La spécification ne limite pas le nombre de descripteurs. En pratique, chaque caractéristique a généralement 1 à 3 descripteurs : CCCD (pour les caractéristiques avec Notify/Indicate), éventuellement User Description et Presentation Format. Trop de descripteurs augmentent la taille de la table GATT.
Dans la plupart des cas, non. Core Bluetooth sur iOS et Android ajoute automatiquement CCCD aux caractéristiques qui ont les propriétés Notify ou Indicate. Les descripteurs personnalisés sont créés manuellement uniquement pour des métadonnées spécifiques.
Non, le CCCD a un format (uint16) et un objectif strictement définis — la gestion des notifications. L'écriture d'autres valeurs viole la spécification Bluetooth et peut entraîner l'arrêt du fonctionnement de l'abonnement. Pour les données personnalisées, utilisez des descripteurs personnalisés avec un UUID 128 bits.
La User Description contient un nom lisible de la caractéristique — par exemple, « Température de l'appareil » au lieu de l'UUID 0x2A6E. L'application peut afficher ce nom dans l'interface, rendant l'interaction avec le périphérique BLE compréhensible pour l'utilisateur sans chaînes codées en dur.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi