
BLE di bawah mikroskop (ATTы GATTы…)
Bagian 1, ikhtisar
Sudah cukup lama sejak spesifikasi Bluetooth 4.0 pertama dirilis. Meskipun topik BLE sangat menarik, banyak pengembang masih enggan membahasnya karena kompleksitasnya. Dalam artikel saya sebelumnya, saya berfokus terutama pada level terendah—Link Layer dan Physical Layer. Hal ini memungkinkan saya menghindari konsep yang rumit dan membingungkan seperti Attribute Protocol (ATP) dan Generic Attribute Profile (GATT). Namun, tanpa memahami konsep-konsep ini, mustahil untuk mengembangkan perangkat yang kompatibel. Hari ini, saya ingin berbagi pengetahuan ini dengan Anda. Dalam artikel ini, saya akan membahas Untuk pemula, dari situs web Nordic. Jadi, mari kita mulai.
Mengapa semuanya begitu rumit?
Menurut saya, langsung terlihat jelas bahwa mengendalikan perangkat melalui ponsel pintar adalah konsep yang sangat menjanjikan dan berjangka panjang. Oleh karena itu, kami memutuskan untuk segera menyusunnya selengkap mungkin. Hal ini untuk mencegah produsen gawai mengembangkan protokol mereka sendiri yang nantinya tidak kompatibel. Hal ini menjelaskan kompleksitasnya. Sejak awal, kami berusaha memasukkan segala kemungkinan ke dalam protokol BLE. Dan apakah protokol ini akan berguna di kemudian hari atau tidak, tidaklah penting. Kami juga mempertimbangkan kemungkinan untuk memperluas daftar perangkat di masa mendatang.
Mari kita lihat gambar yang menunjukkan diagram protokol BLE. Diagram ini terdiri dari beberapa lapisan. Lapisan terendah, lapisan fisik (PHY), bertanggung jawab atas kanal radio perangkat. Lapisan Tautan (LL) berisi seluruh urutan byte dalam pesan yang ditransmisikan. Kita telah mempelajari lapisan ini di artikel sebelumnya. Host Controller Interface (HCI) adalah protokol untuk komunikasi antar lapisan atau chip BLE jika Controller dan Host diimplementasikan pada chip yang berbeda. Logical Link Control and Adaptation Protocol (L2CAP) bertanggung jawab atas pembentukan paket, pembingkaian, pengendalian kesalahan, dan perakitan ulang paket. Security Manager Protocol (SMP) bertanggung jawab atas enkripsi paket. Generic Access Profile (GAP) bertanggung jawab atas pertukaran data awal antar perangkat untuk menentukan "siapa adalah siapa." Pemindaian dan periklanan juga termasuk dalam profil ini. Dalam artikel ini, saya akan berfokus pada dua bagian protokol yang tersisa—GATT dan ATT. GATT merupakan superstruktur pada ATT, sehingga keduanya saling terkait erat.

Untuk menyederhanakan diskusi ini, saya ingin menggunakan sebuah analogi. Saya pernah mendengarnya di suatu tempat dan ingin mengulanginya. Bayangkan perangkat BLE sebagai rak buku dengan beberapa rak. Setiap rak mewakili topik yang berbeda. Misalnya, kita memiliki rak untuk fiksi ilmiah, matematika, dan ensiklopedia. Setiap rak berisi buku-buku tentang topik tersebut. Beberapa buku bahkan memiliki pembatas buku kertas berisi catatan. Kita juga memiliki katalog kertas kecil berisi semua buku. Jika Anda ingat perpustakaan sekolah, perpustakaan itu seperti laci sempit berisi kartu-kartu kertas. Dalam analogi ini, rak buku adalah profil perangkat kita. Rak adalah layanan, buku adalah karakteristik, dan katalog adalah tabel atribut. Pembatas buku dalam buku adalah deskriptor, yang akan saya bahas lebih detail nanti.
Siapa pun yang pernah mengembangkan perangkat tahu bahwa banyak proyek berisi potongan kode yang serupa. Hal ini karena banyak perangkat memiliki fungsi yang serupa. Misalnya, jika perangkat bertenaga baterai, masalah pengisian daya dan pemantauan levelnya akan sama. Hal yang sama berlaku untuk sensor. Pada dasarnya, pendekatan berorientasi objek untuk pemrograman "menyediakan kemampuan untuk membuat objek yang menggabungkan properti dan perilaku menjadi kesatuan mandiri yang kemudian dapat digunakan kembali."Menurut saya, BLE mencoba pendekatan serupa. Bluetooth Special Interest Group (SIG) mengembangkan profil. Perangkat dari produsen berbeda dengan profil yang identik seharusnya dapat bekerja sama dengan lancar. Profil, pada gilirannya, terdiri dari layanan, dan layanan terdiri dari karakteristik yang dilengkapi dengan deskriptor. Secara umum, tampilannya mungkin seperti ini:

