11.2. BLE 堆疊

與網路一樣,Bluetooth Low Energy 是以一疊分層的方式建構而成,每一層解決單一問題,並向上層公開一個乾淨的抽象。下面的名稱直接取自 Bluetooth Core 規格,並出現在 aioblebluetooth API 中。

A vertical stack of five labelled boxes. From bottom to top: Physical (radio), Link Layer, GAP, GATT, Application. An arrow on the right points up the stack labelled "what we build". An arrow on the left points down the stack labelled "what is provided".

Bluetooth Low Energy 堆疊。每一層都向上一層遞交一個更乾淨的抽象,這與網路堆疊所使用的模式相同。

實體層(Physical layer)。 透過 2.4 GHz 無線電在兩個裝置之間移動 位元。包含通道選擇、調變、傳輸功率。相機的工作就是保持供電;其餘的由晶片完成。

連結層(Link layer)。 在兩個同意彼此通訊的裝置之間移動 封包。它加入裝置位址,讓每個封包都能對準某一個鄰近裝置,排程構成一次連線的週期性無線電事件,並處理任何接收方未確認封包的重傳。

通用存取設定檔(Generic Access Profile,GAP)。 探索與連線層。它定義了四種 角色——廣播者(broadcaster)、觀察者(observer)、周邊裝置(peripheral)、中央裝置(central)——以及讓兩個裝置最初得以彼此找到的 廣播 / 掃描 協定,加上開啟與關閉它們之間連線的程序。位址、廣播酬載、連線參數與配對都在這一層。

通用屬性設定檔(Generic Attribute Profile,GATT)。 資料層。它位於一個開啟的 GAP 連線之上,公開一個小型的鍵/值資料庫:一方代管一棵稱為 特徵(characteristics) 的具名數值樹,另一方則讀取、寫入或訂閱它們。實際的應用程式位元組就在這一層流動。

應用層(Application)。 也就是相機與對等端對位元組意義所達成的任何約定。Bluetooth SIG 發布了標準 設定檔(profiles)——心率、電池電量、環境感測——它們定義了常用的特徵,讓不相關的裝置得以互通,但任何應用程式都可自由定義自己的設定檔。

11.2.1. 各層在執行階段如何堆疊

這個模式與網路堆疊相符:

  • 應用程式的位元組進入一個 特徵值(characteristic value)

  • GATT 用一個標頭包裝它,標明這些位元組屬於哪個特徵。

  • GAP 維持一個開啟的連線運作,讓 GATT 有地方可以送出資料。

  • 連結層將整批內容包裝成一個封包,定址到對等端的裝置位址,並排程一個無線電事件來傳輸它。

  • 實體層將該封包轉換成一段短暫的 2.4 GHz 無線電爆發。

從 Python 的角度來看,實體層與連結層幾乎是隱形的——由晶片與無線電韌體處理它們。從 GAP 往上,相機的 Python 程式碼便有更多可以著墨之處。

11.2.2. 使用者導向的 API 悄悄略過的兩層

Bluetooth 規格還命名了另外兩層,它們位於連結層與 GAP/GATT 之間:主機控制器介面(Host Controller Interface,HCI)——主機 CPU 用來驅動獨立無線電晶片的協定——以及 L2CAP——將一條連結層連線切分成數個邏輯通道的多工器。

這兩者在 aioble API 中都不可見,但也都不會消失。HCI 位於 BLE 連接埠(port)內部,除非使用自訂建置的 MicroPython,否則是隱形的;而 L2CAP 則是 GATT 在其上運行的承載者。想要原始位元組串流的應用程式可以宣告自己的 L2CAP 通道(L2CAP 通道)。