Deskriptor — adalah atribut pembantu dari karakteristik BLE yang menyediakan metadata atau konfigurasi untuk nilainya. Bluetooth Core Specification 5.4 mendefinisikan deskriptor sebagai bagian tak terpisahkan dari profil GATT: mereka mendeskripsikan satuan ukuran, rentang nilai, nama teks, dan mengelola langganan notifikasi. Deskriptor yang paling terkenal adalah Client Characteristic Configuration Descriptor (CCCD, 0x2902), yang memungkinkan Central berlangganan notifikasi dari karakteristik. Menurut Bluetooth SIG, ada 8 deskriptor standar yang dispesifikasikan, dan deskriptor kustom dapat dibuat oleh pengembang untuk metadata tambahan apa pun.
Poin utama
Deskriptor — adalah atribut protokol GATT yang melekat pada karakteristik dan memberikan informasi tambahan tentang nilai atau cara penggunaannya. Dalam terminologi GATT, karakteristik adalah data, dan deskriptor adalah metadata dari data tersebut.
Setiap karakteristik dapat memiliki nol atau lebih deskriptor. Deskriptor didefinisikan sebagai atribut terpisah dalam tabel GATT dan memiliki UUID 16-bit sendiri di ruang Bluetooth SIG. Deskriptor tidak dapat berdiri sendiri — mereka selalu terikat pada karakteristik tertentu.
Menurut Bluetooth Core Specification 5.4 (2023), deskriptor dibagi menjadi dua kategori: standar (ditentukan oleh Bluetooth SIG) dan kustom (ditentukan oleh pengembang). Deskriptor standar memiliki UUID dalam rentang 0x2900–0x2908 dan menjalankan fungsi yang ditentukan secara ketat. Deskriptor kustom menggunakan UUID 128-bit, mirip dengan layanan dan karakteristik kustom.
Deskriptor adalah mekanisme kunci untuk konfigurasi perilaku koneksi BLE. Tanpa CCCD (0x2902) tidak mungkin berlangganan notifikasi, tanpa Presentation Format (0x2904) Central tidak akan tahu cara menafsirkan byte mentah karakteristik.
CCCD dengan UUID 0x2902 adalah deskriptor terpenting dan paling banyak digunakan di BLE. Ia mengelola langganan Central ke notifikasi (Notify) dan notifikasi terkonfirmasi (Indicate) dari karakteristik. Tanpa penulisan ke CCCD, karakteristik tidak akan mengirim notifikasi, bahkan jika ia memiliki properti Notify.
CCCD adalah nilai 16-bit di mana bit paling rendah (0x0001) mengaktifkan Notify, dan bit kedua (0x0002) mengaktifkan Indicate. Central menulis nilai yang diinginkan ke CCCD, dengan demikian berlangganan notifikasi. Jika Central menulis 0x0000 — langganan dibatalkan.
Mekanisme kerja CCCD adalah sebagai berikut: ketika Central mendeteksi karakteristik dengan dukungan Notify, ia menemukan deskriptor CCCD-nya dan menulis 0x0001. Setelah itu, setiap kali Peripheral memperbarui nilai karakteristik, nilai tersebut secara otomatis dikirim ke Central yang berlangganan melalui Handle Value Notification (tanpa permintaan dari Central).
Menurut Apple Core Bluetooth Programming Guide, CCCD dikelola secara otomatis oleh sistem saat setNotifyValue dipanggil untuk karakteristik. Pengembang tidak perlu mencari dan menulis CCCD secara manual — Core Bluetooth melakukannya secara otomatis saat aktivasi notifikasi.
Di iOS, langganan dilakukan melalui metode setNotifyValue pada objek CBPeripheral.
import CoreBluetooth
// Berlangganan notifikasi karakteristik
peripheral.setNotifyValue(true, for: characteristic)
// Delegate menerima nilai yang diperbarui
func peripheral(
_ peripheral: CBPeripheral,
didUpdateValueFor characteristic: CBCharacteristic,
error: Error?
) {
// characteristic.value memiliki data baru
guard let data = characteristic.value else { return }
}
Di Android, langganan notifikasi dilakukan melalui BluetoothGatt.setCharacteristicNotification. Pengembang juga harus menulis nilai 0x0001 ke CCCD secara manual.
import android.bluetooth.*;
// Aktifkan notifikasi
bluetoothGatt.setCharacteristicNotification(characteristic, true);
// Tulis 0x0001 ke CCCD
BluetoothGattDescriptor descriptor = characteristic
.getDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);
Bluetooth SIG telah mendefinisikan 8 deskriptor standar untuk tugas konfigurasi karakteristik yang umum. Setiap deskriptor memiliki UUID dan format nilai yang ditentukan secara ketat.
| UUID | Nama deskriptor | Tujuan | Tipe nilai |
|---|---|---|---|
| 0x2900 | Characteristic Extended Properties | Properti tambahan karakteristik | uint16 (mask bit) |
| 0x2901 | Characteristic User Description | Nama teks karakteristik | String UTF-8 |
| 0x2902 | Client Characteristic Configuration | Mengelola notifikasi | uint16 |
| 0x2903 | Server Characteristic Configuration | Konfigurasi server untuk broadcast | uint16 |
| 0x2904 | Characteristic Presentation Format | Format presentasi data | Struktur (7 byte) |
| 0x2905 | Characteristic Aggregate Format | Menggabungkan beberapa karakteristik | Daftar UUID |
| 0x2906 | Valid Range | Rentang nilai yang diizinkan | uint16 × 2 (min, max) |
| 0x2907 | External Report Reference | Referensi ke laporan eksternal | uint16 |
| 0x2908 | Report Reference | Referensi ke laporan internal | uint8 + uint16 |
Characteristic User Description (0x2901) sangat berguna untuk UI: ia berisi nama karakteristik yang dapat dibaca manusia yang dapat ditampilkan di antarmuka aplikasi. Misalnya, karakteristik Battery Level dapat memiliki deskriptor User Description dengan nilai “Tingkat pengisian baterai”.
Characteristic Presentation Format (0x2904) berisi informasi tentang cara menafsirkan nilai karakteristik: format (uint8, uint16, float), eksponen, satuan ukuran (melalui UUID dari registri Bluetooth SIG), ruang nama, dan deskripsi. Misalnya, suhu bisa int16 dengan eksponen -2 (nilai pembagian 0.01°C) dan satuan ukuran “derajat Celcius”.
Akses ke deskriptor berbeda di iOS dan Android. Core Bluetooth secara otomatis mengelola CCCD saat mengaktifkan notifikasi, sedangkan Android memerlukan penulisan manual nilai ke deskriptor. Mari kita lihat kedua pendekatan.
Di iOS, pengembang biasanya tidak berinteraksi langsung dengan deskriptor. Core Bluetooth secara otomatis menemukan CCCD dan menulis nilai yang diperlukan saat setNotifyValue dipanggil. Untuk membaca deskriptor, digunakan metode discoverDescriptors.
// Temukan deskriptor
peripheral.discoverDescriptors(for: characteristic)
// Baca nilai User Description
func peripheral(
_ peripheral: CBPeripheral,
didDiscoverDescriptorsFor characteristic: CBCharacteristic,
error: Error?
) {
for descriptor in characteristic.descriptors ?? [] {
if descriptor.uuid == CBUUID("2901") {
peripheral.readValue(for: descriptor)
}
}
}
Di Android, pengembang harus menemukan sendiri deskriptor CCCD karakteristik dan menulis nilai untuk mengaktifkan notifikasi. Ini adalah langkah tambahan dibandingkan dengan iOS.
// Baca nilai deskriptor User Description
BluetoothGattDescriptor userDesc = characteristic
.getDescriptor(
UUID.fromString("00002901-0000-1000-8000-00805F9B34FB")
);
if (userDesc != null) {
bluetoothGatt.readDescriptor(userDesc);
}
Deskriptor kustom digunakan ketika deskriptor standar Bluetooth SIG tidak mencukupi. Misalnya, produsen sensor medis dapat menambahkan deskriptor dengan informasi tentang kalibrasi sensor atau deskriptor dengan log kesalahan.
Deskriptor kustom dibuat dengan UUID 128-bit, seperti karakteristik kustom. Di sisi Peripheral, pengembang menambahkannya ke karakteristik melalui API yang sesuai. Di sisi Central, deskriptor terdeteksi secara otomatis saat discoverDescriptors dipanggil.
Saat membuat deskriptor kustom, patuhi aturan: panjang nilai harus sesuai dengan tipe data yang diharapkan, hak akses (read/write) harus ditentukan secara eksplisit. Jangan gunakan UUID dari rentang deskriptor standar Bluetooth SIG (0x2900–0x2908) untuk tujuan kustom.
Karakteristik dan deskriptor — ini adalah tingkat atribut GATT yang berbeda. Karakteristik adalah titik data, dan deskriptor adalah metadata atau konfigurasinya. Perbedaan terlihat dalam beberapa aspek: tujuan, UUID, dan aturan akses.
Karakteristik memiliki deklarasi wajib (declaration) yang selalu ada dalam tabel GATT. Deskriptor bersifat opsional — karakteristik mungkin tidak memiliki deskriptor. Karakteristik dapat dibaca, ditulis, atau mengirim notifikasi secara independen. Deskriptor selalu terikat pada karakteristik dan tidak ada secara terpisah.
Menurut Bluetooth Core Specification 5.4, dalam tabel GATT urutan atribut adalah sebagai berikut: deklarasi layanan, deklarasi karakteristik, nilai karakteristik, deskriptor karakteristik (jika ada), kemudian layanan berikutnya. Urutan ini wajib untuk operasi klien GATT yang benar.
Pertanyaan yang sering diajukan
CCCD diperlukan untuk mengelola langganan: properti Notify hanya mengatakan bahwa karakteristik dapat mengirim notifikasi, tetapi tidak mengaktifkannya. Central harus berlangganan secara eksplisit dengan menulis 0x0001 ke CCCD. Ini mencegah pengiriman data yang tidak diinginkan ke Central yang tidak siap.
Spesifikasi tidak membatasi jumlah deskriptor. Dalam praktiknya, setiap karakteristik biasanya memiliki 1–3 deskriptor: CCCD (untuk karakteristik dengan Notify/Indicate), opsional User Description dan Presentation Format. Terlalu banyak deskriptor meningkatkan ukuran tabel GATT.
Dalam kebanyakan kasus tidak. Core Bluetooth di iOS dan Android secara otomatis menambahkan CCCD ke karakteristik yang memiliki properti Notify atau Indicate. Deskriptor kustom dibuat secara manual hanya untuk metadata spesifik.
Tidak, CCCD memiliki format (uint16) dan tujuan yang ditentukan secara ketat — mengelola notifikasi. Menulis nilai lain melanggar spesifikasi Bluetooth dan dapat menyebabkan langganan tidak berfungsi. Untuk data kustom, gunakan deskriptor kustom dengan UUID 128-bit.
User Description berisi nama karakteristik yang dapat dibaca manusia — misalnya, “Suhu casing” alih-alih UUID 0x2A6E. Aplikasi dapat menampilkan nama ini di antarmuka, membuat interaksi dengan perangkat BLE dapat dipahami oleh pengguna tanpa string yang dikodekan secara keras.
Kesimpulan
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