Sebagai contoh, mari kita lihat diagram profil untuk monitor detak jantung (gelang kebugaran). Diagram ini terdiri dari dua layanan dan beberapa fitur. Hierarki profil langsung terlihat jelas dari diagram ini. Fitur titik pemeriksaan mengatur ulang jumlah total pengeluaran kalori menjadi nol.
1. Layanan detak jantung mencakup tiga karakteristik (0x180D):
a) Karakteristik denyut jantung wajib (0x2A37)
b) Parameter Posisi Sensor Tubuh Opsional (0x2A38)
c) Karakteristik kondisional titik kontrol detak jantung (0x2A39)
2. Layanan Pemeliharaan Baterai (0x180F):
a) Karakteristik Level Baterai Wajib (0x2A19)
UUID
Agar dapat mengakses elemen profil (layanan, karakteristik, dan deskriptor) secara unik, semuanya perlu diberi nomor. Untuk tujuan ini, konsep Universally Unique ID (UUID) diperkenalkan. UUID ditunjukkan dalam tanda kurung pada setiap baris. Dan ada satu keanehan di sini. Mereka memutuskan untuk menggunakan kode 16-bit dan 128-bit untuk UUID. Mengapa, Anda bertanya? Protokol BLE berfokus pada konservasi energi. Oleh karena itu, kode 16-bit cukup masuk akal. Kemungkinan besar tidak akan ada lebih dari 65 layanan dan karakteristik unik yang akan dibuat dalam waktu dekat. Pada titik ini, semua yang dapat dihitung sudah dihitung (ingat asal usul pepatah "Anda juga dihitung" :-)). Elemen bernomor , , и Anda dapat melihat tautannya.
Namun, saya rasa semua orang ingat kisah alamat IP 4-byte di internet. Awalnya, mereka pikir itu sudah cukup, tetapi sekarang kita masih berjuang untuk beralih ke alamat 6-byte. Untuk menghindari terulangnya kesalahan ini dan memberikan keleluasaan bagi para penggemar DIY, SIG segera memutuskan untuk memperkenalkan UUID 128-bit. Ini mengingatkan saya pada pita 433 MHz tanpa lisensi, yang diberikan kepada berbagai peretasan kanal radio. Dalam kasus kami, kami diberikan layanan 128-bit dan pengenal karakteristik. Ini berarti kami dapat menggunakan hampir semua nilai 128-bit untuk layanan dan perangkat kami. Kemungkinan semua orang menggunakan UUID yang sama sangat kecil.
Faktanya, UUID 16-bit pendek memiliki ekstensinya sendiri ke nilai 128-bit. Dalam spesifikasi, ekstensi ini disebut Bluetooth Base UUID dan memiliki nilai 00000000-0000-1000-8000-00805F9B34FB. Jika, misalnya, UUID 16-bit suatu atribut memiliki nilai 0x1234, maka UUID 128-bit yang setara akan memiliki nilai 00001234-0000-1000-8000-00805F9B34FB. Rumus yang sesuai bahkan disediakan:
Nilai 128_bit = nilai 16_bit * 2^96 + UUID_Basis_Bluetooth
Saya tidak tahu dari mana angka ajaib ini berasal. Jika ada pembaca yang tahu, silakan tulis di kolom komentar (pengguna dengan nama panggilan Sinopteek sudah melakukannya. Lihat komentar). Untuk membuat UUID 128-bit, pada prinsipnya, Anda dapat menggunakan , yang akan melakukannya untuk Anda.
ATT dan GATT…
Sekarang tiba bagian yang menyenangkan. Perlu saya ingatkan bahwa ATT didasarkan pada hubungan klien-server. Kita sekarang sedang melihat perangkat server. Perangkat ini berisi informasi seperti nilai sensor, status sakelar lampu, data lokasi, dan sebagainya. Setelah semua "peserta dalam parade kita" diberi nomor, kita perlu menyimpannya di memori perangkat. Untuk melakukannya, kita menempatkannya dalam tabel yang disebut tabel atribut. Ingat ini baik-baik. Inilah inti dari BLE. Inilah yang akan kita bahas lebih lanjut. Mulai sekarang, kita akan menyebut setiap baris sebagai atribut. Tabel ini terletak jauh di dalam tumpukan dan, biasanya, kita tidak memiliki akses langsung ke sana. Kita menginisialisasi dan mengaksesnya, tetapi apa yang terjadi di dalamnya masih menjadi misteri.
Mari kita lihat gambar dari spesifikasi, tetapi sebelumnya, saya ingin menunjukkan kebingungan umum dalam istilah, khususnya deskriptor. Peran deskriptor adalah untuk melengkapi deskripsi suatu karakteristik. Deskriptor digunakan ketika kapabilitasnya perlu diperluas. Deskriptor juga merupakan atribut, dan, seperti layanan dan karakteristik, terletak di tabel atribut. Kita akan membahasnya secara detail di bagian kedua artikel ini. Namun, terkadang deskriptor digunakan untuk merujuk ke nomor baris dalam tabel atribut. Hal ini perlu diingat. Untuk menghindari kebingungan, kita akan menggunakan istilah "penunjuk atribut" untuk tujuan ini.

