轉自: http://www.cnblogs.com/aikm/p/5022502.html
版權聲明:本文為部落客原創文章,轉載請注明作者和出處。 作者:強光手電[艾克姆科技-無線事業部]
在使用EN-Dongle捕獲和解析廣播包之前,我們先了解一下BLE封包的結構,之後,再對捕獲的廣播包進行分析。在學習BLE的時候,下面兩個文檔是極其重要的,這是SIG釋出的藍牙的核心協定和核心協定增補。
- 核心協定Core_v4.2。
- 核心協定增補CSS v6。
雖然這兩個文檔是藍牙技術的根本,但是遺憾的是:通過這兩個文檔學習藍牙并不是那麼容易的,閱讀和了解起來很費力。尤其是初學者在閱讀這兩個文檔的時候,感覺無從下口。是以,本文在分析封包的過程中,會明确指出協定文檔在什麼地方定義了他們,讓我們有目的的去查閱協定文檔,做到知其然也知其是以然,這樣,學習起來就會輕松很多。
1. BLE封包結構
BLE封包結構如下,他由下圖所示的各個域組成。因為有的域的長度超過了一個位元組,是以在傳輸的過程中就涉及到多位元組域中哪個位元組先傳輸的問題,BLE封包傳輸時的位元組序和比特序如下:
- 位元組序:大多數多位元組域是從低位元組開始傳輸的。注意,并不是所有的多位元組域都是從低位元組開始傳輸的。
- 比特序:各個位元組傳輸時,每個位元組都是從低位開始。
圖1:BLE封包結構
1.1 前導
前導是一個8比特的交替序列。他不是01010101就是10101010,取決于接入位址的第一個比特。
- 若接入位址的第一個比特為0:01010101
- 若接入位址的第一個比特為1:10101010
接收機可以根據前導的無線信号強度來配置自動增益控制。
1.2 接入位址
接入位址有兩種類型:廣播接入位址和資料接入位址。
- 廣播接入位址:固定為0x8E89BED6,在廣播、掃描、發起連接配接時使用。
- 資料接入位址:随機值,不同的連接配接有不同的值。在連接配接建立之後的兩個裝置間使用。
對于資料信道,資料接入位址是一個随機值,但需要滿足下面幾點要求:
1) 資料接入位址不能超過6個連續的“0”或“1”。
2) 資料接入位址的值不能與廣播接入位址相同。
3) 資料接入位址的4個位元組的值必須互補相同。
4) 資料接入位址不能有超24次的比特翻轉(比特0到1或1到0,稱為1次比特翻轉)。
5) 資料接入位址的最後6個比特需要至少兩次的比特翻轉。
6) 符合上面條件的有效随機資料接入位址大概有231個。
1.3 報頭
1.3.1 廣播封包報頭
報頭的内容取決于該封包是廣播封包還是資料封包。廣播封包的報頭如下圖所示:
圖2:廣播封包報頭
廣播封包的報頭包含4bit廣播封包類型、2bit保留位、1bit發送位址類型和1bit接收位址類型。
1) 廣播封包類型
Core_v4.2的2583頁描述了廣播封包類型,共有7種類型,如下圖所示。
圖3:廣播封包類型
每種廣播封包類型都具有不同的資料格式及行為。Core_v4.2的2584頁的2.3.1節詳細的描述了各個廣播封包類型,大家可以閱讀此章節進一步了解。
2) 發送位址類型和接收位址類型
發送位址類型和接收位址類型訓示了裝置使用公共位址(Public Address)還是随機位址(Random Address)。公共位址和随機位址的長度一樣,都包含6個位元組共48位。BLE裝置至少要擁有這兩種位址類型中的一種,當然也可以同時擁有這兩種位址類型。
- 公共位址(Public Address)
公共位址由兩部分組成,如下圖。公共位址由制造商從IEEE申請,由IEEE注冊機構為該制造商配置設定的機構唯一辨別符OUI(Organizationally Unique Identifier)。這個位址是獨一無二,不能修改的。Core_v4.2 P2576的1.3.1節描述了公共位址。
圖4:公共位址結構
- 随機位址
随機位址有包含兩種:靜态位址(Static Device Address)和私有位址(PrivateDevice Address)。Core_v4.2 P2577的1.3.2.1節描述了靜态位址。
圖5:靜态位址格式
靜态位址有如下要求:
a) 靜态位址的最高2位有效位必須是1。
b) 靜态位址最高2位有效位之外的其餘部分不能全為0。
c) 靜态位址最高2位有效位之外的其餘部分不能全為1。
在私有位址的定義當中,又包含了兩個子類:不可解析私有位址(Non-resolvable Private Address)和可解析私有位址(Resolvable Private Address,RPA)。nRF51822使用的是靜态位址,晶片在出廠時已經設定好了48位位址,我們可以從下面兩個寄存器讀出位址類型和位址。
a) DEVICEADDRTYPE寄存器。
DEVICEADDR[n]寄存器:包含DEVICEADDR[0]和DEVICEADDR[1]兩個寄存器。
圖6:位址類型寄存器
圖7:位址寄存器
1.4 長度
- 廣播封包:長度域包含6個比特,有效值的範圍是6~37。
- 資料封包:長度域包含5個比特,有效值的範圍是0~31。
廣播封包和和資料封包的長度域有所不同,主要原因是:廣播封包除了最多31個位元組的資料之外,還必須要包含6個位元組的廣播裝置位址。6+31=37,是以需要6比特的長度域。
再次強調:廣播時必須要包含6個位元組的廣播裝置位址。
1.5 資料(AdvData)
廣播和掃面響應的資料格式如下圖所示,由有效資料部分和無效資料部分組成。
圖8:廣播和掃描響應的資料格式
1) 有效資料部分:包含N個AD Structure,每個AD Structure由Length,AD Type和AD Data組成。其中:
- Length:AD Type和AD Data的長度。
- AD Type:訓示AD Data資料的含義。
問題來了,我們怎麼知道有哪些AD Type?他們又表示什麼意義?可以通過下面2種方式檢視AD Type和他們表示的意義。
- 從官網查詢,但是需要是會員才可以查詢。
https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm
- 檢視Nordic的SDK中的定義,AD type的定義在程式的“ble_gap.h”頭檔案中。定義如下:
-
#define BLE_GAP_AD_TYPE_FLAGS 0x01
-
#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02
-
#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03
-
#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04
-
#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05
-
#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06
-
#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07
-
#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08
-
#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09
-
#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A
-
#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D
-
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E
-
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F
-
#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10
-
#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11
-
#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12
-
#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14
-
#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15
-
#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16
-
#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17
-
#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18
-
#define BLE_GAP_AD_TYPE_APPEARANCE 0x19
-
#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A
-
#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B
-
#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C
-
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D
-
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E
-
#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20
-
#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21
-
#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D
-
#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF
1.6 校驗
BLE采用的是24位CRC校驗。CRC對報頭、長度和資料進行計算。24位CRC的生成多項式如下:
2. 廣播包解析
通過上文的描述,我們對BLE廣播包有了大緻的了解,接下來我們用EN-Dongle捕獲一個心率計的廣播包,通過對實際廣播包的分析來了解BLE封包結構和廣播。廣播包捕獲實驗的硬體連接配接如下。
圖9:硬體連接配接
2.1 心率計程式下載下傳
2.1.1 下載下傳協定棧
SoftDevice必須使用nRFgo Studio下載下傳,打開nRFgo Studio,切換到“Program SoftDevice”頁籤。點選“Browse…”按鈕打開SoftDevice的HEX檔案(位于“…\BLE實驗\藍牙協定棧(SoftDevice)目錄下的” s110)。點選“Program”下載下傳程式。
2.1.1 下載下傳應用程式
應用程式可以用nRFgo Studio下載下傳,也可以在MDK中直接下載下傳調試,在這裡我們用nRFgo Studio下載下傳。切換到“Program Application”頁籤。點選“Browse…”按鈕打開應用程式的HEX檔案(位于“…\BLE實驗\ ble_app_beacon \pca10028\s110\arm5\_build”目錄下的 nrf51822_xxaa_s110.hex)。點選“Program”下載下傳程式。
2.2 捕獲廣播包
按照《藍牙4.0BLE抓包(一)》中的描述進行抓包,下面是我們捕獲一個心率計的廣播包。
圖10:捕獲的心率計廣播包
圖11:檢視廣播包傳輸的資料
2.3 分析廣播包
為了友善分析,我們先取出這個廣播包實際傳輸的資料,如圖9中所示。心率計完整的廣播封包如下:
D6 BE 89 8E 40 21 60 BF 8A B9 CD C5 0B 09 4E 6F 72 64 69 63 5F 48 52 4D 03 19 41 03 02 01 06 07 03 0D 18 0F 18 0A 18 EF A6 F0
2.3.1 接入位址
D6 BE 89 8E:接入位址,對廣播來說是固定值。注意一下這裡的位元組序,接入位址傳輸時是低位元組在前的。
2.3.2 PDU
q 40:廣播封包報頭。
l bit0~bit3是0000,說明廣播類型是ADV_IND,即通用廣播訓示。
l bit7(RxAdd)是0,bit7(TxAdd)是1,說明使用的是随機位址(random address)。Core_V4.2 P2584的2.3.1有詳細的描述。
q 21:長度,表示這個廣播的長度是33個位元組。
q 9A 3F 20 FB 74 C5:裝置位址,這裡使用的是随機靜态位址。
接下來就是廣播包最重要的部分了,稱之為AdvData,前面我們說過AdvData是N個AD Structure組層成,每個AD Structure的格式都是Length |AD Type|AD Data組成。
0B 09 4E 6F 72 64 69 63 5F 48 52 4D 03 19 41 03 02 01 06 07 03 0D 18 0F 18 0A 18
第一個位元組0B表示第一個AD Structure的長度是11個位元組,即第一個AD Structure是由0B加上緊跟着0B後面的11個位元組組成,是以,第一個AD Structure是:
0B 09 4E 6F 72 64 69 63 5F 48 52 4D
表1:第1個AD Structure的意義
Length | AD Type | AD Data |
0B | 09 | 4E 6F 72 64 69 63 5F 48 52 4D |
11位元組 | AD type為“完整的本地名稱” | 程式中定義的為”Nordic_HRM”對應的十六進制就是4E 6F 72 64 69 63 5F 48 52 4D |
第2個AD Structure是:03 19 41 03
表2:第2個AD Structure的意義
Length | AD Type | AD Data |
03 | 19 | 41 03 |
3位元組 | AD type為“外觀特性” | 外觀特性是一個16位的數值,由SIG定義,用來列舉裝置的外觀樣式,訓示裝置是普通手機,手環什麼的。 |
第3個AD Structure是:02 01 06
表3:第3個AD Structure的意義
Length | AD Type | AD Data |
02 | 01 | 06 |
2位元組 | AD type為“Flag” | flag說明了實體連接配接功能,比如有限發現模式,不支援經典藍牙等。 l bit 0: LE 有限發現模式。 l bit 1: LE 普通發現模式。 l bit 2: 不支援 BR/EDR。 l bit 3: 對 Same Device Capable(Controller) 同時支援 BLE 和 BR/EDR。 l bit 4: 對 Same Device Capable(Host) 同時支援 BLE 和 BR/EDR。 bit 5..7: 預留。 |
第4個AD Structure是:07 03 0D 18 0F 18 0A 18
表4:第4個AD Structure的意義
Length | AD Type | AD Data |
07 | 03 | 0D 18 0F 18 0A 18 |
7位元組 | AD type為“16bit Service uuid清單” | 該裝置支援的完整的16bit Service uuid清單。 l 180D:Heart Rate service UUID(心率服務UUID) l 180F:Battery service UUID(電池服務UUID) l 180A:Device Information service UUID(裝置資訊服務UUID) |
16bit UUID:
128位的UUID相當長,裝置間為了識别資料的類型需要發送長達16位元組的資料。為了提高傳輸效率,藍牙技術聯盟(SIG)定義了一個稱為“UUID基數”的128位通用唯一識别碼,結合一個較短的16位數使用。二者仍然遵循通用唯一識别碼的配置設定規則,隻不過在裝置間傳輸常用的UUID時,隻發送較短的16位版本,接收方收到後補上藍牙UUID基數即可。
藍牙UUID基數如下:
00000000 – 0000 – 1000 – 8000 – 008059B34FB
如要發送的16位UUID為0x2A01,完整的128的UUID便是:
00002A01 – 0000 – 1000 – 8000 – 008059B34FB
低功耗藍牙使用的那部分UUID被分為下列幾組:
l 0x1800 ~ 0x26FF:用作服務類通用唯一識别碼。
l 0x2700 ~ 0x27FF:用于辨別計量機關。
l 0x2800 ~ 0x28FF:用于區分屬性類型。
l 0x2900 ~ 0x29FF:用作特性描述。
l 0x2A00 ~ 0x7FFF:用于區分特性類型。
在程式的“ble_srv_common.h”檔案中定義了16bit service UUID,如下,當然也可以在SIG官網上查詢:
-
#define BLE_UUID_ALERT_NOTIFICATION_SERVICE 0x1811
-
#define BLE_UUID_BATTERY_SERVICE 0x180F
-
#define BLE_UUID_BLOOD_PRESSURE_SERVICE 0x1810
-
#define BLE_UUID_CURRENT_TIME_SERVICE 0x1805
-
#define BLE_UUID_CYCLING_SPEED_AND_CADENCE 0x1816
-
#define BLE_UUID_DEVICE_INFORMATION_SERVICE 0x180A
-
#define BLE_UUID_GLUCOSE_SERVICE 0x1808
-
#define BLE_UUID_HEALTH_THERMOMETER_SERVICE 0x1809
-
#define BLE_UUID_HEART_RATE_SERVICE 0x180D
-
#define BLE_UUID_HUMAN_INTERFACE_DEVICE_SERVICE 0x1812
-
#define BLE_UUID_IMMEDIATE_ALERT_SERVICE 0x1802
-
#define BLE_UUID_LINK_LOSS_SERVICE 0x1803
-
#define BLE_UUID_NEXT_DST_CHANGE_SERVICE 0x1807
-
#define BLE_UUID_PHONE_ALERT_STATUS_SERVICE 0x180E
-
#define BLE_UUID_REFERENCE_TIME_UPDATE_SERVICE 0x1806
-
#define BLE_UUID_RUNNING_SPEED_AND_CADENCE 0x1814
-
#define BLE_UUID_SCAN_PARAMETERS_SERVICE 0x1813
-
#define BLE_UUID_TX_POWER_SERVICE 0x1804
2.3.3 校驗
EF A6 F0:24位CRC。24位CRC的生成多項式如下,對CRC算法感興趣的朋友可以研究一下: