GATT — какво е, Generic Attribute Profile и реализация в Android

Автор: IT Sectr Публикувано: 2026-07-14 Време за четене: 10 мин

GATT (Generic Attribute Profile) — Bluetooth Low Energy (BLE) профил, който определя структурата на данните и правилата за обмен на информация между BLE устройства. GATT е изграден върху Attribute Protocol (ATT) и организира данните в йерархия: услуги (services), характеристики (characteristics) и дескриптори (descriptors). По данни на Bluetooth SIG (2025), GATT профилът се използва в 98% от всички BLE приложения — от фитнес тракери до умни ключалки и медицински сензори.

Основни точки

  • GATT — BLE профил, определящ структурата на предаване на данни чрез услуги, характеристики и дескриптори
  • Йерархия — услугата съдържа характеристики, всяка характеристика е една стойност с опционални дескриптори
  • UUID — всяка услуга и характеристика се идентифицират от 16-битов (стандартни) или 128-битов (персонализирани) UUID
  • Роли — GATT Server (предоставя данни) и GATT Client (чете/записва данни)
  • Android API — BluetoothGatt, BluetoothGattService, BluetoothGattCharacteristic — основните класове за работа с GATT

Какво е GATT?

GATT (Generic Attribute Profile) — е Bluetooth Low Energy (BLE) профилът, който определя как две BLE устройства обменят данни чрез Attribute Protocol (ATT). GATT стандартизира структурата на данните: всички данни са организирани в йерархията „услуга → характеристика → дескриптор”. Профилът беше въведен в спецификацията Bluetooth 4.0 (2010) заедно с BLE и оттогава остава основният механизъм за предаване на данни за енергийно ефективни Bluetooth устройства. За разлика от класическия Bluetooth, където данните се предават чрез сериен порт (SPP), GATT предоставя структуриран достъп до данни чрез операции за четене, запис и уведомления.

Ролята на GATT в BLE стека

BLE стекът се състои от няколко слоя: Physical Layer (радио), Link Layer (управление на връзката), L2CAP (логическо канално предаване), ATT (Attribute Protocol — достъп до атрибути) и GATT (профил, базиран на ATT). GATT е най-високият слой, с който работи разработчикът на приложения. Долният ATT предоставя основни операции: четене, запис, уведомление и индикация на атрибути. GATT добавя семантика: определя какво е услуга, характеристика, как се групират и какви правила важат при тяхното четене и запис. Според Bluetooth Core Specification 5.4 (2023), GATT поддържа до 65 535 атрибута (услуги + характеристики + дескриптори) на едно устройство.

Архитектура на GATT: услуги, характеристики и дескриптори

GATT йерархията се състои от три нива. Услуга (Service) — логическа група от характеристики, решаваща една задача (например „Услуга за батерия” или „Услуга за сърдечен ритъм”). Характеристика (Characteristic) — единица данни с известен тип: текущо ниво на заряд, показания на сензор, състояние на ключ. Всяка характеристика има стойност (value) и един или повече дескриптори (Descriptors), описващи метаданни: мерни единици, настройки за уведомления, диапазон на стойностите. UUID (Universally Unique Identifier) уникално идентифицира всяка услуга и всяка характеристика.

Типове операции с характеристики

GATT поддържа четири типа операции за взаимодействие с характеристики. Read — клиентът изисква текущата стойност на характеристиката от сървъра. Write — клиентът изпраща нова стойност към сървъра. Notify — сървърът изпраща стойността до клиента без потвърждение (по-бърз, но по-малко надежден начин). Indicate — сървърът изпраща стойността с потвърждение за получаване (по-надежден, но по-бавен). Разработчикът избира типа в зависимост от сценария: за показания на сензор за пулс е достатъчен Notify, за запис на конфигурация на умна ключалка — Write с потвърждение.

kotlin
// GATT структура на данни в Android код
data class BleService(
    val uuid: UUID,
    val characteristics: List<BleCharacteristic>
)

data class BleCharacteristic(
    val uuid: UUID,
    val properties: Int, // ЧЕТЕНЕ, ЗАПИС, УВЕДОМЛЕНИЕ, ИНДИКАЦИЯ
    val descriptors: List<BleDescriptor>,
    var value: ByteArray?
)

GATT и GAP: разлики между BLE профилите

В спецификацията BLE са дефинирани два основни профила: GAP (Generic Access Profile) и GATT (Generic Attribute Profile). GAP отговаря за откриване на устройства, установяване на връзка и управление на видимостта — това е „мрежовият слой” на BLE. GATT — за обмен на данни след установяване на връзката, т.е. „приложният слой”. Разработчикът използва GAP за сканиране и свързване към устройство, а GATT — за четене, запис и получаване на уведомления от свързаното устройство.

