GATT (Generic Attribute Profile), BLE cihazları arasındaki veri yapısını ve bilgi alışverişi kurallarını tanımlayan bir Bluetooth Low Energy (BLE) profilidir. GATT, Attribute Protocol (ATT) üzerine inşa edilmiştir ve verileri bir hiyerarşi halinde düzenler: servisler, karakteristikler ve tanımlayıcılar. Bluetooth SIG'e (2025) göre, GATT profili fitness takipçilerinden akıllı kilitlere ve tıbbi sensörlere kadar tüm BLE uygulamalarının %98'inde kullanılmaktadır.
Önemli Noktalar
GATT (Generic Attribute Profile), iki BLE cihazının Attribute Protocol (ATT) aracılığıyla nasıl veri alışverişi yaptığını tanımlayan bir Bluetooth Low Energy (BLE) profilidir. GATT veri yapısını standartlaştırır: tüm veriler “servis → karakteristik → tanımlayıcı” hiyerarşisinde düzenlenir. Profil, BLE ile birlikte Bluetooth 4.0 spesifikasyonunda (2010) tanıtılmıştır ve o zamandan beri enerji verimli Bluetooth cihazları için birincil veri aktarım mekanizması olarak kalmıştır. Verilerin seri bağlantı noktası (SPP) üzerinden iletildiği klasik Bluetooth'un aksine, GATT okuma, yazma ve bildirim işlemleri aracılığıyla verilere yapılandırılmış erişim sağlar.
BLE yığını birkaç katmandan oluşur: Fiziksel Katman (radyo), Bağlantı Katmanı (bağlantı yönetimi), L2CAP (mantıksal kanal kontrolü), ATT (Attribute Protocol — özniteliklere erişim) ve GATT (ATT tabanlı profil). GATT, uygulama geliştiricilerinin çalıştığı en üst katmandır. Alttaki ATT temel işlemleri sağlar: öznitelikleri okuma, yazma, bildirme ve belirtme. GATT anlambilim ekler: bir servis ve karakteristiğin ne olduğunu, nasıl gruplandıklarını ve okuma/yazma sırasında hangi kuralların geçerli olduğunu tanımlar. Bluetooth Core Specification 5.4'e (2023) göre GATT, tek bir cihazda 65.535'e kadar özniteliği (servisler + karakteristikler + tanımlayıcılar) destekler.
GATT hiyerarşisi üç seviyeden oluşur. Bir Servis, tek bir görevi çözen karakteristiklerin mantıksal bir grubudur (örneğin, “Pil Servisi” veya “Kalp Atış Hızı Servisi”). Bir Karakteristik, bilinen bir türe sahip bir veri birimidir: mevcut pil seviyesi, sensör okuması, anahtar durumu. Her karakteristik bir değere ve meta verileri tanımlayan bir veya daha fazla Tanımlayıcıya sahiptir: ölçüm birimleri, bildirim ayarları, değer aralığı. UUID (Evrensel Benzersiz Tanımlayıcı), her servisi ve her karakteristiği benzersiz şekilde tanımlar.
GATT, karakteristiklerle etkileşim için dört tür işlemi destekler. Read — istemci, sunucudan bir karakteristiğin mevcut değerini ister. Write — istemci, sunucuya yeni bir değer gönderir. Notify — sunucu, onay almadan istemciye bir değer gönderir (daha hızlı ancak daha az güvenilir). Indicate — sunucu, alındı onayı ile değer gönderir (daha güvenilir ancak daha yavaş). Geliştirici, senaryoya göre türü seçer: kalp atış hızı sensörü okumaları için Notify yeterlidir; akıllı kilit yapılandırması yazmak için onaylı Write gereklidir.
// Android kodunda GATT veri yapısı
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?
)
BLE spesifikasyonu iki ana profil tanımlar: GAP (Generic Access Profile) ve GATT (Generic Attribute Profile). GAP, cihaz keşfi, bağlantı kurulumu ve görünürlük yönetiminden sorumludur — BLE'nin “ağ katmanıdır”. GATT, bağlantı kurulduktan sonra veri alışverişinden sorumludur — “uygulama katmanı”. Geliştirici, cihazları taramak ve bağlanmak için GAP'ı kullanır ve bağlı cihazdan veri okumak, yazmak ve bildirim almak için GATT'ı kullanır.
| Özellik | GAP | GATT |
|---|---|---|
| Amaç | Keşif ve bağlantı | Veri alışverişi |
| Roller | Merkez / Çevre Birim | İstemci / Sunucu |
| Protokol | HCI, Bağlantı Katmanı | ATT (Attribute Protocol) |
| Aşama | Bağlantıdan önce | Bağlantıdan sonra |
| Ana sınıf | BluetoothAdapter | BluetoothGatt |
GATT iki rol tanımlar: GATT Sunucusu ve GATT İstemcisi. Sunucu, veri sağlayan bir cihazdır (örneğin, kalp atış hızı okumaları gönderen bir fitness takipçisi). İstemci, veri talep eden bir cihazdır (örneğin, okumaları okuyan bir akıllı telefon). Çoğu senaryoda, Android uygulaması GATT İstemcisi olarak hareket eder ve BLE çevre birimi GATT Sunucusu olarak hareket eder. Ancak Android, GATT Sunucusu da olabilir — örneğin, bir uygulama diğer cihazlar için bir BLE cihazını taklit ettiğinde. Rol, GATT bağlantı kurulum aşamasında belirlenir ve oturum boyunca değişmez.
GATT iletişim süreci, cihazlar arasında BLE bağlantısı kurulduktan sonra başlar. İlk olarak, GATT İstemcisi, Hizmet Keşfi aracılığıyla GATT Sunucusundaki servisleri keşfeder — Android, BluetoothGatt.discoverServices() aracılığıyla bağlantı sırasında bunu otomatik olarak yapar. Keşiften sonra, istemci kullanılabilir servislerin, karakteristiklerin ve tanımlayıcıların bir listesini alır. Ardından, istemci karakteristik değerlerini okuyabilir (Read), yeni değerler yazabilir (Write) veya bildirimlere abone olabilir (Set Notify/Indicate). GATT Sunucusu, bağlantı kurulduktan sonra istediği zaman istemciye Notify/Indicate gönderebilir.
Varsayılan olarak, BLE'de tek bir GATT paketinin (MTU) boyutu 23 bayttır; bunun 3 baytı ATT başlığı ve 20 baytı yük verisidir. Uygulamanın daha fazla veri iletmesi gerekiyorsa (örneğin, OTA bellenim güncellemesi), Android'de requestMtu() aracılığıyla MTU'nun 517 bayta kadar artırılması istenebilir. Artırılmış MTU, tek bir veri bloğunu iletmek için gereken paket sayısını azaltır — 50 küçük paket yerine 2 büyük paket gönderebilirsiniz, bu da güç tüketimini azaltır ve iletimi hızlandırır. Maksimum MTU, BLE sürümüne ve çip yeteneklerine bağlıdır — Bluetooth 5.0 517 bayta kadar, eski sürümler 247 bayta kadar destekler.
// Karakteristik bildirimlerine abone ol
fun enableNotifications(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
gatt.setCharacteristicNotification(characteristic, true)
// CCCD'yi (İstemci Karakteristik Yapılandırma Tanımlayıcısı) etkinleştir
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)
}
}
Android'de GATT Sunucusundan bildirim almak için, BluetoothGattCallback.onCharacteristicChanged() geri çağrısını uygulamanız gerekir. Bu yöntemde, uygulama sunucu her Notify veya Indicate gönderdiğinde güncellenmiş karakteristik değerini alır. Gerçek zamanlı veri işleme için bir arabellek ve Kotlin coroutine'leri kullanın — bu, yoğun bildirimler sırasında (örneğin, saniyede 100'den fazla kalp atış hızı okuması) UI iş parçacığının bloke edilmesini önler. Indication'lar için, sunucu tarafında gatt.sendResponse() çağrılmalıdır — Android istemcisinde bu otomatik olarak işlenir.
Android'de GATT ile çalışma, android.bluetooth paketinin sınıfları aracılığıyla uygulanır: BluetoothGatt (bağlantı), BluetoothGattService (servis), BluetoothGattCharacteristic (karakteristik) ve BluetoothGattDescriptor (tanımlayıcı). Bir BLE cihazına bağlantı, BluetoothDevice.connectGatt() çağrılarak başlar — bu yöntem, sonraki tüm işlemlerin gerçekleştirildiği bir BluetoothGatt döndürür. Tüm GATT geri çağrıları BluetoothGattCallback'e gelir — bu, BluetoothGatt'ın oluşturulduğu aynı iş parçacığında çağrılan bir asenkron arayüzdür. Önemli: tüm GATT işlemleri sıralı olarak gerçekleştirilmelidir — aynı BluetoothGatt üzerinde aynı anda birden fazla işlem çağırmak hatalara yol açar.
GATT bağlantı yaşam döngüsünün doğru yönetimi, BLE uygulamasının kararlılığı için kritiktir. connectGatt() çağrıldıktan sonra, uygulama STATE_CONNECTED durumuyla onConnectionStateChange() geri çağrısını bekler. Ardından sistem otomatik olarak Hizmet Keşfini başlatır ve tamamlandıktan sonra onServicesDiscovered() çağrılır. Ancak bundan sonra okuma, yazma ve abonelik işlemleri yapılabilir. İşiniz bittiğinde, her zaman onDestroy() veya onPause() içinde gatt.close()'u çağırın — kapatılmayan GATT bağlantıları pil tüketir ve Android'de aynı cihaza yeniden bağlanmayı engelleyebilir.
// GATT aracılığıyla BLE cihazına bağlan
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) }
}
}
Bluetooth SIG, sabit 16 bitlik UUID'lere sahip düzinelerce standart GATT profili ve servisi tanımlar. En yaygın olanlar: Battery Service (UUID 180F, Battery Level karakteristiği 2A19), Heart Rate servisi (UUID 180D, Heart Rate Measurement karakteristiği 2A37), Device Information servisi (UUID 180A, Manufacturer Name ve Serial Number karakteristikleri). Standart servislerin kullanımı, farklı üreticilerin cihazları arasında uyumluluğu garanti eder — Heart Rate servisine sahip herhangi bir fitness bilekliği, onu destekleyen herhangi bir Android uygulamasıyla çalışmalıdır.
Standart servisler görevi kapsamıyorsa, geliştirici 128 bitlik UUID'lerle özel GATT servisleri oluşturabilir. Özel bir servis tasarlarken şunları yapmanız gerekir: karakteristiklerin mantıksal bir grubunu tanımlayın (örneğin, “Kilit Kontrol Servisi”), her karakteristiğe doğru özellikleri (Read, Write, Notify) atayın, Characteristic Presentation Format tanımlayıcısı aracılığıyla izin verilen değerleri ve ölçüm birimlerini tanımlayın. Karmaşık protokoller için, Write özelliğine sahip bir Command karakteristiği ve Notify özelliğine sahip bir Status karakteristiği eklenmesi önerilir — bu, endüstriyel BLE uygulamalarında benimsenen Command/Status modelini izler.
// Özel GATT servisi oluştur (Android GATT Sunucusu olarak)
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
}
Sıkça Sorulan Sorular
GATT (Generic Attribute Profile), cihazlar arasında veri alışverişi yapısını tanımlayan bir Bluetooth Low Energy profilidir. Bilgiye erişimi standartlaştırmak için gereklidir: tüm BLE cihazları verileri servisler ve karakteristikler halinde düzenleyerek herhangi bir istemcinin sensör okumalarını okumasına, cihazları kontrol etmesine ve bildirim almasına olanak tanır.
GAP, BLE cihaz keşfi ve bağlantısından sorumludur (tarama, reklam verme, bağlantı kurulumu). GATT, bağlantı sonrası veri alışverişinden sorumludur (okuma, yazma, bildirimler). GAP bağlantıdan önce çalışır, GATT sonra. Her iki profil de BLE için zorunludur, ancak farklı işlevler görür: GAP “ağ katmanı”, GATT “uygulama katmanıdır”.
Standart servisler Battery Service (180F, pil seviyesi), Heart Rate (180D, nabız), Device Information (180A, cihaz verileri) içerir. Her servis, 16 bitlik UUID'lere sahip birden çok karakteristik içerir. Geliştiriciler, belirli görevler için 128 bitlik UUID'lerle özel servisler oluşturabilir — akıllı kilit kontrolü veya fitness takipçisi veri iletimi gibi.
Android'de GATT, BluetoothGatt (bağlantı), BluetoothGattService (servis), BluetoothGattCharacteristic (karakteristik) ve BluetoothGattDescriptor (tanımlayıcı) aracılığıyla uygulanır. Bağlantı connectGatt() ile yapılır, ardından BluetoothGattCallback aracılığıyla olaylar gelir: onConnectionStateChange, onServicesDiscovered, onCharacteristicChanged (bildirimler için). Tüm GATT işlemleri sıralı olarak gerçekleştirilmelidir.
UUID (Evrensel Benzersiz Tanımlayıcı), GATT'ta bir servisi veya karakteristiği benzersiz şekilde tanımlayan 16 bit veya 128 bitlik bir tanımlayıcıdır. Standart Bluetooth SIG servisleri 16 bitlik UUID'ler kullanır (örneğin, Heart Rate için 180D). Geliştiricinin özel servisleri 128 bitlik UUID'ler kullanır (örneğin, 12345678-1234-5678-1234-56789abcdef0). UUID, istemcinin GATT Sunucusunda gerekli verileri bulmasını sağlar.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun