GATT — qu'est-ce que c'est, Generic Attribute Profile et implémentation sous Android

Auteur : IT Sectr Publié le : 2026-07-14 Temps de lecture : 10 min

GATT (Generic Attribute Profile) est un profil Bluetooth Low Energy (BLE) qui définit la structure des données et les règles d'échange d'informations entre les périphériques BLE. GATT est construit au-dessus du protocole d'attributs (ATT) et organise les données dans une hiérarchie : services, caractéristiques et descripteurs. Selon Bluetooth SIG (2025), le profil GATT est utilisé dans 98 % de toutes les applications BLE — des trackers d'activité aux serrures intelligentes et capteurs médicaux.

Points clés

  • GATT — un profil BLE qui définit la structure de transfert de données via des services, des caractéristiques et des descripteurs
  • Hiérarchie — un service contient des caractéristiques, chaque caractéristique a une valeur avec des descripteurs optionnels
  • UUID — chaque service et caractéristique est identifié par un UUID 16 bits (standard) ou 128 bits (personnalisé)
  • Rôles — Serveur GATT (fournit les données) et Client GATT (lit/écrit les données)
  • API Android — BluetoothGatt, BluetoothGattService, BluetoothGattCharacteristic — classes principales pour travailler avec GATT

Qu'est-ce que GATT ?

GATT (Generic Attribute Profile) est un profil Bluetooth Low Energy (BLE) qui définit comment deux périphériques BLE échangent des données via le protocole d'attributs (ATT). GATT standardise la structure des données : toutes les données sont organisées dans une hiérarchie « service → caractéristique → descripteur ». Le profil a été introduit dans la spécification Bluetooth 4.0 (2010) avec le BLE et reste depuis le mécanisme principal de transfert de données pour les périphériques Bluetooth économes en énergie. Contrairement au Bluetooth classique, où les données sont transmises via un port série (SPP), GATT fournit un accès structuré aux données via des opérations de lecture, d'écriture et de notification.

Le rôle de GATT dans la pile BLE

