11.3. 無線電與連結層¶
從 Python 的角度來看,BLE 堆疊的最底兩層幾乎完全是自動運作的——無線電晶片以及 MicroPython 在其上執行的各層,會處理從挑選頻道到重傳遺失封包的一切事務。它們所做的選擇中,仍有三項會透出到面向使用者的 API:功率、範圍與吞吐量。
11.3.1. 無線電¶
BLE 使用與 Wi-Fi、微波爐及大多數其他短距離無線裝置相同的 2.4 GHz 工業、科學與醫療(ISM)頻帶。該頻帶被劃分為 40 個寬 2 MHz 的頻道。
40 個頻道中有 三個 保留供 廣播 使用——這是向任何收聽者宣告裝置存在的短促廣播。它們在頻帶上彼此分散,使得收聽者能迅速掃過全部三個,並使任一頻道上的干擾不太可能讓裝置完全失聯。
三十七個 是 資料 頻道。一旦兩個裝置連線,便會在這些頻道上交換封包,依照雙方在連線時議定的偽隨機序列在它們之間跳頻。自適應跳頻 讓任一方都能將某個頻道標記為不良(嚴重的 Wi-Fi 干擾、微波爐、鄰近的 BLE 網路),使序列跳過它。
2.4 GHz 頻帶上的 40 個 BLE 頻道。三個用於廣播,其餘的則在開放連線上承載流量。¶
無線電傳送短促的封包——最長不過幾毫秒——並在其間休眠。那段休眠正是使這項技術 低能耗 的關鍵。典型的 BLE 周邊端實際傳送的時間遠低於其運作時間的百分之一;其餘時間裡,無線電都在排定的事件之間關閉電源。
11.3.2. 連結層¶
連結層是 BLE 中與另一裝置上對應部分溝通的最小單位。它處理四項工作。
封包訊框化。 每個封包都帶有一個短標頭(頻道存取位址、封包長度、控制位元)、一個酬載,以及一個 CRC。接收端會檢查 CRC 並丟棄任何損毀的內容。
定址。 每個 BLE 裝置都有一個 48 位元的 裝置位址,用以在無線電上標識它。有些是 公開的——製造商指派的硬體識別碼,可永久追溯。有些則是 隨機的——在裝置上產生、定期輪替,並可選擇性地加密,使竊聽者無法將兩次傳輸連結到同一台實體硬體。位址在 廣告與掃描 中會再次出現。
連線排程。 一旦兩個裝置連線,連結層便會在跳頻序列上排定週期性的無線電事件——彼此相隔一個固定的 連線間隔——並將上層 GATT 層所佇列的任何資料打包進每一個事件中。雙方在事件之間都回到休眠狀態。連線間隔是應用程式可以請求的一個調節旋鈕(參見 連線)。
可靠性。 連線上的每個封包都會由對方確認。連結層會重傳任何未獲回應的內容,因此上層看到的是一個有序、無遺失的位元組串流。與網路那一側的 UDP -- 送出封包,聽天由命 不同,BLE 在正常使用下並沒有一個獨立的不可靠模式——開放連線上的每個封包都會被重試,直到送達或連結被宣告遺失為止。
連結層也是在一對裝置於配對期間議定金鑰之後 加密 運作之處(參見 配對與綁定)。加密連結上的每個封包在上層看到它之前,都會在接收端先行解密。
11.3.4. Python 對這一切看到的內容¶
幾乎什麼都看不到。bluetooth 與 aioble API 不會公開頻道、跳頻序列、封包 CRC 或重傳計時器;那些全都在 BLE 連接埠與無線電內部處理。確實 會透出的部分,是連線時協商所公開的那些——連線間隔、MTU、位址類型。