BLE 設備工作的第一步就是向外廣播數據。廣播數據中帶有設備相關的信息。本文主要說一下 BLE 的廣播中的數據的規範以及廣播包的解析。
廣播模式
BLE 中有兩種角色 Central 和 Peripheral ,也就是中心設備和外圍設備。中心設備可以主動連接外圍設備,外圍設備發送廣播或者被中心設備連接。外圍通過廣播被中心設備發現,廣播中帶有外圍設備自身的相關信息。
廣播包有兩種: 廣播包 (Advertising Data)和 響應包 (Scan Response),其中廣播包是每個設備必須廣播的,而響應包是可選的。 數據包的格式如下圖所示(圖片來自官方 Spec):每個包都是 31 字節,數據包中分爲有效數據(significant)和無效數據(non-significant)兩部分。
- 有效數據部分 :包含若干個廣播數據單元,稱爲 AD Structure 。如圖中所示,AD Structure 的組成是:第一個字節是長度值 Len ,表示接下來的 Len 個字節是數據部分。數據部分的第一個字節表示數據的類型 AD Type ,剩下的 Len - 1 個字節是真正的數據 AD data 。其中 AD type 非常關鍵,決定了 AD Data 的數據代表的是什麼和怎麼解析,這個在後面會詳細講;
- 無效數據部分 :因爲廣播包的長度必須是 31 個 byte,如果有效數據部分不到 31 自己,剩下的就用 0 補全。這部分的數據是無效的,解釋的時候,忽略即可。
廣播數據格式
所有的 AD type 的定義在文檔 Core Specification Supplement 中。 AD Type 包括如下類型:
定義 | 說明 | 備註 |
---|---|---|
#define GAP_ADTYPE_FLAGS 0x01 | Discovery Mode: @ref GAP_ADTYPE_FLAGS_MODES | 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: 預留。 |
#define GAP_ADTYPE_16BIT_MORE 0x02 | Service: More 16-bit UUIDs available | Service UUID: 廣播數據中一般都會把設備支持的 GATT Service 廣播出來,用來告訴外面本設備所支持的 Service。有三種類型的 UUID:16 bit, 32bit, 128 bit。廣播中,每種類型類型有有兩個類別:完整和非完整的。這樣就共有 6 種 AD Type。 服務的 UUID,通知中央設備什麼服務包括在此外圍設備 更多的16位可用UUID,但不是全部 |
#define GAP_ADTYPE_16BIT_COMPLETE 0x03 | Service: Complete list of 16-bit UUIDs | 服務的 UUID,通知中央設備什麼服務包括在此外圍設備 可用16位uuid的完整列表 |
#define GAP_ADTYPE_32BIT_MORE 0x04 | Service: More 32-bit UUIDs available | 服務的 UUID,通知中央設備什麼服務包括在此外圍設備 更多的32位可用UUID,但不是全部 |
#define GAP_ADTYPE_32BIT_COMPLETE 0x05 | Service: Complete list of 32-bit UUIDs | 服務的 UUID,通知中央設備什麼服務包括在此外圍設備 可用32位uuid的完整列表 |
#define GAP_ADTYPE_128BIT_MORE 0x06 | Service: More 128-bit UUIDs available | 服務的 UUID,通知中央設備什麼服務包括在此外圍設備 更多的128位可用UUID,但不是全部 |
#define GAP_ADTYPE_128BIT_COMPLETE 0x07 | Service: Complete list of 128-bit UUIDs | 服務的 UUID,通知中央設備什麼服務包括在此外圍設備 可用128位uuid的完整列表 |
#define GAP_ADTYPE_LOCAL_NAME_SHORT 0x08 | Shortened local name | 簡稱 |
#define GAP_ADTYPE_LOCAL_NAME_COMPLETE 0x09 | Complete local name | 完整名稱 |
#define GAP_ADTYPE_POWER_LEVEL 0x0A | TX Power Level: 0xXX: -127 to +127 dBm | 發送功率 |
#define GAP_ADTYPE_OOB_CLASS_OF_DEVICE 0x0D | Simple Pairing OOB Tag: Class of device (3 octets) | out-of-band,OOB- 帶外數據 簡單配對OOB標籤:設備類 |
#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_HASHC 0x0E | Simple Pairing OOB Tag: Simple Pairing Hash C (16 octets) | 簡單配對OOB標籤:簡單配對散列C |
#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_RANDR 0x0F | Simple Pairing OOB Tag: Simple Pairing Randomizer R (16 octets) | 簡單配對OOB標籤:簡單配對隨機器R |
#define GAP_ADTYPE_SM_TK 0x10 | Security Manager TK Value | 安全管理器TK值 |
#define GAP_ADTYPE_SM_OOB_FLAG 0x11 | Security Manager OOB Flags | 安全管理器OOB標誌 |
#define GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE 0x12 | Min and Max values of tde connection interval (2 octets Min, 2 octets Max) (0xFFFF indicates no conn interval min or max) | 從機連接間隔的最小值和最大值 |
#define GAP_ADTYPE_SIGNED_DATA 0x13 | Signed Data field | 簽名數據字段 |
#define GAP_ADTYPE_SERVICES_LIST_16BIT 0x14 | Service Solicitation: list of 16-bit Service UUIDs | 服務搜尋:外圍設備可以要請中心設備提供相應的 Service 服務徵集:16位服務uuid列表 |
#define GAP_ADTYPE_SERVICES_LIST_128BIT 0x15 | Service Solicitation: list of 128-bit Service UUIDs | 服務徵集:128位服務uuid列表 |
#define GAP_ADTYPE_SERVICE_DATA 0x16 | Service Data - 16-bit UUID | 服務數據- 16位UUID |
#define GAP_ADTYPE_PUBLIC_TARGET_ADDR 0x17 | Public Target Address | 公共目標地址 表示希望這個廣播包被指定的目標設備處理,此設備綁定了公開地址,DATA 是目標地址列表,每個地址 6 字節。 |
#define GAP_ADTYPE_RANDOM_TARGET_ADDR 0x18 | Random Target Address | 隨機目標地址 表示希望這個廣播包被指定的目標設備處理,此設備綁定了隨機地址,DATA 是目標地址列表,每個地址 6 字節。 |
#define GAP_ADTYPE_APPEARANCE 0x19 | Appearance | 外觀特性 |
#define GAP_ADTYPE_ADV_INTERVAL 0x1A | Advertising Interval | 廣播時間間隔 |
#define GAP_ADTYPE_LE_BD_ADDR 0x1B | LE Bluetootd Device Address | LE 藍牙設備地址 |
#define GAP_ADTYPE_LE_ROLE 0x1C | LE Role | LE 角色 |
#define GAP_ADTYPE_SIMPLE_PAIRING_HASHC_256 0x1D | Simple Pairing Hash C-256 | 簡單配對哈希C-256 |
#define GAP_ADTYPE_SIMPLE_PAIRING_RANDR_256 0x1E | Simple Pairing Randomizer R-256 | 簡單配對隨機發生器R-256 |
#define GAP_ADTYPE_SERVICE_DATA_32BIT 0x20 | Service Data - 32-bit UUID | 服務數據- 32位UUID |
#define GAP_ADTYPE_SERVICE_DATA_128BIT 0x21 | Service Data - 128-bit UUID | 服務數據- 128位UUID |
#define GAP_ADTYPE_3D_INFO_DATA 0x3D | 3D Information Data | 三維信息數據 |
#define GAP_ADTYPE_MANUFACTURER_SPECIFIC 0xFF | Manufacturer Specific Data: first 2 octets contain tde Company Identifier Code followed by tde additional manufacturer specific data | 特定於製造商的數據:前兩個八位包含設備公司標識碼,然後是設備附加的特定於製造商的數據 |
低功耗藍牙的發現模式主要分爲有限可發現模式和普通(無限)可發現模式。
注意發現模式的定義必須在廣播數據的開頭處,不能在掃描迴應數據中定義。
設備就處於有限可發現模式,當設備處於有限可發現模式時,很多人以及網上的一些資料提到廣播會在使能打開之後的 30.72s 之後停止廣播。但是實際測試並不是這樣,而是180s
在有限可發現模式下,默認是180s之後停止廣播,如果想設置這個值,可以用下面的方式:GAP_SetParamValue(TGAP_LIM_ADV_TIMEOUT, ADV_TIMEOUT);
爲了實現在設置的時間或者是默認的時間之後,廣播停止,過了一段時間(默認應該是 30s 之後),廣播又重新開啓了。出現這種情況的時候應關注“GAPROLE_ADVERT_OFF_TIME”的設置,如果不設置該值,就會出現停止廣播 30s(默認值)之後重新廣播的情況。
最常用的場景,一直持續廣播
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
// Duration of slow advertising duration in ms (set to 0 for continuous advertising)
#define DEFAULT_SLOW_ADV_DURATION 0
GAP_SetParamValue( TGAP_GEN_DISC_ADV_MIN, DEFAULT_SLOW_ADV_DURATION );
廣播使能開啓之後,限制廣播在 30s 之後停止,並且在應用部分沒有使能打開的情況下不再廣播
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_LIMITED
uint16 gapRole_AdvertOffTime = 0;
GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );//GAPROLE_ADVERT_OFF_TIME設置的時間單位是ms,默認是30s
uint16 ADV_TIMEOUT = 30;
GAP_SetParamValue( TGAP_LIM_ADV_TIMEOUT, ADV_TIMEOUT );//設置的單位是s,不設置的話,默認是180s
廣播使能開啓之後,限制廣播在 20s 之後停止,然後過 15s 之後自動重新廣播,如此反覆
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_LIMITED
uint16 gapRole_AdvertOffTime = 15000;
GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );//GAPROLE_ADVERT_OFF_TIME設置的時間單位是ms,默認是30s
uint16 ADV_TIMEOUT = 20;
GAP_SetParamValue( TGAP_LIM_ADV_TIMEOUT, ADV_TIMEOUT );//設置的單位是s,不設置的話,默認是180s