La pile BLE se compose de plusieurs couches : couche physique (radio), couche de liaison (gestion de connexion), L2CAP (contrôle de canal logique), ATT (protocole d'attributs — accès aux attributs) et GATT (profil basé sur ATT). GATT est la couche la plus haute avec laquelle travaillent les développeurs d'applications. L'ATT sous-jacent fournit des opérations de base : lecture, écriture, notification et indication d'attributs. GATT ajoute de la sémantique : il définit ce qu'est un service et une caractéristique, comment ils sont regroupés et quelles règles s'appliquent lors de leur lecture et écriture. Selon la Bluetooth Core Specification 5.4 (2023), GATT prend en charge jusqu'à 65 535 attributs (services + caractéristiques + descripteurs) sur un seul périphérique.

Architecture GATT : services, caractéristiques et descripteurs

La hiérarchie GATT se compose de trois niveaux. Un service est un groupe logique de caractéristiques qui résout une tâche (par exemple, « Service de batterie » ou « Service de fréquence cardiaque »). Une caractéristique est une unité de données avec un type connu : niveau de batterie actuel, lecture de capteur, état d'interrupteur. Chaque caractéristique a une valeur et un ou plusieurs descripteurs qui décrivent les métadonnées : unités de mesure, paramètres de notification, plage de valeurs. Un UUID (identifiant universel unique) identifie de manière unique chaque service et chaque caractéristique.

Types d'opérations avec les caractéristiques

GATT prend en charge quatre types d'opérations pour interagir avec les caractéristiques. Read — le client demande la valeur actuelle d'une caractéristique au serveur. Write — le client envoie une nouvelle valeur au serveur. Notify — le serveur envoie une valeur au client sans accusé de réception (plus rapide mais moins fiable). Indicate — le serveur envoie une valeur avec accusé de réception (plus fiable mais plus lent). Le développeur choisit le type en fonction du scénario : pour les lectures de capteur de fréquence cardiaque, Notify est suffisant ; pour écrire la configuration d'une serrure intelligente, Write avec accusé de réception est nécessaire.

kotlin
// Structure de données GATT dans le code Android
data class BleService(
    val uuid: UUID,
    val characteristics: List<BleCharacteristic>
)

data class BleCharacteristic(
    val uuid: UUID,
    val properties: Int, // READ, WRITE, NOTIFY, INDICATE
    val descriptors: List<BleDescriptor>,
    var value: ByteArray?
)

GATT et GAP : différences entre les profils BLE

La spécification BLE définit deux profils principaux : GAP (Generic Access Profile) et GATT (Generic Attribute Profile). GAP est responsable de la découverte des périphériques, de l'établissement de connexion et de la gestion de la visibilité — c'est la « couche réseau » du BLE. GATT est responsable de l'échange de données après l'établissement de la connexion — la « couche application ». Le développeur utilise GAP pour scanner et se connecter à un périphérique, et GATT pour lire, écrire et recevoir des notifications du périphérique connecté.

CaractéristiqueGAPGATT
ObjectifDécouverte et connexionÉchange de données
RôlesCentral / PériphériqueClient / Serveur
ProtocoleHCI, couche de liaisonATT (protocole d'attributs)
PhaseAvant la connexionAprès la connexion
Classe principaleBluetoothAdapterBluetoothGatt

Rôles dans GATT

GATT définit deux rôles : Serveur GATT et Client GATT. Le serveur est un périphérique qui fournit des données (par exemple, un tracker d'activité envoyant des lectures de fréquence cardiaque). Le client est un périphérique qui demande des données (par exemple, un smartphone lisant les lectures). Dans la plupart des scénarios, l'application Android agit en tant que Client GATT et le périphérique BLE agit en tant que Serveur GATT. Cependant, Android peut également être un Serveur GATT — par exemple, lorsqu'une application émule un périphérique BLE pour d'autres appareils. Le rôle est déterminé lors de la phase de configuration de la connexion GATT et ne change pas pendant la session.

Comment fonctionne la communication GATT en BLE

Le processus de communication GATT commence après l'établissement de la connexion BLE entre les périphériques. D'abord, le Client GATT découvre les services sur le Serveur GATT via la découverte de services — Android le fait automatiquement lors de la connexion via BluetoothGatt.discoverServices(). Après la découverte, le client obtient une liste des services, caractéristiques et descripteurs disponibles. Ensuite, le client peut lire les valeurs des caractéristiques (Read), écrire de nouvelles valeurs (Write) ou s'abonner aux notifications (Set Notify/Indicate). Le Serveur GATT peut envoyer Notify/Indicate au client à tout moment après l'établissement de la connexion.

MTU — Unité maximale de transmission

Par défaut, la taille d'un seul paquet GATT (MTU) en BLE est de 23 octets, dont 3 octets d'en-tête ATT et 20 octets de données utiles. Si l'application doit transmettre plus de données (par exemple, une mise à jour OTA du firmware), il est possible de demander une augmentation du MTU jusqu'à 517 octets via requestMtu() dans Android. Un MTU accru réduit le nombre de paquets nécessaires pour transmettre un bloc de données — au lieu de 50 petits paquets, vous pouvez envoyer 2 gros paquets, ce qui réduit la consommation d'énergie et accélère la transmission. Le MTU maximum dépend de la version BLE et des capacités de la puce — Bluetooth 5.0 prend en charge jusqu'à 517 octets, les versions plus anciennes jusqu'à 247 octets.

kotlin
// S'abonner aux notifications de caractéristiques
fun enableNotifications(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
    gatt.setCharacteristicNotification(characteristic, true)

    // Activer CCCD (Descripteur de configuration de caractéristique client)
    val cccdUuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")
    val descriptor = characteristic.getDescriptor(cccdUuid)
    descriptor?.let {
        it.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)
        gatt.writeDescriptor(it)
    }
}

Gestion des notifications

Pour recevoir des notifications du Serveur GATT sur Android, vous devez implémenter le rappel BluetoothGattCallback.onCharacteristicChanged(). Dans cette méthode, l'application reçoit la valeur mise à jour de la caractéristique chaque fois que le serveur envoie Notify ou Indicate. Pour le traitement des données en temps réel, utilisez un tampon et les coroutines Kotlin — cela évite de bloquer le thread UI lors de notifications intensives (par exemple, plus de 100 lectures de fréquence cardiaque par seconde). Pour les Indications, vous devez appeler gatt.sendResponse() côté serveur — sur le client Android, cela est géré automatiquement.

Implémentation de GATT sur Android

Sur Android, le travail avec GATT est implémenté via les classes du package android.bluetooth : BluetoothGatt (connexion), BluetoothGattService (service), BluetoothGattCharacteristic (caractéristique) et BluetoothGattDescriptor (descripteur). La connexion à un périphérique BLE commence par l'appel de BluetoothDevice.connectGatt() — cette méthode retourne un BluetoothGatt via lequel toutes les opérations ultérieures sont effectuées. Tous les rappels GATT arrivent dans BluetoothGattCallback — c'est une interface asynchrone qui est appelée sur le même thread où BluetoothGatt a été créé. Important : toutes les opérations GATT doivent être effectuées séquentiellement — appeler plusieurs opérations simultanément sur le même BluetoothGatt entraîne des erreurs.

Cycle de vie de la connexion GATT

La gestion appropriée du cycle de vie de la connexion GATT est essentielle pour la stabilité de l'application BLE. Après avoir appelé connectGatt(), l'application attend le rappel onConnectionStateChange() avec l'état STATE_CONNECTED. Ensuite, le système lance automatiquement la découverte de services, après quoi onServicesDiscovered() est appelé. Ce n'est qu'après cela que vous pouvez effectuer des lectures, écritures et abonnements. Lors de la fin, appelez toujours gatt.close() dans onDestroy() ou onPause() — les connexions GATT non fermées consomment la batterie et peuvent bloquer la reconnexion au même périphérique sur Android.

kotlin
// Se connecter au périphérique BLE via GATT
private val gattCallback = object : BluetoothGattCallback() {
    override fun onConnectionStateChange(
        gatt: BluetoothGatt, status: Int, newState: Int
    ) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            gatt.discoverServices()
        }
    }

    override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
        val service = gatt.getService(UUID.fromString("180D"))
        val characteristic = service?.getCharacteristic(
            UUID.fromString("2A37")
        )
        characteristic?.let { enableNotifications(gatt, it) }
    }
}

