GATT (Generic Attribute Profile) — profil Bluetooth Low Energy (BLE) yang mendefinisikan struktur data dan aturan pertukaran informasi antar perangkat BLE. GATT dibangun di atas Attribute Protocol (ATT) dan mengatur data dalam hierarki: layanan (services), karakteristik (characteristics), dan deskriptor (descriptors). Menurut data Bluetooth SIG (2025), profil GATT digunakan di 98% dari semua aplikasi BLE — dari pelacak kebugaran hingga kunci pintar dan sensor medis.
Poin utama
GATT (Generic Attribute Profile) — adalah profil Bluetooth Low Energy (BLE) yang mendefinisikan bagaimana dua perangkat BLE bertukar data melalui Attribute Protocol (ATT). GATT menstandarisasi struktur data: semua data diorganisir dalam hierarki “layanan → karakteristik → deskriptor”. Profil ini diperkenalkan dalam spesifikasi Bluetooth 4.0 (2010) bersama dengan BLE dan sejak itu tetap menjadi mekanisme utama transmisi data untuk perangkat Bluetooth hemat energi. Tidak seperti Bluetooth klasik, di mana data ditransmisikan melalui port serial (SPP), GATT menyediakan akses terstruktur ke data melalui operasi baca, tulis, dan notifikasi.
Tumpukan BLE terdiri dari beberapa lapisan: Physical Layer (radio), Link Layer (manajemen koneksi), L2CAP (transmisi saluran logis), ATT (Attribute Protocol — akses ke atribut) dan GATT (profil berbasis ATT). GATT adalah lapisan tertinggi yang digunakan oleh pengembang aplikasi. ATT di bawahnya menyediakan operasi dasar: membaca, menulis, notifikasi, dan indikasi atribut. GATT menambahkan semantik: mendefinisikan apa itu layanan, karakteristik, bagaimana mereka dikelompokkan, dan aturan apa yang berlaku saat membaca dan menulisnya. Menurut Bluetooth Core Specification 5.4 (2023), GATT mendukung hingga 65.535 atribut (layanan + karakteristik + deskriptor) pada satu perangkat.
Hierarki GATT terdiri dari tiga tingkat. Layanan (Service) — grup logis karakteristik yang menyelesaikan satu tugas (misalnya, “Layanan Baterai” atau “Layanan Heart Rate”). Karakteristik (Characteristic) — unit data dengan tipe yang diketahui: level pengisian saat ini, pembacaan sensor, status sakelar. Setiap karakteristik memiliki nilai (value) dan satu atau lebih deskriptor (Descriptors) yang mendeskripsikan metadata: satuan ukuran, pengaturan notifikasi, rentang nilai. UUID (Universally Unique Identifier) secara unik mengidentifikasi setiap layanan dan setiap karakteristik.
GATT mendukung empat jenis operasi untuk interaksi dengan karakteristik. Read — klien meminta nilai saat ini dari karakteristik dari server. Write — klien mengirim nilai baru ke server. Notify — server mengirim nilai ke klien tanpa konfirmasi (cara lebih cepat tetapi kurang andal). Indicate — server mengirim nilai dengan konfirmasi penerimaan (lebih andal tetapi lebih lambat). Pengembang memilih jenis tergantung pada skenario: untuk pembacaan sensor denyut nadi, Notify sudah cukup; untuk menulis konfigurasi kunci pintar — Write dengan konfirmasi.
// Struktur data GATT di kode Android
data class BleService(
val uuid: UUID,
val characteristics: List<BleCharacteristic>
)
data class BleCharacteristic(
val uuid: UUID,
val properties: Int, // BACA, TULIS, NOTIFIKASI, INDIKASI
val descriptors: List<BleDescriptor>,
var value: ByteArray?
)
Dalam spesifikasi BLE ditetapkan dua profil utama: GAP (Generic Access Profile) dan GATT (Generic Attribute Profile). GAP bertanggung jawab untuk deteksi perangkat, pembentukan koneksi, dan manajemen visibilitas — ini adalah “lapisan jaringan” BLE. GATT — untuk pertukaran data setelah koneksi terbentuk, yaitu “lapisan aplikasi”. Pengembang menggunakan GAP untuk memindai dan terhubung ke perangkat, dan GATT — untuk membaca, menulis, dan menerima notifikasi dari perangkat yang terhubung.
| Karakteristik | GAP | GATT |
|---|---|---|
| Tujuan | Deteksi dan koneksi | Pertukaran data |
| Peran | Central / Peripheral | Client / Server |
| Protokol | HCI, Link Layer | ATT (Attribute Protocol) |
| Tahap | Sebelum koneksi | Setelah koneksi |
| Kelas utama | BluetoothAdapter | BluetoothGatt |
GATT mendefinisikan dua peran: GATT Server dan GATT Client. Server — perangkat yang menyediakan data (misalnya, pelacak kebugaran yang mengirimkan pembacaan denyut nadi). Klien — perangkat yang meminta data (misalnya, smartphone yang membaca pengukuran). Dalam sebagian besar skenario, aplikasi Android bertindak sebagai GATT Client, dan periferal BLE sebagai GATT Server. Namun, Android juga dapat menjadi GATT Server — misalnya, jika aplikasi meniru perangkat BLE untuk perangkat lain. Peran ditentukan pada tahap pembentukan koneksi GATT dan tidak berubah selama sesi.
Proses komunikasi GATT dimulai setelah koneksi BLE terbentuk antar perangkat. Pertama, GATT Client mendeteksi layanan di GATT Server melalui operasi Service Discovery — Android melakukannya secara otomatis saat terhubung melalui BluetoothGatt.discoverServices(). Setelah deteksi, klien menerima daftar layanan, karakteristik, dan deskriptor yang tersedia. Kemudian klien dapat membaca nilai karakteristik (Read), menulis nilai baru (Write), atau berlangganan notifikasi (Set Notify/Indicate). GATT Server dapat mengirim Notify/Indicate ke klien kapan saja setelah koneksi terbentuk.
Secara default, ukuran satu paket GATT (MTU, Maximum Transmission Unit) di BLE adalah 23 byte, di mana 3 byte adalah header ATT dan 20 byte adalah data berguna. Jika aplikasi perlu mengirim lebih banyak data (misalnya, pembaruan firmware OTA), dapat meminta peningkatan MTU hingga 517 byte melalui requestMtu() di Android. MTU yang ditingkatkan mengurangi jumlah paket yang diperlukan untuk mengirim satu blok data — alih-alih 50 paket kecil, dapat dikirim 2 paket besar, yang mengurangi konsumsi daya dan mempercepat transmisi. MTU maksimum tergantung pada versi BLE dan kemampuan chip — Bluetooth 5.0 mendukung hingga 517 byte, versi lama hingga 247 byte.
// Berlangganan notifikasi karakteristik
fun enableNotifications(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
gatt.setCharacteristicNotification(characteristic, true)
// Aktifkan 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)
}
}
Untuk menerima notifikasi dari GATT Server di Android, perlu mengimplementasikan callback BluetoothGattCallback.onCharacteristicChanged(). Dalam metode ini, aplikasi menerima nilai karakteristik yang diperbarui setiap kali server mengirim Notify atau Indicate. Untuk pemrosesan data real-time, gunakan buffer dan korutin Kotlin — ini akan mencegah memblokir thread UI saat notifikasi intensif (misalnya, 100+ pembacaan denyut nadi per detik). Pada indikasi (Indicate), selalu panggil gatt.sendResponse() di sisi server — di klien Android, ini ditangani secara otomatis.
Di Android, bekerja dengan GATT diimplementasikan melalui kelas paket android.bluetooth: BluetoothGatt (koneksi), BluetoothGattService (layanan), BluetoothGattCharacteristic (karakteristik) dan BluetoothGattDescriptor (deskriptor). Koneksi ke perangkat BLE dimulai dengan memanggil BluetoothDevice.connectGatt() — metode ini mengembalikan BluetoothGatt, yang melaluinya semua operasi selanjutnya dilakukan. Semua callback GATT datang di BluetoothGattCallback — ini adalah antarmuka asinkron yang dipanggil di thread yang sama dengan tempat BluetoothGatt dibuat. Penting: semua operasi GATT harus dilakukan secara berurutan — memanggil beberapa operasi secara bersamaan pada BluetoothGatt yang sama menyebabkan kesalahan.
Manajemen siklus hidup koneksi GATT yang benar sangat penting untuk stabilitas aplikasi BLE. Setelah memanggil connectGatt(), aplikasi menunggu callback onConnectionStateChange() dengan status STATE_CONNECTED. Kemudian sistem secara otomatis memulai Service Discovery, setelah selesai onServicesDiscovered() dipanggil. Hanya setelah itu pembacaan, penulisan, dan langganan dapat dilakukan. Setelah selesai, selalu panggil gatt.close() di onDestroy() atau onPause() — koneksi GATT yang tidak ditutup menghabiskan baterai dan dapat memblokir koneksi ulang ke perangkat yang sama di Android.
// Hubungkan ke perangkat BLE melalui 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) }
}
}
Bluetooth SIG (Special Interest Group) mendefinisikan puluhan profil dan layanan GATT standar dengan UUID 16-bit tetap. Yang paling umum: layanan Battery Service (UUID 180F, karakteristik Battery Level 2A19), layanan Heart Rate (UUID 180D, karakteristik Heart Rate Measurement 2A37), layanan Device Information (UUID 180A, karakteristik Manufacturer Name, Serial Number). Penggunaan layanan standar menjamin kompatibilitas antar perangkat dari berbagai produsen — gelang kebugaran apa pun dengan layanan Heart Rate harus berfungsi dengan aplikasi Android apa pun yang mendukungnya.
Jika layanan standar tidak mencakup tugas, pengembang dapat membuat layanan GATT sendiri dengan UUID 128-bit (UUID kustom). Saat merancang layanan kustom, perlu: mendefinisikan grup logis karakteristik (misalnya, “Layanan Manajemen Kunci”), memberikan setiap karakteristik properti yang tepat (Read, Write, Notify), menentukan nilai yang diizinkan dan satuan ukuran melalui deskriptor Characteristic Presentation Format. Untuk protokol kompleks, disarankan untuk menyertakan karakteristik Command dengan properti Write dan karakteristik Status dengan Notify dalam layanan — ini sesuai dengan pola Command/Status yang diterima dalam aplikasi BLE industri.
// Buat layanan GATT kustom (Android sebagai 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
}
Pertanyaan yang sering diajukan
GATT (Generic Attribute Profile) — adalah profil Bluetooth Low Energy yang mendefinisikan struktur pertukaran data antar perangkat. Diperlukan untuk standarisasi akses ke informasi: semua perangkat BLE mengatur data dalam layanan dan karakteristik, yang memungkinkan klien mana pun membaca pembacaan sensor, mengontrol perangkat, dan menerima notifikasi.
GAP bertanggung jawab untuk deteksi dan koneksi perangkat BLE (pemindaian, iklan, pembentukan koneksi). GATT — untuk pertukaran data setelah koneksi (baca, tulis, notifikasi). GAP bekerja sebelum koneksi, GATT — setelahnya. Kedua profil wajib untuk BLE, tetapi memiliki fungsi berbeda: GAP adalah “lapisan jaringan”, GATT adalah “lapisan aplikasi”.
Layanan standar meliputi Battery Service (180F, level baterai), Heart Rate (180D, denyut nadi), Device Information (180A, data perangkat). Setiap layanan berisi beberapa karakteristik dengan UUID 16-bit. Pengembang dapat membuat layanan kustom dengan UUID 128-bit untuk tugas spesifik — misalnya, mengontrol kunci pintar atau mengirim data pelacak kebugaran.
Di Android, GATT diimplementasikan melalui BluetoothGatt (koneksi), BluetoothGattService (layanan), BluetoothGattCharacteristic (karakteristik), dan BluetoothGattDescriptor (deskriptor). Koneksi dilakukan melalui connectGatt(), setelah itu peristiwa datang di callback BluetoothGattCallback: onConnectionStateChange, onServicesDiscovered, onCharacteristicChanged (untuk notifikasi). Semua operasi GATT harus dilakukan secara berurutan.
UUID (Universally Unique Identifier) — pengenal 16-bit atau 128-bit yang secara unik menentukan layanan atau karakteristik di GATT. Layanan standar Bluetooth SIG menggunakan UUID 16-bit (misalnya, 180D untuk Heart Rate). Layanan kustom pengembang — UUID 128-bit (misalnya, 12345678-1234-5678-1234-56789abcdef0). UUID memungkinkan klien menemukan data yang diperlukan di GATT Server.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga