Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Artikel ini menunjukkan cara menggunakan API Klien Bluetooth Generic Attribute (GATT) untuk aplikasi Windows.
Important
Anda harus mendeklarasikan kemampuan "bluetooth" di Package.appxmanifest.
<Capabilities> <DeviceCapability Name="bluetooth" /> </Capabilities>
Overview
Anda dapat menggunakan API di Windows. Devices.Bluetooth.GenericAttributeProfile namespace untuk mengakses perangkat Bluetooth LE. Perangkat BLUETOOTH LE mengekspos fungsionalitasnya melalui kumpulan:
- Layanan
- Karakteristik
- Deskriptor
Layanan menentukan kontrak fungsional perangkat LE dan berisi kumpulan karakteristik yang menentukan layanan. Karakteristik tersebut, pada gilirannya, berisi deskriptor yang menggambarkan karakteristiknya. 3 istilah ini secara umum dikenal sebagai atribut perangkat.
API Bluetooth LE GATT menyediakan objek dan fungsi, alih-alih akses ke transport mentah. GATT API juga memungkinkan Anda bekerja dengan perangkat Bluetooth LE dengan kemampuan untuk melakukan tugas-tugas berikut:
- Melakukan penemuan atribut
- Membaca dan menulis nilai atribut
- Mendaftarkan panggilan balik untuk peristiwa Characteristic ValueChanged
Untuk membuat implementasi yang berguna, Anda harus memiliki pengetahuan sebelumnya tentang layanan GATT dan karakteristik yang ingin dikonsumsi aplikasi dan untuk memproses nilai karakteristik tertentu sedih sehingga data biner yang disediakan oleh API diubah menjadi data yang berguna sebelum disajikan kepada pengguna. API GATT Bluetooth hanya mengekspos primitif dasar yang diperlukan untuk berkomunikasi dengan perangkat BLUETOOTH LE. Untuk menginterpretasikan data, profil aplikasi harus ditentukan, baik oleh profil standar Bluetooth SIG, atau profil kustom yang diterapkan oleh vendor perangkat. Profil membuat kontrak pengikatan antara aplikasi dan perangkat, tentang apa yang diwakili data yang ditukar dan cara menafsirkannya.
Untuk kenyamanan, Bluetooth SIG mempertahankan daftar profil publik yang tersedia.
Mencari perangkat di sekitar
Ada dua metode utama untuk mencari perangkat di sekitar:
- DeviceWatcher di Windows. Devices.Enumeration
- BluetoothLEAdvertisementWatcher di Windows.Devices.Bluetooth.Advertisement
Metode ke-2 dibahas panjang lebar dalam dokumentasi Iklan sehingga tidak akan banyak dibahas di sini tetapi ide dasarnya adalah menemukan alamat Bluetooth perangkat terdekat yang memenuhi Filter Iklan tertentu. Setelah memiliki alamat, Anda dapat memanggil BluetoothLEDevice.FromBluetoothAddressAsync untuk mendapatkan referensi ke perangkat.
Sekarang, kembali ke metode DeviceWatcher. Perangkat BLUETOOTH LE sama seperti perangkat lain di Windows dan dapat dikueri menggunakan API Enumeration. Gunakan kelas DeviceWatcher dan berikan string kueri yang menentukan perangkat yang akan dicari:
// Query for extra properties you want returned
string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" };
DeviceWatcher deviceWatcher =
DeviceInformation.CreateWatcher(
BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),
requestedProperties,
DeviceInformationKind.AssociationEndpoint);
// Register event handlers before starting the watcher.
// Added, Updated and Removed are required to get all nearby devices
deviceWatcher.Added += DeviceWatcher_Added;
deviceWatcher.Updated += DeviceWatcher_Updated;
deviceWatcher.Removed += DeviceWatcher_Removed;
// EnumerationCompleted and Stopped are optional to implement.
deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;
deviceWatcher.Stopped += DeviceWatcher_Stopped;
// Start the watcher.
deviceWatcher.Start();
Setelah memulai DeviceWatcher, Anda akan menerima DeviceInformation untuk setiap perangkat yang memenuhi kueri di handler untuk peristiwa Tambahkan untuk perangkat yang dimaksud. Untuk melihat lebih rinci tentang DeviceWatcher, lihat sampel lengkap on Github.
Menyambungkan ke perangkat
Setelah perangkat yang diinginkan ditemukan, gunakan DeviceInformation.Id untuk mendapatkan objek Perangkat LE Bluetooth untuk perangkat yang dimaksud:
private async Task ConnectDevice(DeviceInformation deviceInfo)
{
// Note: BluetoothLEDevice.FromIdAsync must be called from a UI thread because it may prompt for consent.
BluetoothLEDevice bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync(deviceInfo.Id);
// ...
}
Di sisi lain, melepas semua referensi ke objek BluetoothLEDevice untuk suatu perangkat (dan jika tidak ada aplikasi lain di sistem yang memiliki referensi ke perangkat tersebut) akan memicu pemutusan sambungan otomatis setelah jeda waktu singkat.
bluetoothLeDevice.Dispose();
Jika aplikasi perlu mengakses perangkat lagi, cukup buat ulang objek perangkat dan mengakses karakteristik (dibahas di bagian berikutnya) akan memicu OS untuk terhubung kembali jika perlu. Jika perangkat berada di dekatnya, Anda akan mendapatkan akses ke perangkat jika tidak, perangkat akan kembali dengan kesalahan DeviceUnreachable.
Note
Membuat objek BluetoothLEDevice dengan memanggil metode ini saja tidak (harus) memulai koneksi. Untuk memulai koneksi, atur GattSession.MaintainConnection ke true, atau panggil metode penemuan layanan yang tidak di-cache di BluetoothLEDevice, atau lakukan operasi baca/tulis terhadap perangkat.
- Jika GattSession.MaintainConnection diatur ke true, maka sistem menunggu tanpa batas waktu untuk koneksi, dan akan terhubung ketika perangkat tersedia. Tidak ada yang perlu ditunggu oleh aplikasi Anda, karena GattSession.MaintainConnection adalah properti .
- Untuk penemuan layanan dan operasi baca/tulis di GATT, sistem menunggu waktu terbatas tetapi variabel. Apa pun dari seketika hingga hitungan menit. Faktor-faktornya mencakup trafik pada stack, dan seberapa lama permintaan tersebut mengantre. Jika tidak ada permintaan lain yang tertunda, dan perangkat jarak jauh tidak dapat dijangkau, maka sistem akan menunggu selama tujuh (7) detik sebelum waktu habis. Jika ada permintaan lain yang tertunda, maka setiap permintaan dalam antrean dapat memakan waktu tujuh (7) detik untuk diproses, jadi semakin lanjut permintaan Anda ke bagian belakang antrean, semakin lama Anda akan menunggu.
Saat ini, Anda tidak dapat membatalkan proses koneksi.
Menghitung layanan dan karakteristik yang didukung
Sekarang setelah Anda memiliki objek BluetoothLEDevice, langkah selanjutnya adalah menemukan data apa yang diekspos perangkat. Langkah pertama untuk melakukan ini adalah mengkueri layanan:
GattDeviceServicesResult result = await bluetoothLeDevice.GetGattServicesAsync();
if (result.Status == GattCommunicationStatus.Success)
{
var services = result.Services;
// ...
}
Setelah layanan menarik diidentifikasi, langkah selanjutnya adalah mengkueri karakteristik.
GattCharacteristicsResult result = await service.GetCharacteristicsAsync();
if (result.Status == GattCommunicationStatus.Success)
{
var characteristics = result.Characteristics;
// ...
}
OS mengembalikan daftar objek ReadOnly GattCharacteristic yang kemudian dapat Anda operasikan.
Lakukan operasi Baca/Tulis pada sebuah karakteristik
Karakteristiknya adalah unit dasar komunikasi berbasis GATT. Ini berisi nilai yang mewakili bagian data yang berbeda pada perangkat. Misalnya, karakteristik tingkat baterai memiliki nilai yang mewakili tingkat baterai perangkat.
Baca properti karakteristik untuk menentukan operasi apa yang didukung:
GattCharacteristicProperties properties = characteristic.CharacteristicProperties;
if(properties.HasFlag(GattCharacteristicProperties.Read))
{
// This characteristic supports reading from it.
}
if(properties.HasFlag(GattCharacteristicProperties.Write))
{
// This characteristic supports writing to it.
}
if(properties.HasFlag(GattCharacteristicProperties.Notify))
{
// This characteristic supports subscribing to notifications.
}
Jika operasi baca didukung, Anda dapat membaca nilainya:
GattReadResult result = await selectedCharacteristic.ReadValueAsync();
if (result.Status == GattCommunicationStatus.Success)
{
var reader = DataReader.FromBuffer(result.Value);
byte[] input = new byte[reader.UnconsumedBufferLength];
reader.ReadBytes(input);
// Utilize the data as needed
}
Menulis ke karakteristik mengikuti pola yang serupa:
var writer = new DataWriter();
// WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle
writer.WriteByte(0x01);
GattCommunicationStatus result = await selectedCharacteristic.WriteValueAsync(writer.DetachBuffer());
if (result == GattCommunicationStatus.Success)
{
// Successfully wrote to device
}
Tip
DataReader dan DataWriter sangat diperlukan saat bekerja dengan buffer mentah yang Anda dapatkan dari banyak API Bluetooth.
Berlangganan pemberitahuan
Pastikan karakteristik mendukung baik Indicate atau Notify (periksa properti karakteristik untuk memastikan).
Indicate dianggap lebih andal karena setiap peristiwa yang diubah nilai digabungkan dengan pengakuan dari perangkat klien.
Notify lebih umum karena sebagian besar transaksi GATT lebih memilih menghemat daya daripada sangat dapat diandalkan. Bagaimanapun, semua itu ditangani di lapisan pengontrol sehingga aplikasi tidak terlibat. Kami akan secara kolektif menyebutnya sebagai "pemberitahuan".
Ada dua hal yang harus diurus sebelum mendapatkan pemberitahuan:
- Tulis ke Deskriptor Konfigurasi Karakteristik Klien (CCCD)
- Menangani peristiwa Characteristic.ValueChanged
Menulis ke CCCD memberi tahu perangkat Server bahwa klien ini ingin mengetahui setiap kali nilai karakteristik tertentu berubah. Untuk melakukan ini:
GattCommunicationStatus status = await selectedCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.Notify);
if(status == GattCommunicationStatus.Success)
{
// Server has been informed of clients interest.
}
Sekarang, kejadian ValueChanged pada GattCharacteristic akan dipicu setiap kali nilainya berubah pada perangkat jarak jauh. Yang tersisa hanyalah mengimplementasikan handler:
characteristic.ValueChanged += Characteristic_ValueChanged;
...
void Characteristic_ValueChanged(GattCharacteristic sender,
GattValueChangedEventArgs args)
{
// An Indicate or Notify reported that the value has changed.
var reader = DataReader.FromBuffer(args.CharacteristicValue);
// Parse the data however required.
}
Examples
Untuk sampel lengkapnya, lihat sampel Bluetooth Low Energy.
Windows developer