進行BLE 應用開發,我們會經常聽說到連個詞匯“協議棧”和“協議”。那他 們之間有什么關系和區別呢。
協議定義的是一系列的通信標準,通信雙方需要共同按照規定好的標準進行正常的數據收發。
舉個例子來說兩個人想要進行交流必須要說同一種語言,這就是協議。
協議棧是協議的具體實現形式,通俗理解為用代碼實現的函數庫,以便于開發人員調用。 藍牙 4.0 BLE 協議棧就是將各個層定義的協議都集合在一起,以函數的形式實現,并提供一 些應用層 API 供用戶調用。
下面來看一下BLE基本協議層
藍牙核心規格中說明了藍牙核心系統組成包含主機部分和控制器部分(一個主控制器和一 個或多個二級控制器)。主機和控制器的分離追溯到藍牙 BR/EDR 設備時期,控制器和主機 通常分開實現。
主機部分:所有非核心配置文件以下和主機控制接口以上層。 控制器部分:主機控制接口以下層。
ti公司的cc2540的結構,將ble協議棧的各個部分進行了詳細的區分,這個結構對我們來說過于復雜。
TI 公司(CC2540)精簡一下,大致分可分為以下幾層。 所有 Profile (配置文件層)和應用都建構在 GAP 或 GATT 之上。TI 的 CC2540 器件可以單芯片實現 BLE 藍牙協議棧結構圖的所有組件,包括應用程序。
下面我們簡單了解一下藍牙協議棧的分層
下面解釋一下我們會涉及到的一些專業名詞:
物理層(Physical Layer):1Mbps 自適應跳頻 GFSK(高斯頻移鍵控調制),運行在免征的 2.4GHz 頻段。
鏈路層(Link Layer):此層為 RF 控制器,用于控制設備的射頻狀態,控制設備會處于 5 種狀態之一:待機(Standby)、廣播、監聽/掃描(Scan)、初始化、連接。廣播設備不需 要建立連接就可以發送數據;而掃描設備監聽廣播數據。發起設備響應一個連接請求給廣播 設備。如果廣播設備接受連接請求,發起者設備和廣播設備將會進入連接狀態。此時兩個設 備的角色變了:主機和從機。發起連接的設備叫做主機,接受連接請求的設備稱為從機。
主機控制接口層(Host Controller Interface):為主機和控制器之間提供一個標準通信接 口。這一層可以通過軟件 API 或硬件接口實現,例如 UART、SPI、USB。
邏輯鏈路控制及自適應協議層(Logical link Control and Adaptation Protocol):為上層提 供數據封裝服務,允許邏輯上的點對多點數據通信。
安全管理層(Security Manager):定義了配對和密鑰分配方式。并為協議棧的其它層和 其它設備之間的安全連接和交換數據提供服務。
通用訪問配置文件層(Generic Access Profile):GAP 是直接與應用程序或配置文件 (profiles)通信的接口,處理設備發現和連接相關服務。另外還處理安全特性的初始化。對 上級,提供應用程序接口;對下級,管理各級智能部門,尤其是指示 LL 層控制器 5 種狀態 切換。
屬性協議層(Attribute Protocol):允許設備向其它設備展示一塊特定的數據,稱之為“屬 性”。在 ATT 環境中,展示“屬性”的設備稱之為服務器,與之配對的設備稱之為客戶端。 鏈路層狀態(主機和從機)與設備的 ATT 角色是相互獨立的。例如,主機設備既可以是 ATT 服務器,也可以是 ATT 客戶端。從機設備可以是 ATT 客戶端,也可以是 ATT 服務端。
通用屬性配置文件層(Generic Attribute Profile):定義了使用 ATT 的服務框架。GATT 規定了配置文件(profiles)的結構。在 BLE 中,所有被 profile 或服務器用到的數據塊都稱之 為“特征”。兩個建立連接的設備之間的所有數據通信都是通過 GATT 子程序處理。應用程 序和 profiles 直接使用 GATT 層。GATT 負責處理向上與應用打交道,其關鍵工作是為檢索工 作提供合適的 profile 結構,而 profile 由檢索關鍵詞(characteristics)組成。
再需要介紹的就是協議棧頂層的配置文件層
藍牙 4.0BLE 協議棧配置文件層包括 GAP/安全配置文件、GATT 配置文件兩部分,處于 協議棧的頂層部分,配置文件將協議棧和應用緊密地聯系在一起。這使得開發者即使對協議 棧底層的原理沒有深入的了解。也可以方便地進行應用的開發。
通用屬性配置文件層(Generic Attribute Profile):定義了使用 ATT 的服務框架。GATT 規定了配置文件(profiles)的結構。在 BLE 中,所有被 profile 或服務器用到的數據塊都稱之 為“特征”。兩個建立連接的設備之間的所有數據通信都是通過 GATT 子程序處理。應用程 序和 profiles 直接使用 GATT 層。GATT 負責處理向上與應用打交道,其關鍵工作是為檢索工 作提供合適的 profile 結構,而 profile 由檢索關鍵詞(characteristics)組成。
剛才也說到了新的藍牙規格采用基于屬性協議(ATT)的服務結構,所有低功耗數據通信都是通過 通用屬性配置文件(GATT)運行。從 GATT 角度來看,當連個設備建立連接后,他們處于 兩個狀態――GATT 服務器和 GATT 客戶端。如果應用或另一個配置文件使用 GATT 配置文 件,那么客戶端和服務器可以有序的方式進行互動。
GATT 服務器――它是為 GATT 客戶端提供讀寫數據服務的設備。
GATT 客戶端――它是從 GATT 服務器讀寫應用數據的設備。
特別注意的是,GATT 角色中的客戶端和服務器與鏈路層角色的主機和從機是兩個完全 獨立的概念,與 GAP 的外設和集中器也是完全獨立的。一個從機可以是 GATT 客戶端或 GATT 服務器;主機也可以是 GATT 客戶端和 GATT 服務器。
服務器包含一個或多個 GATT 服務,GATT 服務是完成特定功能的一系列數據的集合。 而 GATT 配置文件定義如何利用屬性協議發現、讀取、編寫和獲取指示。這些功能支持基于 服務的結構。所采用的服務在配置文件規格中有所界定。GATT 使你能了解配置文件規格所 界定的服務和特征。
GATT 結構使創建和實施新的配置文件更加容易。許多新的配置文件仍在開發過程中, 因為這一優勢繼續擴大。配置文件實施十分簡單,有助應用和支持這些配置文件的嵌入式設 備迅速增加。
在 TI 公司的示例工程 SimpleBLEPeripheral 應用中,有三個服務:
強制的 GAP 服務――這一服務包含設備和訪問信息,例如,設備名、供應商和產品 標示,它是 BLE 協議棧的一部分,是 BLE 規范對每一個 BLE 設備必須強制要求的, 這部分源碼并沒有提供,而是編譯到協議棧庫中了。
強制的 GATT 服務――這一服務包含 GATT 服務器的信息,是協議棧的一部分。是 BLE 規范對每一個 GATT 服務器設備的必須要求。這部分源碼并不提供,而是編譯 到協議棧庫中。
SimpleGATTProfile 服務――這個服務是一個示例配置文件進行測試和示范。所有的 源碼程序在 simpleGATTProfile.c 和 simpleGATTProfile.h 文件中。這個服務包含應用 數據的信息,與應用數據的傳遞密切相關。讀者可以按照上面示例特定的格式編寫 自己的 GATT 服務。
“特性”是服務用到的值,以及其內容和配置信息,GATT 定義了 BLE 連接中發現、讀 取、寫入屬性的子過程。GATT 服務上的特性值,及其內容和配置信息(即描述符)存儲于 屬性表中。屬性表是一個數據庫,包含了小塊數據被稱之為屬性。除了值本身,每個屬性都 有與之相關的以下屬性。
句柄——屬性在表中的地址,每個屬性有唯一的句柄。
類型——這表明數據所代表的含義,通常由 Bluetooth SIG 規定或用戶自定義的 “UUID”(universal unique identifier)。
權限——規定了 GATT 客戶端設備對屬性的訪問權限,包括是否能訪問和怎樣訪問。
GATT 定義了 GATT 服務器和客戶端之間通信的若干個子進程。
下面是一些子進程:
l 讀特性值——客戶端設備請求讀取特定句柄處的特性值,服務器將此值回應為客戶端 (假設屬性為可讀權限)。
l 使用特性的 UUID 讀——客戶端請求一個特定類型的所有特性值,服務端將所有相匹 配類型的特性的句柄和值回應給客戶端(假定屬性有讀權限)。客戶端不需要知道 這些特性的句柄。
l 讀多個特性值——客戶端一次請求讀取多個句柄的特性值,服務器將這些特性值回 應給客戶端(假定屬性有讀權限),客戶端需要知道如何解析這些不同特性值的數 據。
l 讀特性描述符——客戶端請求讀取特殊句柄的特性描述符,服務器將特性描述符的值 回應為客戶端(假定屬性有讀權限)。
l UUID 發現特性值——客戶端通過發送“特性”的類型(UUID)來請求發現這個“特 性”的句柄,服務器將特性的聲明回應給客戶端,其中包括特性值的句柄以及特性 的權限。
l 寫特性值——客戶端請求向服務器特定的句柄寫入特性值,服務器將數據是否寫入成 功的信息反饋給客戶端。
l 寫特性描述符——客戶端請求向服務器特定的句柄寫入特性描述符,服務器將數據是 否寫入成功的信息反饋給客戶端。
l 特性值通知——服務器將一個特性值通知給客戶端。這個客戶端無需向服務器請求這 個數據,當客戶端接收到通知數據后 3,也不需要回應服務器。但必須首先配置特性 使能通知服務,profile 定義了什么時候服務器應該發送這個數據。
每個 profile 初始化其相應的服務并內在的通過 GATT 服務注冊服務。GATT 服務添加整 個服務向屬性列表,并給每個屬性分配唯一句柄。
GATT 屬性列表中有一些特殊屬性類型,其值有藍牙技術聯盟技術定義:
GATT_PRIMARY_SERVICE_UUID——表示新服務的開始和提供的服務類型。
GATT_CHARACTER_UUID——稱之為“特性聲明”,表示緊跟其后的是 GATT 特 性值。
GATT_CLIENT_CHAR_CFG_UUID——這個屬性代表特性描述符,它與屬性表中它 前面近的句柄處的特征值相關,它允許 GATT 客戶端設備使能特性值通知。
GATT_CHAR_USER_DESC_UUID——這個屬性代表特性描述符,它與屬性表中它前 面近的句柄處的特性值相關,包含一個 ASCII 字符串,是對相關特性的描述。
這些特定屬性類型在 BLE 規范中包括,更多其他的詳細屬性類型請參考文檔 BLE_API_Guide_main.htm。
下面是已經采用的基于 GATT 的藍牙配置文件和服務:
基于 GATT 的規格 服務
(可進行資格認證)
已采納 版本
ANP 警報通知配置文件
1.0
ANS 警報通知服務
1.0
CTS 當前時間服務
1.0
DIS 設備信息服務
1.0
FMP Find Me 配置文件
1.0
HTP 健康體溫計配置文件
1.0
HTS 健康體溫計服務
1.0
HRP 心率配置文件
1.0
HRS 心率服務
1.0
IAS 即時警報服務
1.0
LLS 鏈路丟失服務
1.0
NDCS 下個日光節約時間更改服務
1.0
PASP 電話警報狀態配置文件
1.0
PASS 電話警報狀態服務
1.0
PXP 近距傳感配置文件
1.0
RTUS 參考時間更新服務
1.0
TIP 時間配置文件
1.0
TPS 發射功率服務
1.0
通用訪問配置文件(Generic Access Profile)
BLE 協議棧中的 GAP 層負責處理設備訪問模式和程序。包括設備發現、建立連接、終止
連接、初始化安全特寫和設備配置。
GAP 層總是作為下面四種角色之一:
(1) 廣播者------不可連續廣播設備;
(2) 觀察者------掃描廣播,但不發起建立連接;
(3) 外部設備------可連接的廣播設備,可以在單個鏈路層連接中作為從機;
(4) 集中器------掃描廣播設備并發起連接,在單鏈路層或多鏈路層作為主機,目前,TI 的 BLE 協議棧支持一個集中器連接 3 個外設。
BLE 規范說明允許特性的的多個角色組合。簡單外設實例默認僅支持外設角色,可以通 過添加源碼程序使工程同時指出外設和廣播角色。當然在編譯廣播源碼時,需禁止編譯外設 源碼。
在典型低功耗藍牙系統中,外部設備廣播特定數據為了是集中器知道它是一個可連接設備。廣播包包含:設備地址、以及一些額外的數據,例如設備名。集中器接收到廣播包,會向外部設備發送一個掃描請求,這個外部設備響應一個響應信號,被稱之“掃描回應”。因此集中器選擇意識到外部設備,知道是可以連接的設備,這就是發現設備的過程。此時,集中器向外部設備發送請求建立連接。一個連接請求包含許多連接參數:
連接時間間隔(Connection Interval)
兩個 BLE 設備連接使用跳頻機制,兩個設備發送和接收數據使用特定的信道,一段時間 后使用心得信道(鏈路層處理信道切換),兩設備在切換設備之后收發數據稱之為連接事件。 即使沒有應用數據收發,兩設備也一直通過交換鏈路層數據位置連接狀態。連接間隔就是兩 個連接時間的間隔。連接間隔以 1.25ms 為單位。連接間隔的范圍:6(7.5ms)~ 3200(4s)。
不同的應用可能要求不同的連接間隔。長時間連接間隔的優勢是節省功耗。因為設備在連接過程中有大量的睡眠時間,不好之處是設備發送數據后,需要等待哦下一個連接設備。
短的連接間隔好處是設備收發數據機會多,因為兩個之間連接的頻率高。不好之處是耗能較高,因為設備頻繁被連接事件喚醒。
n從機延時(Slave Latency) 這項參數可以使從機(外設)跳過幾項連接事件,使從機設備更靈活。如果沒有數據發
送時,可以選擇跳過連接事件和休眠,以至于更省電。這個是由從機(外設)決定。
從機延時值就是可以跳過大的連接事件個數。其值的范圍:0 ~ 499,0 表示不跳過任 何連接事件。然而大有效間隔時間不能大于 16s。
監視超時(Supervision Timeout)
兩個成功連接事件之間的大允許間隔。如果超過了這個大時間而沒有成功的連接事 件,設備被認為丟失連接,返回沒有連接狀態。參數值以 10ms 為單位。監視超時值的范圍 從 10(100Ms) ~ 3200(32s)。另外,超時值必須大于有效連接間隔。
有效間隔時間等于連個連接事件按之間的時間。假設從機跳過可能事件的大數量被從 機延時允許(如果從機延時被設置為 0,測有效連接間隔等于真實連接事件)。下面是運算 公式:
這就是告訴我們,在這種情況下,從機向主機沒有數據發送時,從機僅僅是每個 500ms 傳輸一次連接事件。
許多應用中,從機設置跳過連接事件大個數。因此,在選擇連接參數時,需要考慮有 效連接間隔。選擇正確的連接參數對 BLE 設備的功耗優化啟到重要作用。先列表在連接參數 設置上給出一個通用概述:
減少連接間隔: u增加設備功耗
增加雙向傳輸數據量
降低設備之間數據傳輸所用的時間 增加連接間隔:
降低設備的功耗 u降低設備傳輸數據量 u提高設備之間數據傳輸所用的時間
減少從機延時(或這個為 0): u提高從機設備的功耗 u降低從機設備接收集中器數據的時間。
降低從機延時: u外圍設備沒有數據發送集中器期間降低了功耗。、
Effective Connection Interval = (Connection Interval) * ( 1 + (Slave Latency) )
Take the following example: Connection Interval: 80 (100ms) Slave Latency: 4
Effective Connection Interval: (100ms) * ( 1 + 4 ) = 500ms
提高集中器發送給外圍設備的數據時間。
在某些情況,集中器向外設請求一個連接參數包,對外設也是不容易的。在其他情況, 一個外設可能期望改變連接中的參數,以外設應用為基礎。外設可以通過向集中器發送“連 接參數參數更新請求”來改變連接設置,這個請求由協議棧的 L2CAP 層處理。這個 請求包 括 4 個參數:小連接間隔、大連接間隔、從機延時和超時連接。這些參數值代表外設所 要求的連接參數。集中器接收請求后可以選擇接收或拒絕這些新的參數。
連接可以被主機和從機以任何原因自動終止。一方發起終止,并且另一方必須響應,因此兩個設備都退出連接狀態。
GAP 層也處理 BLE 連接中安全特性的初始化,只有在已認證連接中,特定的數據才能被 讀寫。一旦連接建立,兩個設備進行配對。當配對完之后,形成加密和認證鏈接的秘鑰。典 型案例中,外設請求集中器提供秘鑰來完成配對工作。秘鑰可能是一個固定值,例如“000000”, 也可以是一個隨機產生的值提供給使用者。當集中器發送正確的秘鑰后,兩個設備交換安全 秘鑰并加密和認證鏈接。
在許多情況下,同一對集中器和外設會不時地連接和斷開,BLE 有一個安全特性在配對 時,提供一個長期的安全秘鑰信息。這種特性叫做綁定。它允許兩個設備重新連接后快速完 成加密和認證,并且不需要每次連接執行配對過程,只需要兩個之間存儲這個長期秘鑰信息。
參考 SimpleBLEPeripheral 應用,GAP 部分由 GAP 配置文件處理,并且綁定信息管理由 GAP 安全配置文件(security profile)處理,更多的信息在 TI 的 CC2540/41 BLE 協議棧的 GAP 配置文件頭文件
鏈路層規格
借助先進的省電和加密功能,鏈路層將提供超低耗能的閑置模式運行、簡單的設備發現 以及可靠的點對多點數據傳輸。
使用 GAP 和 GATT 的堆棧 API
應用程序和配置文件直接調用 GAP 和 GATT API 功能來實現 BLE 相關功能,例如,廣
播、連接、讀寫“特性” 。
APIs 中有不同層的 BLE 協議棧的詳細信息。可以在 HTML 指導中咨詢,更多其他的詳
細信息請參考 BLE_API_Guide_main.htm 文檔。 使用 GAP 和 GATT 的 API 功能一般步驟如下: (1) 使用適當的參數調用 API 功能;
(2) 協議棧執行特定的操作并返回;
(3) 操作完成后,或者任何時候堆棧有消息需要報告給調用 API 功能的任務,堆棧發送 一條 OSAL 纖細給調用 API 的任務。
(4) 調用 API 任務接收和處理相應地消息;
(5) 調用 API 的任務釋放消息;
從 GAP 從機角色 profile 可以看到一個過程的示例(peripheral.c)。
(1) Profile 調用 GAP API 函數 GAP_DeviceInit 初始化設備;、
(2) GAP 進行初始化并返回 SUCCESS(0x00);
(3) 初始化之完成后,BLE 協議棧發送 OSAL 消息,外圍角色 profile 的頭事件值為 GAP_MSG_EVENT,并且操作碼為 GAP_DEVICE_INIT_DONE_EVENT;
(4) Profile 任務接收 SYS_EVENT_MSG 事件,表明它是一個消息,Profile 接收到這個 消息并查看消息頭和操作碼的值。基于這些,Profile 知道將消息數據歸類到相應的類型 (gapDeviceInitDoneEvent_t)并處理。這種情況下,Profile 將生成密鑰存儲到 Flash 存儲器, 并在本地保存設備地址;
(5) Profile 釋放消息并返回;
這是另外一個示例,如果 GATT 客戶端向共同體 GATT 服務器請求一個 GATT 讀請求,
它是可能存在的。
(1) 應用調用 GATT 子程序 API 功能,連接通過,特性句柄(包含數據類型),它自己
的任務 ID 作為參數。
(2) GATT 處理請求,并返回 SUCCESS;
(3) 在下次連接事件協議棧發送讀請求,遠處的設備接收到讀請求,協議棧發送一個包含 讀響應的 OSAL 消息給應用,消息包括頭事件值為 GATT_MSG_EVENT,操作碼為 ATT_READ_RSP;
(4) 應用任務接收到 SYS_EVENT_MSG 事件,表示它是一個消息,Profile 接收到這個消 息并查看消息頭和操作碼。基于這些,Profile 知道將消息歸類到相應的類型(attReadRsp_t), 檢索在讀響應中接收的數據。
(5) Profile 釋放消息并返回;
GATT 的 Profile 層次結構
為了實現用戶的應用,profile 通常有一個或者多個“Services”組成。
一個 service 或許包含某個特征值“characteristic values”,(例如,在一個溫度采集設備 中,通常會包含一個溫度的特征值) 每一個特征值必須有占用一個特征申明結構,其中包括他的其他特性,它是服務端和客 戶端共享的讀寫空間
這個特征值可以包含一個可選的描述(descriptor 字串),來只是這個特征值的含義。