Jadi atribut adalah nilai diskrit yang memiliki properti berikut yang terkait dengannya:
1. Pegangan atribut adalah indeks tabel yang sesuai dengan suatu atribut.
2. Atribut Type adalah UUID yang menjelaskan tipenya
3. Nilai Atribut adalah data yang diindeks oleh penunjuk atribut.
4. Izin Atribut adalah bagian atribut yang tidak dapat dibaca atau ditulis menggunakan protokol atribut.
Bagaimana kita memahami semua ini? Indeks suatu atribut, secara garis besar, adalah nomornya di tabel kita.
Hal ini memungkinkan klien untuk merujuk suatu atribut dalam permintaan baca atau tulis. Kita dapat menomori baris (atribut) kita dari 0x0001 hingga 0xFFFF. Dalam metafora rak buku kita, ini adalah nomor kartu dalam katalog kertas. Demikian pula, seperti dalam katalog perpustakaan, kartu-kartu disusun dalam urutan menaik. Nomor setiap baris berikutnya harus lebih banyak daripada yang sebelumnya. Sama seperti di perpustakaan, kartu terkadang hilang, begitu pula celah dalam nomor baris kita. Hal ini dapat diterima. Yang penting, kartu-kartu tersebut disusun dalam urutan menaik.
Tipe atribut menentukan apa yang diwakili oleh atribut tersebut. Mirip dengan bahasa C,
Jika ada variabel Boolean, numerik, dan string, di sini pun sama. Berdasarkan tipe atributnya, kita tahu
Apa yang kita bahas di sini dan bagaimana kita harus melanjutkan dengan atribut ini? Di bawah ini, kita akan membahas beberapa jenis atribut spesifik. Misalnya, "deklarasi layanan" (0x2800), "deklarasi karakteristik" (0x2803), dan "deklarasi deskriptor" (0x2902).
Nilai suatu atribut adalah nilai aktualnya, mohon maaf atas tautologinya. Jika tipe atributnya berupa string, nilainya bisa berupa, misalnya, slogan "Hello World!!!" Jika tipe atributnya adalah "deklarasi layanan", nilainya adalah layanan itu sendiri. Terkadang, nilainya berupa informasi tentang lokasi atribut lain dan propertinya.
Izin atribut memungkinkan server menentukan apakah akses baca atau tulis diizinkan.
Harap dicatat bahwa izin ini hanya berlaku untuk nilai atribut, bukan untuk penunjuk, tipe, atau bidang izin itu sendiri. Jadi, jika suatu atribut dapat ditulis, kita dapat mengubah, misalnya, string "Halo Dunia!!!" menjadi "Selamat pagi." Namun, kita tidak dapat melarang penulisan baris baru atau mengubah tipe atribut dan menetapkan string tersebut sebagai "deklarasi layanan." Ketika klien mengakses server, klien meminta atributnya. Hal ini memungkinkan klien untuk menentukan apa yang dapat disediakan server, meskipun membaca dan menulis nilai tidak diperlukan.
Seperti apa bentuknya
Konsep GATT adalah mengelompokkan atribut-atribut dalam tabel atribut dalam urutan yang sangat spesifik dan logis. Mari kita lihat lebih dekat profil detak jantung di bawah ini. Kolom paling kiri tabel ini bersifat opsional. Kolom ini hanya menjelaskan baris (atribut) ini. Semua kolom lainnya sudah familiar.

Di bagian atas setiap grup, kita selalu memiliki atribut deklarasi layanan. Tipenya selalu 0x2800, dan indeksnya bergantung pada jumlah atribut yang sudah ada di tabel. Izinnya selalu hanya-baca, tanpa autentikasi atau otorisasi apa pun. Kita akan membahas konsep-konsep ini nanti. Nilainya adalah UUID lain yang mengidentifikasi layanan tersebut. Dalam tabel, nilainya adalah 0x180D, yang didefinisikan oleh Bluetooth SIG sebagai layanan detak jantung.
Setelah deklarasi layanan terdapat deklarasi karakteristik. Bentuknya mirip dengan deklarasi layanan. UUID-nya selalu 0x2803, dan izinnya juga selalu hanya-baca, tanpa autentikasi atau otorisasi apa pun. Mari kita lihat kolom Nilai Atribut, yang berisi beberapa data. Kolom ini selalu berisi penunjuk, UUID, dan serangkaian properti. Ketiga elemen ini menjelaskan deklarasi nilai karakteristik selanjutnya. Penunjuk tersebut secara alami menunjukkan lokasi deklarasi nilai karakteristik dalam tabel atribut. UUID menjelaskan jenis informasi atau nilai yang dapat kita harapkan—misalnya, nilai suhu, kondisi sakelar lampu, atau nilai arbitrer lainnya. Terakhir, properti menjelaskan cara berinteraksi dengan nilai karakteristik.
Ada jebakan lain yang menanti kita di sini. Ini berkaitan dengan izin atribut dan properti karakteristik. Mari kita lihat gambar properti bitfield dari spesifikasi.

Seperti yang Anda lihat, terdapat juga kolom di sini yang menyediakan akses baca dan tulis. Anda mungkin bertanya-tanya mengapa kami memiliki izin baca/tulis untuk atribut dan properti tersebut.
Izin baca/tulis untuk nilai karakteristik? Bukankah seharusnya selalu sama? Masalahnya, properti untuk nilai karakteristik pada dasarnya hanyalah rekomendasi klien yang digunakan dalam GATT dan lapisan aplikasi. Properti tersebut hanyalah petunjuk tentang apa yang dapat diharapkan klien dari atribut deklarasi karakteristik. Mari kita bahas lebih lanjut. Jenis izin apa saja yang dimiliki suatu atribut?
1. Izin akses:
- membaca
— rekaman
— membaca dan menulis
2. Izin otentikasi:
— diperlukan autentikasi
- tidak diperlukan otentikasi
3. Izin otorisasi:
- diperlukan otorisasi
- tidak diperlukan otorisasi
Perbedaan utama antara izin atribut dan properti karakteristik adalah bahwa izin atribut bersifat khusus server, sedangkan izin karakteristik bersifat khusus klien. Server mungkin mengizinkan pembacaan nilai karakteristik, tetapi tetap memerlukan autentikasi atau otorisasi. Oleh karena itu, ketika klien meminta properti karakteristik, kita akan melihat bahwa pembacaan diizinkan. Namun, mencoba membacanya akan mengakibatkan kesalahan. Oleh karena itu, kita dapat dengan yakin mengatakan bahwa izin lebih diutamakan daripada properti. Kita, di sisi klien, tidak memiliki cara untuk mengetahui izin apa yang dimiliki suatu atribut.
Deskriptor
Mari kembali ke tabel kita. Setelah mendeklarasikan nilai karakteristik, deklarasi atribut berikut dapat dilakukan:
1. Pengumuman karakteristik baru (mungkin ada beberapa karakteristik dalam suatu layanan)
2. Deklarasi layanan baru (mungkin ada banyak di tabel)
3. Deklarasi deskriptor
Dalam kasus karakteristik pengukuran detak jantung di tabel kami, deklarasi nilai karakteristik disertai dengan deklarasi deskriptor. Deskriptor adalah atribut yang berisi informasi tambahan tentang karakteristik tersebut. Ada beberapa jenis deskriptor, yang akan kita bahas secara rinci di bagian kedua artikel ini. Untuk saat ini, kita hanya akan menyentuh Deskriptor Konfigurasi Karakteristik Klien (CCCD). Ini memiliki UUID 0x2902. Dengan menggunakan deskriptor ini, klien dapat mengaktifkan indikasi atau notifikasi di server. Perbedaan di antara keduanya tidak kentara, tetapi tetap ada. Notifikasi tidak memerlukan pengakuan penerimaan dari klien. Indikasi memerlukannya, meskipun terjadi pada tingkat GATT, bukan tingkat aplikasi. Mengapa demikian, Anda bertanya? Sayangnya, saya tidak tahu. Saya hanya akan mengatakan bahwa spesialis Nordik merekomendasikan penggunaan notifikasi. Selain itu, pemeriksaan integritas paket (menggunakan CRC) terjadi pada kedua kasus.
Kesimpulan
Di akhir artikel, saya ingin menyampaikan hal berikut. Tabel terakhir agak membingungkan. Namun, saya berhenti di situ karena sudah ada di , yang saya andalkan. Di bagian kedua artikel ini, saya bermaksud membahas lebih dalam spesifikasi Bluetooth 4.0. Diagram dan ilustrasi yang lebih akurat menanti kita di sana. Di bagian ketiga, saya ingin menganalisis log yang diperoleh dari salah satu gawai menggunakan Wireshark dan melihat semua teori yang telah kita pelajari dalam praktiknya.
Karyawan Grup Perusahaan
Vladimir Pechersky
Sumber: www.habr.com
