一、GATT協議概述
GATT(Generic Attribute Profile)是藍牙協議中的一個子協議,作為BLE(Bluetooth Low Energy)協議棧的一部分,提供了一種通用的機制來管理連接設備之間的數據傳輸。它定義了使用BLE協議棧上的外設之間的數據交換方式,並且使之成為可能的商業化的應用,比如智能物聯網、健康監護設備等等。
GATT協議中的服務(Services)和特徵(Characteristics)是BLE的核心概念之一,它們是應用程序建立藍牙連接並在連接設備之間交換數據的基礎。服務定義了一組相關的特徵,而特徵則包含了一些屬性,包括類型、值和權限,以及一些關於如何訪問這些屬性的描述。通過GATT協議,應用程序可以向遠程設備發送請求以讀取或更改服務和特徵的屬性。
在BLE連接中,一個設備可以同時充當客戶端和服務器端。作為服務器端的設備需要發佈其提供的服務和特徵,以便可用於客戶端的應用程序進行訂閱和請求。作為客戶端的設備則可以掃描周圍的設備,查找它們可以提供的服務和特徵。當客戶端訂閱了一個服務或特徵時,服務器就會發送通知或者指示以向客戶端傳遞數據。
二、GATT協議的具體實現
1.服務和特徵的定義
GATT協議中的服務和特徵通過UUID(Universally Unique Identifier)來進行識別和命名。UUID是一個128位的數字,用於將服務和特徵唯一地標識出來。
// 以下是一個服務的UUID定義 #define SERVICE_UUID 0x180D // 以下是一個特徵的UUID定義 #define CHARACTERISTIC_UUID 0x2A37
服務和特徵的定義需要在服務器端進行,包括一個服務的UUID、包含的特徵的UUID以及每個特徵的屬性和權限。這些信息需要通過GATT API加到服務之中,例如在Android系統中,可以通過BluetoothGattService和BluetoothGattCharacteristic類來實現:
// 定義一個GATT服務 BluetoothGattService service = new BluetoothGattService(SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY); // 為服務添加特徵 BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(CHARACTERISTIC_UUID, BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_READ); service.addCharacteristic(characteristic);
2.建立連接和發現服務
當一個設備(客戶端)與另一個設備(服務器)建立連接時,需要先檢查它是否支持GATT協議。這是通過發現設備是否支持LE(Low Energy)設備來完成的。
// 檢查設備是否支持BLE PackageManager pm = getPackageManager(); if (!pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Log.e(TAG, "Device does not support BLE"); finish(); return; } // 初始化BLE適配器 final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); return; } // 搜索周圍的BLE設備 mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); mBluetoothLeScanner.startScan(mScanCallback);
在發現服務並且連接成功後,需要請求進行服務和特徵的發現。在Android中,可以使用BluetoothGatt#discoverServices()方法調用該請求。一旦服務被發現並且可用,應用程序就可以查看、訂閱和請求服務和特徵。
// 發現服務和特徵 @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (newState == BluetoothProfile.STATE_CONNECTED) { gatt.discoverServices(); } } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { List services = gatt.getServices(); // 處理服務和特徵 } }
3.讀寫特徵值
在GATT協議中,特徵的值存儲在設備內存中,可以通過讀取和寫入特定的特徵進行數據傳輸。
在Android中,可以使用BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)方法來請求讀取特徵值,而使用BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic)方法來請求寫入特徵值:
// 讀取特徵值 BluetoothGattCharacteristic characteristic = mGattService.getCharacteristic(CHARACTERISTIC_UUID); mBluetoothGatt.readCharacteristic(characteristic); @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { byte[] value = characteristic.getValue(); // 處理讀取到的特徵值 } } // 寫入特徵值 BluetoothGattCharacteristic characteristic = mGattService.getCharacteristic(CHARACTERISTIC_UUID); byte[] value = new byte[] {0x00, 0x01}; characteristic.setValue(value); mBluetoothGatt.writeCharacteristic(characteristic); @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { // 處理寫入結果 }
三、GATT協議的常見問題
1.連接問題
由於BLE是低功耗協議,因此它具有一些連接上的限制。如果在連接過程中沒有成功發送或接收數據,連接就會自動關閉。由於BLE的連接速度較慢,因此在連接設備之間傳輸大量數據也很困難。這些問題可以通過保持連接、定期發送數據包和使用緩存的數據傳輸來解決。
2.功耗問題
由於BLE協議是一種低功耗協議,因此它使用的通信速率和數據量都相對較小。一些高效的GATT協議實現可以減少功耗,並在數據傳輸結束後自動關閉連接,以節省能量。
3.並發連接問題
GATT協議可以支持多個連接,但由於BLE是低功耗協議,它的連接速度非常慢。在同一時間內與多個設備進行數據交換可能會導致傳輸速度過慢,甚至導致連接失敗。
可以通過使用廣播通知和優化數據傳輸來最大程度地減少並發連接問題。特別是在同時與多個設備進行通信時,可以採用時間分割多址(Time Division Multiple Access,TDMA)的方式來避免衝突和丟包。
結論
通過對GATT協議的詳細講解,我們可以了解到BLE協議的幾個關鍵點,包括服務和特徵、連接和發現、讀寫特徵值以及GATT協議的常見問題等等。這些問題不僅對於普通開發者來說很重要,而且對於物聯網和健康監護等行業應用也非常有影響。
原創文章,作者:GVNMB,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/369468.html