ХарактеристикаGAPGATT
ПредназначениеОткриване и свързванеОбмен на данни
РолиCentral / PeripheralClient / Server
ПротоколHCI, Link LayerATT (Attribute Protocol)
ЕтапПреди свързванеСлед свързване
Основен класBluetoothAdapterBluetoothGatt

Роли в GATT

GATT дефинира две роли: GATT Server и GATT Client. Сървър — устройството, което предоставя данни (например фитнес тракер, предаващ показания на пулса). Клиент — устройството, което изисква данни (например смартфон, четящ измерванията). В повечето сценарии Android приложението действа като GATT Client, а BLE периферията като GATT Server. Android обаче може също да бъде GATT Server — например ако приложението емулира BLE устройство за други устройства. Ролята се определя на етапа на установяване на GATT връзката и не се променя по време на сесията.

Как работи GATT комуникацията в BLE

Процесът на GATT комуникация започва след установяване на BLE връзка между устройствата. Първо, GATT Client открива услуги на GATT Server чрез операцията Service Discovery — Android я изпълнява автоматично при свързване чрез BluetoothGatt.discoverServices(). След откриването клиентът получава списък с налични услуги, характеристики и дескриптори. След това клиентът може да чете стойности на характеристики (Read), да записва нови стойности (Write) или да се абонира за уведомления (Set Notify/Indicate). GATT Server може да изпраща Notify/Indicate до клиента по всяко време след установяване на връзката.

MTU — максимален размер на пакета

По подразбиране размерът на един GATT пакет (MTU, Maximum Transmission Unit) в BLE е 23 байта, от които 3 байта са заглавна част на ATT и 20 байта са полезни данни. Ако приложението трябва да предаде повече данни (например OTA актуализация на фърмуера), може да поиска увеличение на MTU до 517 байта чрез requestMtu() в Android. Увеличеният MTU намалява броя на пакетите, необходими за предаване на един блок данни — вместо 50 малки пакета могат да се изпратят 2 големи, което намалява консумацията на енергия и ускорява предаването. Максималният MTU зависи от версията на BLE и възможностите на чипа — Bluetooth 5.0 поддържа до 517 байта, по-старите версии — до 247 байта.

kotlin
// Абонирайте се за уведомления за характеристика
fun enableNotifications(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
    gatt.setCharacteristicNotification(characteristic, true)

    // Активирайте CCCD (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)
    }
}

Обработка на уведомления

За получаване на уведомления от GATT Server в Android трябва да се имплементира обратното извикване BluetoothGattCallback.onCharacteristicChanged(). В този метод приложението получава актуализираната стойност на характеристиката всеки път, когато сървърът изпраща Notify или Indicate. За обработка на данни в реално време използвайте буфер и Kotlin корутини — това ще предотврати блокирането на UI нишката при интензивни уведомления (например 100+ показания на пулс в секунда). При индикации (Indicate) задължително извиквайте gatt.sendResponse() от страна на сървъра — в Android клиента това се обработва автоматично.

Реализация на GATT в Android

В Android работата с GATT се реализира чрез класовете на пакета android.bluetooth: BluetoothGatt (връзка), BluetoothGattService (услуга), BluetoothGattCharacteristic (характеристика) и BluetoothGattDescriptor (дескриптор). Свързването към BLE устройство започва с извикване на BluetoothDevice.connectGatt() — този метод връща BluetoothGatt, чрез който се изпълняват всички последващи операции. Всички GATT обратни извиквания идват в BluetoothGattCallback — това е асинхронен интерфейс, извикван в същата нишка, в която е създаден BluetoothGatt. Важно: всички GATT операции трябва да се изпълняват последователно — едновременното извикване на няколко операции на един и същ BluetoothGatt води до грешки.

Жизнен цикъл на GATT връзката

Правилното управление на жизнения цикъл на GATT връзката е критично за стабилността на BLE приложението. След извикване на connectGatt(), приложението очаква обратното извикване onConnectionStateChange() със състояние STATE_CONNECTED. След това системата автоматично стартира Service Discovery, след чието завършване се извиква onServicesDiscovered(). Едва след това могат да се изпълнят четене, запис и абониране. След приключване на работата задължително извикайте gatt.close() в onDestroy() или onPause() — незатворените GATT връзки консумират батерия и могат да блокират повторното свързване към същото устройство в Android.

kotlin
// Свържете се с BLE устройство чрез 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) }
    }
}