Profils et services GATT standard

Bluetooth SIG définit des dizaines de profils et services GATT standard avec des UUID 16 bits fixes. Les plus courants : Battery Service (UUID 180F, caractéristique Battery Level 2A19), service Heart Rate (UUID 180D, caractéristique Heart Rate Measurement 2A37), service Device Information (UUID 180A, caractéristiques Manufacturer Name et Serial Number). L'utilisation de services standard garantit la compatibilité entre les périphériques de différents fabricants — tout bracelet de fitness avec un service Heart Rate devrait fonctionner avec toute application Android qui le prend en charge.

Conception de services GATT personnalisés

Si les services standard ne couvrent pas la tâche, le développeur peut créer des services GATT personnalisés avec des UUID 128 bits. Lors de la conception d'un service personnalisé, vous devez : définir un groupe logique de caractéristiques (par exemple, « Service de contrôle de serrure »), attribuer à chaque caractéristique les propriétés correctes (Read, Write, Notify), définir les valeurs autorisées et les unités de mesure via le descripteur Characteristic Presentation Format. Pour les protocoles complexes, il est recommandé d'inclure une caractéristique Command avec propriété Write et une caractéristique Status avec Notify — cela suit le modèle Command/Status adopté dans les applications BLE industrielles.

kotlin
// Créer un service GATT personnalisé (Android comme Serveur GATT)
private fun createCustomService(): BluetoothGattService {
    val serviceUuid = UUID.fromString("12345678-1234-5678-1234-56789abcdef0")
    val service = BluetoothGattService(
        serviceUuid, BluetoothGattService.SERVICE_TYPE_PRIMARY
    )

    val charUuid = UUID.fromString("12345678-1234-5678-1234-56789abcdef1")
    val characteristic = BluetoothGattCharacteristic(
        charUuid,
        BluetoothGattCharacteristic.PROPERTY_READ or
        BluetoothGattCharacteristic.PROPERTY_NOTIFY,
        BluetoothGattCharacteristic.PERMISSION_READ
    )
    service.addCharacteristic(characteristic)
    return service
}

