liwen01 2026.01.01
前言
我們現在使用的藍牙,它不是一蹴而就的,它經歷了從電纜替代者(經典藍牙)到 萬物互聯基石(低功耗藍牙)的演變。
要理解 SDP、GAP、ATT、GATT 這些類似重疊的協議,需要回到藍牙技術發展的歷史背景和設計哲學。
(一)歷史背景
(1)早期無線通信的春秋戰國
在藍牙標準誕生之初,不同廠家對如何發現對方、如何加密、如何連接有不同的理解。如果沒有一個統一的框架,A 廠家的手機可能根本搜不到 B 廠家的耳機。
GAP (Generic Access Profile) 的存在是為了定義通用的行為準則,設計目的有兩個:
(A)標準化流程:它規定了所有藍牙設備必須如何打招呼(廣播)、如何交換名片(發現)以及如何建立外交關係(連接)。
(B)解耦:它讓上層應用不需要關心底層的物理跳頻或鏈路層狀態轉換,只需知道自己是中心設備(Central)還是 外圍設備(Peripheral)。
(2)解決經典藍牙業務繁雜問題
經典藍牙(BR/EDR)的設計初衷是取代各種電纜(串口線、打印線、耳機線)。
因此,它承載了非常多的特定協議(Profiles),如 HFP(通話)、A2DP(音樂)、SPP(串口)。
SDP (Service Discovery Protocol) 就是藍牙世界裏的黃頁服務,設計目的也有兩個:
(A)動態查詢: 經典藍牙設備通常功能複雜,當手機連接音箱時,它不知道這個音箱是否帶麥克風(HFP),也不知其音質等級(A2DP)。
(B)按需建立: 通過 SDP,設備可以先查詢對方支持哪些服務,獲取連接這些服務所需的端口號(如 RFCOMM 通道),然後再建立真正的業務連接,節省了系統資源。
(3)解決BLE極致功耗問題
2010年左右,藍牙 4.0 (BLE) 問世。此時的設計目標變了:不再是傳輸高帶寬的音頻,而是傳輸極小的數據(如温度、心率),且要求一顆鈕釦電池能用一年。
經典藍牙的協議棧(包括 SDP)對於這些小傳感器來説太重、太費電了。
為了極致省電,藍牙設計者提出了 ATT 和 GATT 的組合:
傳感器數據通常非常簡單(就是一個數值),比如温度濕度傳感器。
(A)ATT (Attribute Protocol):極簡的搬運工
ATT 棄了複雜的握手,將所有數據簡化為屬性(Attribute)。它只負責最簡單的操作:讀、寫、通知。它像是一個高效的倉庫搬運工,只認貨架號(Handle),不問數據背後的邏輯。
但是ATT的屬性(Attribute)太底層了,一堆 handle 很難管理,所以就有了GATT 。
(B)GATT (Generic Attribute Profile):邏輯的架構師
GATT 的目的是在 ATT 之上建立了一套層級結構(Service > Characteristic),把 ATT 相關的屬性打包。
GATT 是聲明式的,它不需要像 SDP 那樣進行復雜的動態交互,而是通過簡單的屬性列表直接告訴對方:我的 0x0012 貨架放的是心率數據
(二)GAP(Generic Access Profile)
GAP(Generic Access Profile,通用訪問配置文件)是藍牙協議棧中最基礎、最重要的配置文件之一。
可以把它看做是藍牙設備的身份證和外交官。它定義了設備如何互相發現、建立連接以及確保基本的互操作性。
(1)GAP 的核心作用
為確保不同廠商的設備能夠互相發現並建立連接,GAP 的核心作用有4個:
(A)模式與過程 (Modes and Procedures): 設備如何被發現(廣播)以及如何發現別人(掃描)。
(B)角色 (Roles): 定義設備在藍牙網絡中的身份(如手機是 Central,手環是 Peripheral)。
(C)安全 (Security): 定義安全級別和配對模式的基礎。
(D)數據格式 (Data Formats): 定義廣播數據和掃描響應數據的通用格式。
(2)GAP 四大核心角色(Roles)
在連接建立之前,GAP 首先定義了設備在鏈路層表現出的身份。這決定了誰負責發信號,誰負責找信號。
在低功耗藍牙 (BLE) 中,GAP 定義了四種特定的角色。這些角色決定了鏈路層 (Link Layer) 的狀態。
(A)Broadcaster(廣播者): 僅發送廣播數據,不支持建立連接,比如:温度傳感器、Beacon。此時鏈路層處於 Advertising State 狀態。
(B)Observer(觀察者): 僅掃描廣播數據,不支持發起連接,比如:僅用於數據採集的網關,此時鏈路層處於 Scanning State 狀態。
(C)Peripheral(外設): 發送廣播,支持被連接。通常是數據提供方,通常是性能受限、對功耗敏感的設備,比如:智能手環、心率帶、智能鎖。
此時鏈路層處於Advertising / Connection (Slave) 狀態
(D)Central(中心設備): 掃描廣播,發起連接。通常是控制方和數據處理方,一般擁有更強處理能力和電量的設備,比如:智能手機、平板電腦。
此時鏈路層處於Scanning / Connection (Master) 狀態
注意: 一個設備可以在不同時間切換不同角色,甚至在 V5.x 中通過多重連接拓撲同時扮演不同角色。
(3)GAP 的操作模式、過程、連接參數
(A)發現模式 (Discoverability Modes) :有三種發現模式:
不可被發現模式 (Non-Discoverable Mode): 設備不發送廣播,或者發送的廣播不支持被發現(僅用於維持現有連接或廣播特定非發現數據)。
有限可發現模式 (Limited Discoverable Mode): 設備在短時間內(通常有超時限制)可被發現。常用於按下按鈕後的配對狀態。
一般可發現模式 (General Discoverable Mode): 設備在很長一段時間內都可以被發現。這是大多數消費電子產品的默認狀態。
(B)連接模式 (Connectability Modes) 有三種:
不可連接 (Non-Connectable): 僅廣播數據,拒絕連接請求。
定向可連接 (Directed Connectable): 僅接受來自特定(已綁定)設備的連接請求,用於快速重連。
無向可連接 (Undirected Connectable): 接受任何設備的連接請求。
(C)發現過程 (Discovery Procedures)
作為中心設備(Central)或觀察者(Observer),GAP 定義瞭如何去發現周圍設備:
有限發現過程 (Limited Discovery Procedure): 僅過濾並顯示處於有限可發現模式的設備。
一般發現過程 (General Discovery Procedure): 發現所有可發現的設備。
(D)連接參數 (Connection Parameters)
在 GAP 中,定義了中心設備和外圍設備建立連接時必須協商的關鍵參數。這些參數直接影響功耗和數據吞吐量。
連接間隔 (Connection Interval): 兩次通信之間的時間間隔(7.5ms ~ 4.0s)。
間隔越短,速度越快但耗電;間隔越長,越省電。
外圍設備延遲 (Peripheral Latency/Slave Latency): 允許外圍設備在沒有數據發送時跳過連接事件的次數。這對低功耗至關重要。
監督超時 (Supervision Timeout): 如果超過這個時間沒有通信,連接被視為斷開。
在藍牙 5.3 引入了 Connection Subrating (連接子速率),雖然這主要是鏈路層的功能,
但在 GAP 層面,它允許設備在保持低佔空比(省電)的同時,能夠更快速地切換到高佔空比(高性能)模式,而無需完全重新協商連接參數。
(4)GAP 與底層(Link Layer)的協調邏輯
在架構圖中,GAP 位於 L2CAP 和 Link Layer (LL) 之上。它的管理指令是自上而下下達的:
GAP 發指令: 應用層告訴 GAP 我要連接那台名為 'Apple Watch' 的設備。
GAP 調度: GAP 檢查當前配置,並命令 Link Layer 進入 Initiating State(發起狀態)。
LL 執行: Link Layer 在空中監聽對方的廣播包,並在極短的窗口期內完成握手。
GAP 反饋: 連接成功後,GAP 會通知上層(如 GATT 或應用層):鏈路已建立,可以開始傳輸數據了。
(5)為什麼手環設備能省電
這裏我們以藍牙手環來舉例,從手環的初始化、連接、進入靜默期、調整 這個週期來看它是如何進行功耗管理的。
初始化: 手環 GAP 設置為 Peripheral,每 1 秒發一次廣播。
連接: 手機 Central 發現手環,GAP 建立連接,初始連接間隔設為 30ms(為了快速同步數據)。
進入靜默期: 數據同步完了,App 進入後台。此時手機 GAP 發起連接參數更新請求。
調整: 連接間隔被拉長到 500ms,且設置了 Slave Latency = 10。這意味着手環即使每 500ms 該醒來一次,但如果沒數據,它可以連續睡 10 次,也就是 5 秒鐘才跟手機通信一次。
結果就是:這種由 GAP 協調的參數調整,讓你的手環續航從 3 天延長到了 20 天。
(三)SDP (Service Discovery Protocol)
SDP (Service Discovery Protocol) 是 金典藍牙(BR/EDR)設備的 黃頁電話簿。
在兩個金典藍牙設備建立連接後,必須通過 SDP 來查詢對方:你到底支持哪些功能?怎麼連接這些功能?
(1)SDP 的核心概念與適用範圍
SDP 提供了一種機制,允許客户端應用程序發現服務器應用程序提供的服務以及這些服務的屬性。
它不定義具體的服務操作(那是各個 Profile 的事),只負責發現。
重要前提: SDP 主要用於 藍牙經典 (BR/EDR) 技術,雖然 BLE 設備主要用 GATT,但雙模設備(Dual Mode,同時支持 Classic 和 BLE)依然必須實現 SDP 棧以支持經典藍牙部分的功能。
(2)SDP 架構與角色 (Architecture & Roles)
SDP 採用簡單的 Client-Server (客户端-服務器) 模型:
SDP Server (服務端): 通常是提供服務的設備(如藍牙音箱),它維護一個服務記錄數據庫。
SDP Client (客户端): 通常是想要使用服務的設備(如手機),它向服務端發起查詢。
常見的查詢方式有:
服務搜索 (Service Search): 客户端問:你這裏有支持 UUID 為 0x110B(音頻接收)的服務嗎?
屬性獲取 (Service Attribute): 客户端問:對於這個音頻服務,你的連接通道是多少?
服務瀏覽 (Service Browsing): 客户端請求查看服務器上所有可公開的服務列表。
(3)SDP 的核心組件、數據模型
SDP 服務器維護的數據庫由一系列 Service Records (服務記錄) 組成。
(1)Service Record (服務記錄)
Service Record Handle: 每一個服務(如免提通話、串口通信)都對應一條記錄,這是 SDP 服務器分配給某一個服務的索引號。
在一台設備(Server)上,每一個服務記錄都有一個唯一的句柄,長度為32位,稱為 Handle。
分配規則: 範圍是 0x00000000 到 0xFFFFFFFF。通常 0x00000000 是保留給 SDP 服務本身的。
(2)Service Attributes (服務屬性)
每條記錄包含多個屬性,描述該服務的細節。屬性由 Attribute ID 和 Attribute Value 組成。
Attribute ID (屬性 ID): 定義了該屬性的含義,由藍牙 SIG 統一規定,例如:
0x0001:始終代表ServiceClassIDList(服務類別列表)。0x0100:始終代表ServiceName(服務名稱)。
客户端通過這個 ID 告訴服務器:請把這個服務的 ServiceName(0x0100) 告訴我。
Attribute Value (屬性值) : 這是最具體的數據,它的格式叫 Data Element,可以是一個整數、一個字符串、一個布爾值,甚至是一個嵌套的列表。
(3)UUID (通用唯一標識符)
UUID 這是 SDP 的靈魂,它是一個全球唯一的標籤,用來標識這就是 A2DP 音頻或這就是串口協議。
關鍵點: UUID 通常是作為Attribute Value的一部分出現的。
比如在 ServiceClassIDList 這個屬性(ID 為 0x0001)裏,它的值通常就是一個 UUID(如 0x110B 代表 A2DP Audio Sink)。
一般16位 UUID(簡短版)用於官方標準服務,128位 UUID(完整版)用於廠商自定義服務。
(4)Handle、Attribute ID、Value、UUID 的區別
Handle (32位):找到那個服務記錄的鑰匙。
Attribute ID (16位):指明你想看記錄裏的哪一項。
Attribute Value:那一項裏存的實際數據。
UUID:存在數據裏的標準身份標籤。
(4)SDP 協議過程 (Protocol Procedures)
SDP 定義了三種主要的 PDU (協議數據單元) 交互模式,運行在 L2CAP 協議之上(通常使用 PSM 0x0001)。
(A)Service Search Transaction (服務搜索)
Client 問: 你有支持 UUID 為 0x1101 (Serial Port) 的服務嗎?
Server 答: 有,對應的 Service Record Handle 是 0x00010005。
用途: 僅獲取記錄的句柄,不獲取具體細節。
(B)Service Attribute Transaction (屬性獲取)
Client 問: 請給我 Handle 為 0x00010005 的所有屬性(或者特定屬性,如協議列表)。
Server 答: 這是屬性列表:ID 0x0001 是...,ID 0x0004 是...
用途: 已知句柄,獲取詳細信息。
(C)Service Search Attribute Transaction (搜索並獲取)
Client 問: 查找支持 UUID 0x1101 的服務,並直接把它們的協議列表屬性發給我。
Server 答: 找到了,這是數據...
用途: 最高效的方式,一次交互完成搜索和讀取,減少空中交互時間。
(四)ATT (Attribute Protocol)
ATT (Attribute Protocol) 是藍牙低功耗 (BLE) 世界的 搬運工。它是 BLE 通信的最底層數據傳輸協議。
上層的 GATT (Generic Attribute Profile) 幾乎所有的操作(讀、寫、通知)都是通過 ATT 協議定義的 PDU (協議數據單元) 來完成的。
(1)ATT 的核心架構與角色
ATT 定義了兩個核心角色,這兩個角色完全獨立於 GAP 的主機/從機或中心/外圍角色。
服務器 (Server)::數據持有者,它存儲了所有的狀態、數據和配置信息(即屬性)。它通常是傳感器設備(如心率帶、温度計)。
注意:在大多數情況下,BLE 外圍設備 (Peripheral) 充當 ATT Server,但這並不是強制的。
客户端 (Client):數據請求者,它向服務器發起請求,或者接收服務器推送的數據。通常是手機、網關或平板電腦。
(2)ATT 的屬性(數據單元)
ATT 層傳輸的最小單位就是 Attribute (屬性)。服務器本質上就是一個巨大的屬性列表(Attribute Table)。每一個屬性都由以下四個元素組成:
Attribute Handle:handle 長度16bit,它是屬性的地址或索引。客户端通過句柄來找到它要讀寫的數據。範圍:0x0001 ~ 0xFFFF。
Attribute Type :定義這到底是什麼數據。使用 UUID 標識(如 0x2800 代表服務聲明,0x2A37 代表心率測量值)。
Attribute Value :實際的數據載體。長度可變(0 ~ 512 字節)。
Attribute Permissions:定義誰可以訪問該屬性(讀/寫/加密要求)。注意:權限不通過空中傳輸,僅存在於服務器內部邏輯中。
(3)ATT PDU 類型 (通信方式)
ATT 協議定義了 6 種基本的通信交互模式 (PDU Types)。理解這 6 種模式是理解 BLE 數據流的關鍵。
(A)請求 (Request) 由 Client -> Server,客户端發送請求,必須等待服務器回覆響應,比如:手機讀取手環電量 (Read Request)。 特點是:串行,慢,但可靠。
(B)響應(Response):由 Server -> Client,服務器對請求的回覆,比如:手環回覆電量值 (Read Response)。
(C)命令 (Command):由 Client -> Server 。客户端發送數據,不需要服務器回覆。也叫 "Write without Response"。比如:手機快速向智能燈泡發送調色指令。
特點是:由底層鏈路層保證數據到達,應用層不確認,速度最快
(D)通知 (Notification): 由 Server -> Client。服務器主動推送數據,不需要客户端確認。比如:心率帶每秒推送一次實時心率。特點是:最常用的數據上報方式,吞吐量高。
(E)指示 (Indication):由Server -> Client。服務器主動推送數據,必須等待客户端回覆確認。在收到確認前,服務器不能發下一條。比如:血糖儀發送血糖結果(數據至關重要,必須確保對方應用層收到了)。
特點是:慢,但在應用層極其可靠
(F)確認 (Confirmation):由 Client -> Server。是客户端收到指示 (Indication) 後的回覆。
(4)增強型 ATT (Enhanced ATT, EATT)
增強型 ATT (Enhanced ATT, EATT) 這是從藍牙 5.2 引入並在 V5.3 中繼續強化的重要特性。
傳統 ATT (Legacy ATT): 是順序 (Sequential)的。如果你發送了一個 Read Request,在收到 Read Response 之前,你不能發送任何其他請求。
這就像單行道,容易造成阻塞(Head-of-Line Blocking)。
增強型 ATT (EATT): 它運行在 L2CAP 的增強型基於信用的流量控制 (Enhanced Credit Based Flow Control) 模式之上。
它的特點是:
- 支持併發 (Concurrent): 允許同時執行多個 ATT 事務。
- 低延遲: 優先級高的命令不會被前面正在處理的大數據包阻塞。
- MTU: EATT 的 MTU 是獨立配置的,通常更靈活。
在 V5.3 設備中,如果雙方都支持 EATT,設備將優先建立 EATT 信道以提升用户體驗(如音頻流傳輸時的同時控制操作)。
(5)ATT MTU (最大傳輸單元)
ATT_MTU 決定了在一個數據包中最多能傳多少字節的有效載荷。默認值為 23 字節 (BLE 4.0)。
典型值: 為247 字節 (常見的 DLE 擴展後數值) 或 512 字節 (最大)。
ATT連接建立後,客户端通常會發起 Exchange MTU Request,雙方協商使用兩者支持的較小值。
(五)GATT (Generic Attribute Profile)
如果 ATT 是負責運輸數據的卡車,那麼 GATT (Generic Attribute Profile) 就是定義貨物如何打包、存放、分類以及如何進行存取操作的倉庫管理規範。
(1)GATT 核心概念與角色 (Roles)
GATT 定義了兩個在數據交換中完全不同的角色。請注意,這與鏈路層的主機 (Central/Master) 和從機 (Peripheral/Slave) 概念是獨立的,儘管通常存在某種映射關係。
GATT Server (服務端): 擁有數據並接受數據訪問請求的設備。它的職責是存儲數據(Services 和 Characteristics),響應 Client 的讀/寫請求,或主動向 Client 推送數據。比如智能手環(存有心率數據)
GATT Client (客户端): 發起命令和請求,試圖讀取或寫入數據的設備。它的職責是執行服務發現 (Service Discovery),發起讀寫操作,接收 Server 推送的數據。比如智能手機(想要讀取手環的心率)。
(2)GATT 數據層級結構 (Hierarchy)
GATT 最重要的貢獻是定義了嚴格的數據層級結構,使得不同廠商的設備可以互相理解。
(A)Profile (配置文件) Profile 實際上不是 GATT 協議本身定義的實體,而是由 Bluetooth SIG 或廠商定義的集合。一個 Profile 可能包含一個或多個 Service。
(B)Service (服務) :Service 是數據和相關行為的邏輯集合,用於實現特定的功能或特性。這裏分三種服務:
Primary Service (首要服務): 暴露設備主要功能的服務。
Secondary Service (次要服務): 僅作為被引用的輔助服務(較少見)。
Include Service (引用服務): 一個服務可以引用另一個服務(類似於編程中的 #include),例如跑步服務可能引用心率服務。
(C)Characteristic (特徵) :Characteristic 是 GATT 中最小的邏輯數據單元,包含實際的數據值。它由三個主要部分組成:
Declaration (聲明): 包含屬性(讀、寫、通知等)、Handle(句柄)和 UUID。
Value (值): 實際的數據(例如:心率值 0x48)。
Descriptor (描述符): (可選)關於特徵的額外信息。
(D)Descriptor (描述符) :對 Characteristic 的進一步描述或配置。
最著名的 Descriptor 是 CCCD (Client Characteristic Configuration Descriptor)。Client 必須寫入這個描述符來開啓 Server 的通知 (Notify) 或指示 (Indicate) 功能。
(3)GATT 核心操作流程 (GATT Procedures)
(A)配置與發現 (Discovery)
Client 連接 Server 後,通常不知道 Server 有什麼功能,需要進行發現:
-
Discover Primary Services: 找出設備支持的所有主要服務。
-
Discover Characteristics: 找出某個服務下有哪些特徵。
-
Discover Descriptors: 找出特徵下有哪些描述符。
-
Exchange MTU: 協商最大傳輸單元,以決定一次能傳多少字節(藍牙 4.2/5.0+ 之後非常重要,以提高吞吐量)。
(B)數據讀取 (Client -> Server)
- Read Characteristic Value: 讀取某個句柄的值。
- Read Blob: 讀取長數據的片段(當數據超過 MTU 時)。
- Read Multiple: 一次性讀取多個句柄的值。
(C)數據寫入 (Client -> Server)
- Write Request: Client 寫入數據,Server 必須回覆 (Ack)。可靠,但慢。
- Write Command (Write without Response): Client 寫入數據,Server 不回覆。速度快,用於高吞吐量場景(如 OTA 升級)。
- Signed Write: 帶有簽名的寫入,用於未加密連接但需要認證的場景。
(D)服務器發起的數據推送 (Server -> Client)
這是 BLE 低功耗的關鍵,Client 不需要一直輪詢 (Polling),而是訂閲後等待 Server 推送。
- Notification (通知): Server 發送數據給 Client,Client 不回覆。速度快,但如果丟包不會重傳。
- Indication (指示): Server 發送數據給 Client,Client 必須回覆 Confirmation。可靠,但在收到回覆前 Server 不能發下一條,速度較慢。
注意: 要啓用 Notification 或 Indication,Client 必須先在對應的 CCCD (描述符) 中寫入特定的值。
結尾
隨着低功耗藍牙的普及,Host 層的改進越來越趨向於高效率和低延遲。理解 GAP 的連接管理、ATT 的原子操作以及 GATT 的層級解構,是開發高性能藍牙產品的基本。
希望這篇文章能有助於你更好地理解藍牙協議棧及其工作原理。