Стандартни GATT профили и услуги

Bluetooth SIG (Special Interest Group) дефинира десетки стандартни GATT профили и услуги с фиксирани 16-битови UUID. Най-често срещаните: услуга Battery Service (UUID 180F, характеристика Battery Level 2A19), услуга Heart Rate (UUID 180D, характеристика Heart Rate Measurement 2A37), услуга Device Information (UUID 180A, характеристики Manufacturer Name, Serial Number). Използването на стандартни услуги гарантира съвместимост между устройства от различни производители — всяка фитнес гривна с услуга Heart Rate трябва да работи с всяко Android приложение, което я поддържа.

Проектиране на персонализирани GATT услуги

Ако стандартните услуги не покриват задачата, разработчикът може да създаде свои GATT услуги с 128-битови UUID (персонализирани UUID). При проектиране на персонализирана услуга трябва: да се дефинира логическата група от характеристики (например „Услуга за управление на ключалка”), да се зададат на всяка характеристика правилните свойства (Read, Write, Notify), да се определят допустимите стойности и мерни единици чрез дескриптора Characteristic Presentation Format. За сложни протоколи се препоръчва включването в услугата на характеристика Command със свойство Write и характеристика Status с Notify — това съответства на модела Command/Status, приет в индустриалните BLE приложения.

kotlin
// Създайте персонализирана GATT услуга (Android като 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
}

Често задавани въпроси

Какво е GATT в BLE и за какво служи?

GATT (Generic Attribute Profile) — е Bluetooth Low Energy профил, който определя структурата за обмен на данни между устройства. Той е необходим за стандартизиране на достъпа до информация: всички BLE устройства организират данните в услуги и характеристики, което позволява на всеки клиент да чете показания от сензори, да управлява устройства и да получава уведомления.

По какво GATT се различава от GAP?

GAP отговаря за откриване и свързване на BLE устройства (сканиране, реклама, установяване на връзка). GATT — за обмен на данни след свързване (четене, запис, уведомления). GAP работи преди свързване, GATT — след това. И двата профила са задължителни за BLE, но изпълняват различни функции: GAP е „мрежовият слой”, GATT е „приложният слой”.

Какви GATT услуги и характеристики съществуват?

Стандартните услуги включват Battery Service (180F, ниво на заряд), Heart Rate (180D, пулс), Device Information (180A, данни за устройството). Всяка услуга съдържа няколко характеристики с 16-битови UUID. Разработчиците могат да създават персонализирани услуги с 128-битови UUID за специфични задачи — например управление на умна ключалка или предаване на данни от фитнес тракер.

Как работи GATT в Android?

В Android GATT се имплементира чрез BluetoothGatt (връзка), BluetoothGattService (услуга), BluetoothGattCharacteristic (характеристика) и BluetoothGattDescriptor (дескриптор). Свързването се осъществява чрез connectGatt(), след което събитията идват в обратното извикване BluetoothGattCallback: onConnectionStateChange, onServicesDiscovered, onCharacteristicChanged (за уведомления). Всички GATT операции трябва да се изпълняват последователно.

Какво е UUID в GATT?

UUID (Universally Unique Identifier) — 16-битов или 128-битов идентификатор, който уникално определя услуга или характеристика в GATT. Стандартните Bluetooth SIG услуги използват 16-битови UUID (например 180D за Heart Rate). Персонализираните услуги на разработчици — 128-битови UUID (например 12345678-1234-5678-1234-56789abcdef0). UUID позволява на клиента да намери необходимите данни на GATT Server.

Резюме

  • GATT — BLE профил за структуриран обмен на данни чрез йерархия от услуги, характеристики и дескриптори, базиран на Attribute Protocol (ATT)
  • Йерархия на данните — услуга (логическа група), характеристика (конкретна стойност с тип), дескриптор (метаданни — единици, настройки за уведомления)
  • GATT роли — Server (предоставя данни, обикновено BLE периферия) и Client (чете/записва, обикновено Android смартфон)
  • Операции — Read, Write, Notify (без потвърждение, по-бързо) и Indicate (с потвърждение, по-надеждно); изборът зависи от сценария
  • Android API — BluetoothGatt, BluetoothGattCallback, BluetoothGattService, BluetoothGattCharacteristic; последователни асинхронни извиквания чрез обратни извиквания
  • Стандартни профили — Battery Service, Heart Rate, Device Information — осигуряват съвместимост между устройства от различни производители
  • Персонализирани услуги — 128-битови UUID за уникални задачи; проектират се по модела Command/Status с правилни свойства (Read, Write, Notify, Indicate)

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също