GATT (Generic Attribute Profile) — Bluetooth Low Energy (BLE) profil, amely meghatározza az adatstruktúrát és az információcsere szabályait BLE-eszközök között. A GATT az Attribute Protocol (ATT) fölé épül, és az adatokat hierarchiába rendezi: szolgáltatások (services), jellemzők (characteristics) és leírók (descriptors). A Bluetooth SIG (2025) adatai szerint a GATT profilt az összes BLE-alkalmazás 98%-ában használják — a fitneszkövetőktől az intelligens zárakig és orvosi érzékelőkig.
Legfontosabb pontok
GATT (Generic Attribute Profile) — a Bluetooth Low Energy (BLE) profil, amely meghatározza, hogy két BLE-eszköz hogyan cserél adatokat az Attribute Protocol (ATT) segítségével. A GATT szabványosítja az adatstruktúrát: minden adat a „szolgáltatás → jellemző → leíró” hierarchiában van szervezve. A profilt a Bluetooth 4.0 specifikációban (2010) vezették be a BLE-vel együtt, és azóta is az energiahatékony Bluetooth-eszközök fő adatátviteli mechanizmusa maradt. Ellentétben a klasszikus Bluetooth-tal, ahol az adatok soros porton (SPP) keresztül kerülnek továbbításra, a GATT strukturált hozzáférést biztosít az adatokhoz olvasási, írási és értesítési műveleteken keresztül.
A BLE-verem több rétegből áll: Physical Layer (rádió), Link Layer (kapcsolatkezelés), L2CAP (logikai csatornaátvitel), ATT (Attribute Protocol — hozzáférés az attribútumokhoz) és GATT (ATT-alapú profil). A GATT a legfelső réteg, amellyel az alkalmazásfejlesztő dolgozik. Az alatta lévő ATT alapvető műveleteket biztosít: attribútumok olvasása, írása, értesítése és jelzése. A GATT szemantikát ad hozzá: meghatározza, mi a szolgáltatás, mi a jellemző, hogyan csoportosulnak, és milyen szabályok érvényesek az olvasásukra és írásukra. A Bluetooth Core Specification 5.4 (2023) szerint a GATT egyetlen eszközön akár 65 535 attribútumot (szolgáltatások + jellemzők + leírók) támogat.
A GATT-hierarchia három szintből áll. Szolgáltatás (Service) — egy feladatot megoldó jellemzők logikai csoportja (például „Akkumulátor szolgáltatás” vagy „Pulzusszám szolgáltatás”). Jellemző (Characteristic) — ismert típusú adategység: aktuális töltöttségi szint, érzékelő leolvasások, kapcsoló állapota. Minden jellemzőnek van értéke (value) és egy vagy több leírója (Descriptors), amelyek metaadatokat írnak le: mértékegységek, értesítési beállítások, értéktartomány. Az UUID (Universally Unique Identifier) egyedileg azonosít minden szolgáltatást és minden jellemzőt.
A GATT négyféle műveletet támogat a jellemzőkkel való interakcióhoz. Read — a kliens kéri a jellemző aktuális értékét a szervertől. Write — a kliens új értéket küld a szervernek. Notify — a szerver értesítés nélkül küldi az értéket a kliensnek (gyorsabb, de kevésbé megbízható). Indicate — a szerver az értéket átvételi visszaigazolással küldi (megbízhatóbb, de lassabb). A fejlesztő a forgatókönyv alapján választja ki a típust: pulzusérzékelő leolvasásához elegendő a Notify, intelligens zár konfigurációjának írásához — Write visszaigazolással.
// GATT adatstruktúra Android kódban
data class BleService(
val uuid: UUID,
val characteristics: List<BleCharacteristic>
)
data class BleCharacteristic(
val uuid: UUID,
val properties: Int, // OLVASÁS, ÍRÁS, ÉRTESÍTÉS, JELZÉS
val descriptors: List<BleDescriptor>,
var value: ByteArray?
)
A BLE specifikációban két fő profil van meghatározva: GAP (Generic Access Profile) és GATT (Generic Attribute Profile). A GAP felelős az eszközök észleléséért, a kapcsolat létrehozásáért és a láthatóság kezeléséért — ez a BLE „hálózati rétege”. A GATT — a kapcsolat létrehozása utáni adatcseréért, vagyis az „alkalmazási réteg”. A fejlesztő a GAP-ot használja az eszköz szkennelésére és csatlakozására, a GATT-ot pedig a csatlakoztatott eszközről történő olvasásra, írásra és értesítések fogadására.
| Jellemző | GAP | GATT |
|---|---|---|
| Cél | Észlelés és csatlakozás | Adatcsere |
| Szerepek | Central / Peripheral | Client / Server |
| Protokoll | HCI, Link Layer | ATT (Attribute Protocol) |
| Szakasz | Csatlakozás előtt | Csatlakozás után |
| Fő osztály | BluetoothAdapter | BluetoothGatt |
A GATT két szerepet határoz meg: GATT Server és GATT Client. Szerver — az eszköz, amely adatokat szolgáltat (például fitneszkövető, amely pulzusadatokat küld). Kliens — az eszköz, amely adatokat kér (például okostelefon, amely leolvassa a méréseket). A legtöbb forgatókönyvben az Android-alkalmazás GATT Client-ként, a BLE-periféria pedig GATT Server-ként működik. Az Android azonban lehet GATT Server is — például ha az alkalmazás BLE-eszközt emulál más eszközök számára. A szerep a GATT-kapcsolat létrehozásának szakaszában kerül meghatározásra, és nem változik a munkamenet során.
A GATT kommunikáció folyamata a BLE-kapcsolat létrehozása után kezdődik az eszközök között. Először a GATT Client felfedezi a szolgáltatásokat a GATT Serveren a Service Discovery műveleten keresztül — az Android ezt automatikusan elvégzi csatlakozáskor a BluetoothGatt.discoverServices() segítségével. A felfedezés után a kliens megkapja az elérhető szolgáltatások, jellemzők és leírók listáját. Ezután a kliens olvashatja a jellemzők értékeit (Read), írhat új értékeket (Write) vagy feliratkozhat értesítésekre (Set Notify/Indicate). A GATT Server bármikor küldhet Notify/Indicate értesítést a kliensnek a kapcsolat létrehozása után.
Alapértelmezés szerint egy GATT-csomag (MTU, Maximum Transmission Unit) mérete BLE-ben 23 bájt, ebből 3 bájt az ATT fejléc és 20 bájt a hasznos adat. Ha az alkalmazásnak több adatot kell továbbítania (például OTA firmware-frissítés), kérhető az MTU növelése 517 bájtra az Android requestMtu() függvényén keresztül. A megnövelt MTU csökkenti az egy adatblokk továbbításához szükséges csomagok számát — 50 kis csomag helyett 2 nagy csomag küldhető, ami csökkenti az energiafogyasztást és gyorsítja az átvitelt. A maximális MTU a BLE verziójától és a chip képességeitől függ — Bluetooth 5.0 akár 517 bájtot, régebbi verziók akár 247 bájtot támogatnak.
// Feliratkozás a jellemző értesítéseire
fun enableNotifications(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
gatt.setCharacteristicNotification(characteristic, true)
// CCCD engedélyezése (Client Characteristic Configuration Descriptor)
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)
}
}
Az GATT Server értesítéseinek fogadásához Androidban implementálni kell a BluetoothGattCallback.onCharacteristicChanged() visszahívást. Ebben a metódusban az alkalmazás minden alkalommal megkapja a jellemző frissített értékét, amikor a szerver Notify vagy Indicate értesítést küld. Valós idejű adatfeldolgozáshoz használjon puffert és Kotlin-korutinokat — ez megakadályozza a UI szál blokkolását intenzív értesítések esetén (például 100+ pulzusmérés másodpercenként). Indikációknál (Indicate) feltétlenül hívja meg a gatt.sendResponse() függvényt a szerver oldalon — az Android kliens oldalon ez automatikusan történik.
Androidon a GATT-tal való munka az android.bluetooth csomag osztályain keresztül valósul meg: BluetoothGatt (kapcsolat), BluetoothGattService (szolgáltatás), BluetoothGattCharacteristic (jellemző) és BluetoothGattDescriptor (leíró). A BLE-eszközhöz való csatlakozás a BluetoothDevice.connectGatt() meghívásával kezdődik — ez a metódus visszaadja a BluetoothGatt-ot, amelyen keresztül minden további művelet végrehajtódik. Minden GATT visszahívás a BluetoothGattCallback-ben érkezik — ez egy aszinkron interfész, amely ugyanabban a szálban hívódik meg, ahol a BluetoothGatt létrejött. Fontos: minden GATT-műveletet szekvenciálisan kell végrehajtani — több művelet egyidejű meghívása ugyanazon a BluetoothGatt-on hibákhoz vezet.
A GATT-kapcsolat életciklusának helyes kezelése kritikus a BLE-alkalmazás stabilitása szempontjából. A connectGatt() meghívása után az alkalmazás a STATE_CONNECTED állapottal várja az onConnectionStateChange() visszahívást. Ezután a rendszer automatikusan elindítja a Service Discovery-t, amelynek befejezése után az onServicesDiscovered() hívódik meg. Csak ezután végezhető el az olvasás, írás és feliratkozás. A munka befejezésekor feltétlenül hívja meg a gatt.close() függvényt az onDestroy() vagy onPause() metódusban — a le nem zárt GATT-kapcsolatok energiát fogyasztanak és blokkolhatják az újbóli csatlakozást ugyanahhoz az eszközhöz Androidon.
// Csatlakozás BLE-eszközhöz GATT-on keresztül
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) }
}
}
A Bluetooth SIG (Special Interest Group) több tucat szabványos GATT-profilt és szolgáltatást határoz meg rögzített 16 bites UUID-okkal. A leggyakoribbak: Battery Service szolgáltatás (UUID 180F, Battery Level jellemző 2A19), Heart Rate szolgáltatás (UUID 180D, Heart Rate Measurement jellemző 2A37), Device Information szolgáltatás (UUID 180A, Manufacturer Name, Serial Number jellemzők). A szabványos szolgáltatások használata garantálja a kompatibilitást a különböző gyártók eszközei között — bármely fitneszkarkötő Heart Rate szolgáltatással működnie kell bármely Android-alkalmazással, amely támogatja azt.
Ha a szabványos szolgáltatások nem fedik le a feladatot, a fejlesztő saját GATT-szolgáltatásokat hozhat létre 128 bites UUID-okkal (egyedi UUID-ok). Egy egyedi szolgáltatás tervezésekor meg kell: határozni a jellemzők logikai csoportját (például „Zárkezelő szolgáltatás”), minden jellemzőhöz megfelelő tulajdonságokat rendelni (Read, Write, Notify), meghatározni a megengedett értékeket és mértékegységeket a Characteristic Presentation Format leírón keresztül. Összetett protokollok esetén ajánlott a szolgáltatásba belefoglalni egy Command jellemzőt Write tulajdonsággal és egy Status jellemzőt Notify tulajdonsággal — ez megfelel az ipari BLE-alkalmazásokban elfogadott Command/Status mintának.
// Egyedi GATT-szolgáltatás létrehozása (Android mint GATT Server)
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
}
Gyakran ismételt kérdések
A GATT (Generic Attribute Profile) egy Bluetooth Low Energy profil, amely meghatározza az eszközök közötti adatcsere szerkezetét. Az információhoz való hozzáférés szabványosításához szükséges: minden BLE-eszköz szolgáltatásokba és jellemzőkbe rendezi az adatokat, ami lehetővé teszi bármely kliens számára az érzékelők leolvasását, az eszközök vezérlését és az értesítések fogadását.
A GAP felelős a BLE-eszközök észleléséért és csatlakoztatásáért (szkennelés, reklámozás, kapcsolat létrehozása). A GATT — a kapcsolat utáni adatcseréért (olvasás, írás, értesítések). A GAP a kapcsolat előtt működik, a GATT — utána. Mindkét profil kötelező a BLE-hez, de különböző funkciókat látnak el: a GAP a „hálózati réteg”, a GATT az „alkalmazási réteg”.
A szabványos szolgáltatások közé tartozik a Battery Service (180F, töltöttségi szint), Heart Rate (180D, pulzus), Device Information (180A, eszközinformációk). Minden szolgáltatás több jellemzőt tartalmaz 16 bites UUID-okkal. A fejlesztők egyedi szolgáltatásokat hozhatnak létre 128 bites UUID-okkal speciális feladatokhoz — például intelligens zár vezérléséhez vagy fitneszkövető adatainak továbbításához.
Androidon a GATT a BluetoothGatt (kapcsolat), BluetoothGattService (szolgáltatás), BluetoothGattCharacteristic (jellemző) és BluetoothGattDescriptor (leíró) osztályokon keresztül valósul meg. A csatlakozás a connectGatt() segítségével történik, ezután az események a BluetoothGattCallback visszahívásban érkeznek: onConnectionStateChange, onServicesDiscovered, onCharacteristicChanged (értesítésekhez). Minden GATT-műveletet szekvenciálisan kell végrehajtani.
UUID (Universally Unique Identifier) — 16 bites vagy 128 bites azonosító, amely egyedileg határozza meg a szolgáltatást vagy jellemzőt a GATT-ban. A szabványos Bluetooth SIG szolgáltatások 16 bites UUID-okat használnak (például 180D a Heart Rate számára). A fejlesztők egyedi szolgáltatásai — 128 bites UUID-ok (például 12345678-1234-5678-1234-56789abcdef0). Az UUID lehetővé teszi a kliens számára, hogy megtalálja a szükséges adatokat a GATT Serveren.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is