--- title: 藍牙GATT:如何設計自定義服務和特性 description: 藍牙GATT:如何設計自定義服務和特性 # image: https://hackmd.io/screenshot.png tags: Bluetooth # robots: noindex, nofollow langs: zh-Hant --- # 藍牙GATT:如何設計自定義服務和特性 > original post: https://www.novelbits.io/bluetooth-gatt-services-characteristics/ GATT代表**通用屬性配置文件(Generic Attribute Profile)**。要了解GATT是什麼,我們首先需要了解GATT的基礎框架:**屬性協議(ATT, Attribute Protocol)**。只有在兩個BLE設備之間建立連接後,GATT才會發揮作用 ## Attribute Protocol (ATT) 屬性協議定義了伺服器及客戶端兩個角色: - **Server**: 曝露本身控制或包含數據的設備,它是接受來自對等設備的傳入命令並發送**響應**,**通知**和**指示**的設備。 - **Client**: 這是與服務器連接的設備,目的是讀取服務器的公開數據和/或控制服務器的行為。 它是發送命令和請求並接受傳入通知和指示的設備。 伺服器曝露的數據結構為**屬性(Attribute)**。 屬性是伺服器曝露任何類型數據的通用術語,用於定義此數據的結構。例如,服務(service)和特徵(characteristic)是屬性的類型。屬性由以下內容組成: - **Attribute type (UUID)**: 這是一個16-bit數字(Bluetooth SIG採用的屬性),或128-bit數字(開發人員定義的自定義屬性類型)。 > 例如,SIG採用的溫度測量值的UUID是**0x2A1C**,SIG特殊的128-bit基本UUID為0000**0000**-0000-1000-8000-00805F9B34FB,溫度測量值的16-bit UUID值替換基本UUID中以粗體顯示的2個位元組。 > 另一方面,自定義UUID可以是不使用SIG採用的基本UUID的任何128-bit數字。 - **Attribute Handle**: 這是伺服器為其每個屬性分配的16-bit,將其視為地址。客戶端使用此值來引用特定屬性,並且伺服器保證該值在兩個設備之間的連接生命週期內唯一標識屬性。Handle範圍是**0x0001-0xFFFF**,其中**0x0000**的值是保留的。 - **Attribute Permissions**: 權限確定是否可以讀取或寫入屬性,是否可以被通知或被指示,以及每個操作需要哪些安全級別。這些權限不是通過屬性協議(ATT)定義或發現的,而是在更高層(GATT層或應用層)定義的。 屬性的邏輯表示: |Attribute Handle|Attribute type|Attribute Value|Attribute Permissions| |:-:|:-:|:-:|:-:| |2 bytes| 2 or 16 bytes|變數長度|特定實現 ## The Generic Attribute Profile (GATT) 現在我們已經介紹了屬性的概念,我們將討論BLE中的三個重要概念: - Services (服務) - Characteristics (特徵) - Profiles (配置) 這些概念專門用於允許層次結構化伺服器公開的數據。服務和特徵是用於特定目的的屬性類型。特徵是屬性數據庫中的最低級別屬性。配置有點不同,不會在服務器上發現。 GATT定義了服務的格式及其特徵,以及用於與這些屬性介面的過程,例如服務探索,特徵讀取,特徵寫入,通知和指示。 GATT扮演與屬性協議(ATT)相同的角色。角色不是按設備設置的 - 而是根據事務確定的(例如請求⟷響應,指示⟷確認,通知) ## Services and Characteristics ### Services 服務是一個或多個屬性的群組,其中一些屬性是特徵。它旨在將滿足伺服器上特定功能的相關屬性組合在一起。 服務還包含有助於在服務中構建數據的其他屬性(例如**service declarations**, **characteristic declarations**等)。 **include service**允許服務引用其他服務。有兩種類型的服務: - **Primary Service**:代表設備的主要功能。 - **Secondary Service**:提供設備的輔助功能,並由設備上的至少一個其他主要服務引用。 ## Characteristics 特徵始終是服務的一部分,它代表服務器要向客戶端公開的一條信息/數據。該特徵包含有助於定義其擁有的值的其他屬性: - **Properties**:由多個bit表示,用於定義如何使用特徵值。 一些示例包括:讀取,寫入,寫入無響應,通知,指示。 - **Descriptors**:用於包含有關特徵值的相關信息。一些示例包括:extended properties, user description,用於 subscribing to notifications and indications的字段,以及 presentation of the value的字段,例如值的格式和單位。 ## Profiles 配置的定義比服務更廣泛。他們關注的是在服務,特徵甚至連接和安全要求方面定義客戶端和伺服器的行為。另一方面,服務及其規範僅在伺服器端處理這些服務和特徵的實現。 在配置文件規範中,通常會發現以下內容: - 角色的定義以及GATT伺服器和客戶端之間的關係。 - 所需服務。 - 服務要求。 - 如何使用所需的服務和特性。 - 連接建立要求的詳細信息,包括廣告和連接參數。 - 安全考慮。 ## Example GATT 讓我們看一下GATT實現的一個例子。在本例中,我們將查看Silicon Labs藍牙低功耗開發框架(BGLib)使用的示例GATT.xml文件。 ![GATT XML example](https://i.imgur.com/lj3NohB.png "GATT XML example") 在此XML中,您將注意到以下內容: - 定義了兩種服務: - 具有UUID的Generic Access Profile(GAP)服務:0x1800(SIG採用的服務)。 - 使用UUID的Cable Replacement服務:0bd51666-e7cb-469b-8e4d-2742f1ba77cc(自定義或特定於供應商的服務)。 - 根據規範,Generic Access Profile是強制性的,它包括以下強制性特徵: - Name使用UUID 0x2a00和值:Bluegiga CR Demo。 - Appearance為UUID 0x2a01,值為0x4142。(外觀值定義可以在[這裡](https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml)找到) **Note**:創建和包含此服務通常由芯片組的SDK處理,通常提供API以簡單地設置名稱和外觀值。 - Cable Replacement服務有一個名為數據data的特徵 - data特徵具有UUID:e7add780-b042-4876-aae1-112855353cc1 - 它啟用了寫入和指示。 ## GATT Design Guidelines 雖然GATT是一個非常靈活的框架,但在設計它並在其中創建服務和特徵時,需要遵循一些通用的指導原則。以下是一些建議: - 確保實現以下強制服務及其特徵: - **Generic Access Profile**(GAP)service. - **Name** and **Appearance** characteristics within the GAP service. - 需要記住的一件事是,供應商SDK通常不要求您明確實現此服務,而是提供用於設置名稱和外觀的API。然後,SDK處理創建GAP服務並根據用戶提供的值設置特徵。 - 盡可能利用Bluetooth SIG採用的配置,服務和特性。這有以下好處 - 您可以減少涉及服務和特性(包括廣告數據包,探索過程等)的UUID的數據包的大小 - 因為使用了16-bit UUID而不是128-bit。 - 藍牙芯片組和模塊供應商通常在其SDK中提供這些配置文件,服務和特性的實現 - 大大縮短了開發時間。 - 與其他第三方設備和應用程序的互操作性,允許更多設備與您的設備連接並提供更豐富的用戶體驗。 - 在單個服務中提供相關功能的群組特徵。 - 避免使用具有太多特徵的服務。良好的服務分離使得探索某些特徵變得更快,並導致更好的GATT設計,模塊化和用戶友好。