Questions fréquentes

Qu'est-ce que GATT en BLE et pourquoi est-il nécessaire ?

GATT (Generic Attribute Profile) est un profil Bluetooth Low Energy qui définit la structure d'échange de données entre les périphériques. Il est nécessaire pour standardiser l'accès à l'information : tous les périphériques BLE organisent les données en services et caractéristiques, permettant à tout client de lire les capteurs, de contrôler les appareils et de recevoir des notifications.

Quelle est la différence entre GATT et GAP ?

GAP est responsable de la découverte et de la connexion des périphériques BLE (scan, publicité, établissement de connexion). GATT est responsable de l'échange de données après la connexion (lecture, écriture, notifications). GAP fonctionne avant la connexion, GATT après. Les deux profils sont obligatoires pour BLE, mais remplissent des fonctions différentes : GAP est la « couche réseau », GATT est la « couche application ».

Quels sont les services et caractéristiques GATT existants ?

Les services standard incluent Battery Service (180F, niveau de batterie), Heart Rate (180D, pouls), Device Information (180A, données du périphérique). Chaque service contient plusieurs caractéristiques avec des UUID 16 bits. Les développeurs peuvent créer des services personnalisés avec des UUID 128 bits pour des tâches spécifiques — comme le contrôle d'une serrure intelligente ou la transmission de données d'un tracker d'activité.

Comment GATT fonctionne-t-il sur Android ?

Sur Android, GATT est implémenté via BluetoothGatt (connexion), BluetoothGattService (service), BluetoothGattCharacteristic (caractéristique) et BluetoothGattDescriptor (descripteur). La connexion se fait via connectGatt(), après quoi les événements arrivent via BluetoothGattCallback : onConnectionStateChange, onServicesDiscovered, onCharacteristicChanged (pour les notifications). Toutes les opérations GATT doivent être effectuées séquentiellement.

Qu'est-ce qu'un UUID dans GATT ?

UUID (identifiant universel unique) est un identifiant 16 ou 128 bits qui identifie de manière unique un service ou une caractéristique dans GATT. Les services standard Bluetooth SIG utilisent des UUID 16 bits (par exemple, 180D pour Heart Rate). Les services personnalisés du développeur utilisent des UUID 128 bits (par exemple, 12345678-1234-5678-1234-56789abcdef0). L'UUID permet au client de trouver les données nécessaires sur le Serveur GATT.

Résumé

  • GATT — un profil BLE pour l'échange structuré de données via une hiérarchie de services, caractéristiques et descripteurs, basé sur le protocole d'attributs (ATT)
  • Hiérarchie des données — service (groupe logique), caractéristique (valeur spécifique avec type), descripteur (métadonnées — unités, paramètres de notification)
  • Rôles GATT — Serveur (fournit les données, généralement périphérique BLE) et Client (lit/écrit, généralement smartphone Android)
  • Opérations — Read, Write, Notify (sans accusé de réception, plus rapide) et Indicate (avec accusé de réception, plus fiable) ; le choix dépend du scénario
  • API Android — BluetoothGatt, BluetoothGattCallback, BluetoothGattService, BluetoothGattCharacteristic ; appels asynchrones séquentiels via des rappels
  • Profils standard — Battery Service, Heart Rate, Device Information — garantissent la compatibilité entre les périphériques de différents fabricants
  • Services personnalisés — UUID 128 bits pour des tâches uniques ; conçus selon le modèle Command/Status avec les propriétés correctes (Read, Write, Notify, Indicate)

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.

Discuter du projet

Lisez aussi