藍牙4.0BLE抓包(二) – 廣播包解析

在使用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”頭文件中。定義如下:
複製代碼
 1 #define BLE_GAP_AD_TYPE_FLAGS                               0x01 /**< Flags for discoverability. */ 2 #define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE   0x02 /**< Partial list of 16 bit service UUIDs. */ 3 #define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE         0x03 /**< Complete list of 16 bit service UUIDs. */ 4 #define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE   0x04 /**< Partial list of 32 bit service UUIDs. */ 5 #define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE         0x05 /**< Complete list of 32 bit service UUIDs. */ 6 #define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE  0x06 /**< Partial list of 128 bit service UUIDs. */ 7 #define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE        0x07 /**< Complete list of 128 bit service UUIDs. */ 8 #define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME                    0x08 /**< Short local device name. */ 9 #define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME                 0x09 /**< Complete local device name. */10 #define BLE_GAP_AD_TYPE_TX_POWER_LEVEL                      0x0A /**< Transmit power level. */11 #define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE                     0x0D /**< Class of device. */12 #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C               0x0E /**< Simple Pairing Hash C. */13 #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R         0x0F /**< Simple Pairing Randomizer R. */14 #define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE           0x10 /**< Security Manager TK Value. */15 #define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS          0x11 /**< Security Manager Out Of Band Flags. */16 #define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE     0x12 /**< Slave Connection Interval Range. */17 #define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT       0x14 /**< List of 16-bit Service Solicitation UUIDs. */18 #define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT      0x15 /**< List of 128-bit Service Solicitation UUIDs. */19 #define BLE_GAP_AD_TYPE_SERVICE_DATA                        0x16 /**< Service Data - 16-bit UUID. */20 #define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS               0x17 /**< Public Target Address. */21 #define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS               0x18 /**< Random Target Address. */22 #define BLE_GAP_AD_TYPE_APPEARANCE                          0x19 /**< Appearance. */23 #define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL                0x1A /**< Advertising Interval. */ 24 #define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS         0x1B /**< LE Bluetooth Device Address. */25 #define BLE_GAP_AD_TYPE_LE_ROLE                             0x1C /**< LE Role. */26 #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256            0x1D /**< Simple Pairing Hash C-256. */27 #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256      0x1E /**< Simple Pairing Randomizer R-256. */28 #define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID             0x20 /**< Service Data - 32-bit UUID. */29 #define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID            0x21 /**< Service Data - 128-bit UUID. */30 #define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA                 0x3D /**< 3D Information Data. */31 #define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA          0xFF /**< Manufacturer Specific Data. */
複製代碼

 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 4021 60 BF 8A B9 CDC5 0B 09 4E 6F 72 64 69 63 5F 48 52 4D 03 19 41 03 02 01 0607 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,說明使用的是隨機地址(randomaddress)。Core_V4.2 P25842.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官網上查詢:

複製代碼
 1 #define BLE_UUID_ALERT_NOTIFICATION_SERVICE                      0x1811     /**< Alert Notification service UUID. */ 2 #define BLE_UUID_BATTERY_SERVICE                                 0x180F     /**< Battery service UUID. */ 3 #define BLE_UUID_BLOOD_PRESSURE_SERVICE                          0x1810     /**< Blood Pressure service UUID. */ 4 #define BLE_UUID_CURRENT_TIME_SERVICE                            0x1805     /**< Current Time service UUID. */ 5 #define BLE_UUID_CYCLING_SPEED_AND_CADENCE                       0x1816     /**< Cycling Speed and Cadence service UUID. */ 6 #define BLE_UUID_DEVICE_INFORMATION_SERVICE                      0x180A     /**< Device Information service UUID. */ 7 #define BLE_UUID_GLUCOSE_SERVICE                                 0x1808     /**< Glucose service UUID. */ 8 #define BLE_UUID_HEALTH_THERMOMETER_SERVICE                      0x1809     /**< Health Thermometer service UUID. */ 9 #define BLE_UUID_HEART_RATE_SERVICE                              0x180D     /**< Heart Rate service UUID. */10 #define BLE_UUID_HUMAN_INTERFACE_DEVICE_SERVICE                  0x1812     /**< Human Interface Device service UUID. */11 #define BLE_UUID_IMMEDIATE_ALERT_SERVICE                         0x1802     /**< Immediate Alert service UUID. */12 #define BLE_UUID_LINK_LOSS_SERVICE                               0x1803     /**< Link Loss service UUID. */13 #define BLE_UUID_NEXT_DST_CHANGE_SERVICE                         0x1807     /**< Next Dst Change service UUID. */14 #define BLE_UUID_PHONE_ALERT_STATUS_SERVICE                      0x180E     /**< Phone Alert Status service UUID. */15 #define BLE_UUID_REFERENCE_TIME_UPDATE_SERVICE                   0x1806     /**< Reference Time Update service UUID. */16 #define BLE_UUID_RUNNING_SPEED_AND_CADENCE                       0x1814     /**< Running Speed and Cadence service UUID. */17 #define BLE_UUID_SCAN_PARAMETERS_SERVICE                         0x1813     /**< Scan Parameters service UUID. */18 #define BLE_UUID_TX_POWER_SERVICE                                0x1804     /**< TX Power service UUID. */
複製代碼

 

2.3.3 校驗

  EF A6 F0:24位CRC。24位CRC的生成多項式如下,對CRC算法感興趣的朋友可以研究一下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章