蓝牙协议栈HCI EIR(EXTENDED INQUIRY RESPONSE)扩展搜索响应
零. 概述
本文章主要講下藍(lán)牙協(xié)議棧HCI EIR的搜索的注冊(讓別人搜索到我們的EIR)以及主動搜索對方的EIR信息
一. 聲明
本專欄文章我們會以連載的方式持續(xù)更新,本專欄計劃更新內(nèi)容如下:
第一篇:藍(lán)牙綜合介紹 ,主要介紹藍(lán)牙的一些概念,產(chǎn)生背景,發(fā)展軌跡,市面藍(lán)牙介紹,以及藍(lán)牙開發(fā)板介紹。
第二篇:Transport層介紹,主要介紹藍(lán)牙協(xié)議棧跟藍(lán)牙芯片之前的硬件傳輸協(xié)議,比如基于UART的H4,H5,BCSP,基于USB的H2等
第三篇:傳統(tǒng)藍(lán)牙controller介紹,主要介紹傳統(tǒng)藍(lán)牙芯片的介紹,包括射頻層(RF),基帶層(baseband),鏈路管理層(LMP)等
第四篇:傳統(tǒng)藍(lán)牙host介紹,主要介紹傳統(tǒng)藍(lán)牙的協(xié)議棧,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的協(xié)議吧。
第五篇:低功耗藍(lán)牙controller介紹,主要介紹低功耗藍(lán)牙芯片,包括物理層(PHY),鏈路層(LL)
第六篇:低功耗藍(lán)牙host介紹,低功耗藍(lán)牙協(xié)議棧的介紹,包括HCI,L2CAP,ATT,GATT,SM等
第七篇:藍(lán)牙芯片介紹,主要介紹一些藍(lán)牙芯片的初始化流程,基于HCI vendor command的擴(kuò)展
第八篇:附錄,主要介紹以上常用名詞的介紹以及一些特殊流程的介紹等。
另外,開發(fā)板如下所示,對于想學(xué)習(xí)藍(lán)牙協(xié)議棧的最好人手一套。以便更好的學(xué)習(xí)藍(lán)牙協(xié)議棧,相信我,學(xué)完這一套視頻你將擁有修改任何協(xié)議棧的能力(比如Linux下的bluez,Android下的bluedroid)。
-------------------------------------------------------------------------------------------------------------------------
CSDN學(xué)院鏈接(進(jìn)入選擇你想要學(xué)習(xí)的課程):https://edu.csdn.net/lecturer/5352?spm=1002.2001.3001.4144
藍(lán)牙交流扣扣群:970324688
Github代碼:https://github.com/sj15712795029/bluetooth_stack
入手開發(fā)板:https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22329603896.18.5aeb41f973iStr&id=622836061708
藍(lán)牙學(xué)習(xí)目錄:https://blog.csdn.net/XiaoXiaoPengBo/article/details/107727900
--------------------------------------------------------------------------------------------------------------------------
二.?EIR注冊以及extern inquiry掃描對方的EIR
1. EIR概念介紹
在了解EIR之前,我們先來說下搜索,在之前我們也說過搜索分為3中類型,標(biāo)準(zhǔn)/RSSI/EIR
那區(qū)別在于標(biāo)準(zhǔn)搜索只會附帶以下信息
那RSSI就是在標(biāo)準(zhǔn)搜索的基礎(chǔ)上會附帶RSSI,那么EIR(EXTENDED INQUIRY RESPONSE)就是在這些基礎(chǔ)上會附帶額外的一些信息,比如remote name,對方支持的UUID等(前提是對方注冊了EIR)。
EIR信息不管是否有效數(shù)據(jù)是多少byte,最終都要240byte
EIR Data Structure的格式為:1Byte length+nByte type(一般是1byte)+n byte EIR raw data
其中l(wèi)ength包括Type + raw data
EIR可以包含的信息有如下(并不是所有的都會用在EIR中,以下是SIG的data type):
| 0x01 | ?Flags? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.3 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.3 and 18.1 (v4.0)Core Specification Supplement, Part A, section 1.3 |
| 0x02 | ?Incomplete List of 16-bit Service Class UUIDs? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.1 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.1 and 18.2 (v4.0)Core Specification Supplement, Part A, section 1.1 |
| 0x03 | ?Complete List of 16-bit Service Class UUIDs? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.1 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.1 and 18.2 (v4.0)Core Specification Supplement, Part A, section 1.1 |
| 0x04 | ?Incomplete List of 32-bit Service Class UUIDs? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.1 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, section 18.2 (v4.0)Core Specification Supplement, Part A, section 1.1 |
| 0x05 | ?Complete List of 32-bit Service Class UUIDs? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.1 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, section 18.2 (v4.0)Core Specification Supplement, Part A, section 1.1 |
| 0x06 | ?Incomplete List of 128-bit Service Class UUIDs? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.1 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.1 and 18.2 (v4.0)Core Specification Supplement, Part A, section 1.1 |
| 0x07 | ?Complete List of 128-bit Service Class UUIDs? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.1 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.1 and 18.2 (v4.0)Core Specification Supplement, Part A, section 1.1 |
| 0x08 | ?Shortened Local Name? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.2 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.2 and 18.4 (v4.0)Core Specification Supplement, Part A, section 1.2 |
| 0x09 | ?Complete Local Name? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.2 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.2 and 18.4 (v4.0)Core Specification Supplement, Part A, section 1.2 |
| 0x0A | ?Tx Power Level? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.5 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.5 and 18.3 (v4.0)Core Specification Supplement, Part A, section 1.5 |
| 0x0D | ?Class of Device? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.6 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.5 and 18.5 (v4.0)Core Specification Supplement, Part A, section 1.6 |
| 0x0E | ?Simple Pairing Hash C? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.6 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.5 and 18.5 (v4.0) |
| 0x0E | ?Simple Pairing Hash C-192? | Core Specification Supplement, Part A, section 1.6 |
| 0x0F | ?Simple Pairing Randomizer R? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.6 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.5 and 18.5 (v4.0) |
| 0x0F | ?Simple Pairing Randomizer R-192? | Core Specification Supplement, Part A, section 1.6 |
| 0x10 | ?Device ID? | Device ID Profile v1.3 or later |
| 0x10 | ?Security Manager TK Value? | Bluetooth Core Specification:Vol. 3, Part C, sections 11.1.7 and 18.6 (v4.0)Core Specification Supplement, Part A, section 1.8 |
| 0x11 | ?Security Manager Out of Band Flags? | Bluetooth Core Specification:Vol. 3, Part C, sections 11.1.6 and 18.7 (v4.0)Core Specification Supplement, Part A, section 1.7 |
| 0x12 | ?Slave Connection Interval Range? | Bluetooth Core Specification:Vol. 3, Part C, sections 11.1.8 and 18.8 (v4.0)Core Specification Supplement, Part A, section 1.9 |
| 0x14 | ?List of 16-bit Service Solicitation UUIDs? | Bluetooth Core Specification:Vol. 3, Part C, sections 11.1.9 and 18.9 (v4.0)Core Specification Supplement, Part A, section 1.10 |
| 0x15 | ?List of 128-bit Service Solicitation UUIDs? | Bluetooth Core Specification:Vol. 3, Part C, sections 11.1.9 and 18.9 (v4.0)Core Specification Supplement, Part A, section 1.10 |
| 0x16 | ?Service Data? | Bluetooth Core Specification:Vol. 3, Part C, sections 11.1.10 and 18.10 (v4.0) |
| 0x16 | ?Service Data - 16-bit UUID? | Core Specification Supplement, Part A, section 1.11 |
| 0x17 | ?Public Target Address? | Bluetooth Core Specification:Core Specification Supplement, Part A, section 1.13 |
| 0x18 | ?Random Target Address? | Bluetooth Core Specification:Core Specification Supplement, Part A, section 1.14 |
| 0x19 | ?Appearance? | Bluetooth Core Specification:Core Specification Supplement, Part A, section 1.12 |
| 0x1A | ?Advertising Interval? | Bluetooth Core Specification:Core Specification Supplement, Part A, section 1.15 |
| 0x1B | ?LE Bluetooth Device Address? | Core Specification Supplement, Part A, section 1.16 |
| 0x1C | ?LE Role? | Core Specification Supplement, Part A, section 1.17 |
| 0x1D | ?Simple Pairing Hash C-256? | Core Specification Supplement, Part A, section 1.6 |
| 0x1E | ?Simple Pairing Randomizer R-256? | Core Specification Supplement, Part A, section 1.6 |
| 0x1F | ?List of 32-bit Service Solicitation UUIDs? | Core Specification Supplement, Part A, section 1.10 |
| 0x20 | ?Service Data - 32-bit UUID? | Core Specification Supplement, Part A, section 1.11 |
| 0x21 | ?Service Data - 128-bit UUID? | Core Specification Supplement, Part A, section 1.11 |
| 0x22 | ?LE Secure Connections Confirmation Value? | Core Specification Supplement Part A, Section 1.6 |
| 0x23 | ?LE Secure Connections Random Value? | Core Specification Supplement Part A, Section 1.6 |
| 0x24 | ?URI? | Bluetooth Core Specification:Core Specification Supplement, Part A, section 1.18 |
| 0x25 | ?Indoor Positioning? | Indoor Positioning Service v1.0 or later |
| 0x26 | ?Transport Discovery Data? | Transport Discovery Service v1.0 or later |
| 0x27 | ?LE Supported Features? | Core Specification Supplement, Part A, Section 1.19 |
| 0x28 | ?Channel Map Update Indication? | Core Specification Supplement, Part A, Section 1.20 |
| 0x29 | ?PB-ADV? | Mesh Profile Specification Section 5.2.1 |
| 0x2A | ?Mesh Message? | Mesh Profile Specification Section 3.3.1 |
| 0x2B | ?Mesh Beacon? | Mesh Profile Specification Section 3.9 |
| 0x2C | ?BIGInfo? | ? |
| 0x2D | ?Broadcast_Code? | ? |
| 0x3D | ?3D Information Data? | 3D Synchronization Profile, v1.0 or later |
| 0xFF | ?Manufacturer Specific Data? | Bluetooth Core Specification:Vol. 3, Part C, section 8.1.4 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.4 and 18.11 (v4.0)Core Specification Supplement, Part A, section 1.4 |
以上介紹都在文檔CSS_V9中,想詳細(xì)看的可以看下
2.?EIR注冊,方便被對方搜索到?
假設(shè)我們僅僅支持HFP HF的UUID,那么我們僅僅注冊HFP的UUID,藍(lán)牙本地名稱
1)EIR數(shù)據(jù)組包(我們只開了PROFILE_HFP_ENABLE的宏)
static err_t bt_ass_eir_data() {uint8_t data_pos =0;uint8_t len = 0;#if 1/* local name */len = strlen(BT_LOCAL_NAME);eir_data[data_pos++] = len + 1;eir_data[data_pos++] = BT_DT_COMPLETE_LOCAL_NAME;memcpy(eir_data+data_pos,BT_LOCAL_NAME,strlen(BT_LOCAL_NAME));data_pos += strlen(BT_LOCAL_NAME); #endif/* 16 bit UUID */len = 1; #if PROFILE_DID_ENABLElen += 2; #endif #if PROFILE_HFP_ENABLElen += 2; #endif #if PROFILE_SPP_ENABLElen += 2; #endif #if PROFILE_A2DP_ENABLElen += 2; #endif #if PROFILE_AVRCP_ENABLElen += 2; #endifeir_data[data_pos++] = len;eir_data[data_pos++] = BT_DT_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS; #if PROFILE_DID_ENABLEeir_data[data_pos++] = BT_SERVICE_CLASS_PNP_INFORMATION & 0xff;eir_data[data_pos++] = (BT_SERVICE_CLASS_PNP_INFORMATION>>8) & 0xff; #endif #if PROFILE_HFP_ENABLEeir_data[data_pos++] = BT_SERVICE_CLASS_HANDSFREE & 0xff;eir_data[data_pos++] = (BT_SERVICE_CLASS_HANDSFREE>>8) & 0xff; #endif #if PROFILE_SPP_ENABLEeir_data[data_pos++] = BT_SERVICE_CLASS_SERIAL_PORT & 0xff;eir_data[data_pos++] = (BT_SERVICE_CLASS_SERIAL_PORT>>8) & 0xff; #endif #if PROFILE_A2DP_ENABLEeir_data[data_pos++] = BT_SERVICE_CLASS_AUDIO_SINK & 0xff;eir_data[data_pos++] = (BT_SERVICE_CLASS_AUDIO_SINK>>8) & 0xff; #endif #if PROFILE_AVRCP_ENABLEeir_data[data_pos++] = BT_SERVICE_CLASS_AV_REMOTE_CONTROL & 0xff;eir_data[data_pos++] = (BT_SERVICE_CLASS_AV_REMOTE_CONTROL>>8) & 0xff; #endif/* Device ID */ #if PROFILE_DID_ENABLEeir_data[data_pos++] = 9;eir_data[data_pos++] = BT_DT_DEVICE_ID;eir_data[data_pos++] = DID_VENDOR_ID_SOURCE_VALUE & 0xff;eir_data[data_pos++] = (DID_VENDOR_ID_SOURCE_VALUE>>8) & 0xff;eir_data[data_pos++] = DID_VENDOR_ID_VALUE & 0xff;eir_data[data_pos++] = (DID_VENDOR_ID_VALUE>>8) & 0xff;eir_data[data_pos++] = DID_PRODUCT_ID_VALUE & 0xff;eir_data[data_pos++] = (DID_PRODUCT_ID_VALUE>>8) & 0xff;eir_data[data_pos++] = DID_VERSION_ID_VALUE & 0xff;eir_data[data_pos++] = (DID_VERSION_ID_VALUE>>8) & 0xff; #endifreturn 0; }2) HCI寫EIR
err_t bt_stack_worked(void *arg) {printf("bt_stack_worked\r\n");bt_ass_eir_data();hci_write_eir(eir_data);return 0; }其中hci_write_eir的函數(shù)實現(xiàn)如下:
err_t hci_write_eir(uint8_t *eir_data) {struct bt_pbuf_t *p;if((p = bt_pbuf_alloc(BT_TRANSPORT_TYPE, HCI_WRITE_EIR_PLEN, BT_PBUF_RAM)) == NULL){BT_HCI_TRACE_ERROR("ERROR:file[%s],function[%s],line[%d] bt_pbuf_alloc fail\n",__FILE__,__FUNCTION__,__LINE__);return BT_ERR_MEM;}/* Assembling command packet */p = hci_cmd_ass(p, HCI_WRITE_EIR, HCI_HOST_C_N_BB, HCI_WRITE_EIR_PLEN);/* Assembling cmd prameters */((uint8_t *)p->payload)[3] = 0x01; /* FEC is required */memset(((uint8_t *)p->payload)+4,0,240);memcpy(((uint8_t *)p->payload)+4,eir_data,240);phybusif_output(p, p->tot_len,PHYBUSIF_PACKET_TYPE_CMD);bt_pbuf_free(p);return BT_ERR_OK; }我們來看下轉(zhuǎn)的btsnoop架設(shè)看一下我們用HCI寫EIR的效果
可以看到我們設(shè)置上了Local Name以及HFP的UUID
我們來抓一個air log看下EIR數(shù)據(jù)
可以看到EIR data是在baseband(基帶層)層抓到的
3.?extern inquiry,搜索到對方的EIR信息
要實現(xiàn)Extern inquiry掃描,那么需要做三個步驟:
步驟 1) 在藍(lán)牙初始化的時候write inquiry mode
我們首先來介紹下這個HCI command
參數(shù):Inquiry mode
我們來看下代碼
err_t hci_write_inquiry_mode(uint8_t inquiry_mode) {struct bt_pbuf_t *p;if((p = bt_pbuf_alloc(BT_TRANSPORT_TYPE, HCI_W_INQUIRY_MODE_LEN, BT_PBUF_RAM)) == NULL){BT_HCI_TRACE_ERROR("ERROR:file[%s],function[%s],line[%d] bt_pbuf_alloc fail\n",__FILE__,__FUNCTION__,__LINE__);return BT_ERR_MEM;}/* Assembling command packet */p = hci_cmd_ass(p, HCI_WRITE_INQUIRY_MODE, HCI_HOST_C_N_BB, HCI_W_INQUIRY_MODE_LEN);((uint8_t *)p->payload)[3] = inquiry_mode;phybusif_output(p, p->tot_len,PHYBUSIF_PACKET_TYPE_CMD);bt_pbuf_free(p);return BT_ERR_OK; }其中入?yún)⑽覀兌x有以下類型,而我們選擇INQUIRY_MODE_EIR
#define INQUIRY_MODE_STANDARD 0 #define INQUIRY_MODE_RSSI 1 #define INQUIRY_MODE_EIR 2步驟2)執(zhí)行inquiry command
此步驟跟前面搜索的一樣,不做介紹,我們直接來看下第三個步驟
步驟3)接收inquiry with EIR data
我們首先來看下我們的代碼
case HCI_INQUIRY_RESULT:case HCI_EXT_INQ_RESULT:for(i=0; i<((uint8_t *)p->payload)[0]; i++){resp_offset = i*14;BT_HCI_TRACE_DEBUG("hci_event_input: Inquiry result %d\nBD_ADDR: 0x",i);for(i = 0; i < BD_ADDR_LEN; i++){BT_HCI_TRACE_DEBUG("%x",((uint8_t *)p->payload)[1+resp_offset+i]);}BT_HCI_TRACE_DEBUG("\n");BT_HCI_TRACE_DEBUG("Page_Scan_Rep_Mode: 0x%x\n",((uint8_t *)p->payload)[7+resp_offset]);BT_HCI_TRACE_DEBUG("Class_of_Dev: 0x%x 0x%x 0x%x\n",((uint8_t *)p->payload)[10+resp_offset],((uint8_t *)p->payload)[11+resp_offset], ((uint8_t *)p->payload)[12+resp_offset]);BT_HCI_TRACE_DEBUG("Clock_Offset: 0x%x%x\n",((uint8_t *)p->payload)[13+resp_offset],((uint8_t *)p->payload)[14+resp_offset]);bdaddr = (void *)(((uint8_t *)p->payload)+(1+resp_offset));if((inqres = bt_memp_malloc(MEMP_HCI_INQ)) != NULL){bd_addr_set(&(inqres->bdaddr), bdaddr);inqres->psrm = ((uint8_t *)p->payload)[7+resp_offset];inqres->psm = ((uint8_t *)p->payload)[9+resp_offset];memcpy(inqres->cod, ((uint8_t *)p->payload)+10+resp_offset, 3);inqres->co = *((uint16_t *)(((uint8_t *)p->payload)+13+resp_offset));if(evhdr->code == HCI_EXT_INQ_RESULT){uint8_t temp_rssi = ((uint8_t *)p->payload)[14+resp_offset];uint8_t *eir_data = ((uint8_t *)p->payload) + 15;uint8_t *temp_eir_data = eir_data;if(temp_rssi && 0x80) /* negative rssi */inqres->rssi = ((int8_t)(temp_rssi & (~0x80)) -128)&0xff;elseinqres->rssi = temp_rssi;while(temp_eir_data[0] != 0){uint8_t eir_element_len = temp_eir_data[0];uint8_t eir_element_type = temp_eir_data[1];if(eir_element_type == BT_DT_COMPLETE_LOCAL_NAME){memset(inqres->remote_name,0,HCI_REMOTE_NAME_LEN);memcpy(inqres->remote_name,temp_eir_data+2,eir_element_len-1);break;}temp_eir_data += eir_element_len + 1;}}HCI_REG(&(pcb->ires), inqres);HCI_EVENT_INQ_RESULT(pcb,inqres,ret);}else{BT_HCI_TRACE_ERROR("ERROR:file[%s],function[%s],line[%d] bt_memp_malloc fail\n",__FILE__,__FUNCTION__,__LINE__);}}break;可以看到雖然普通的inquiry result跟extern inquiry result是不一樣的,我們的代碼還是放在一起解析。
我們來看下btsnoop,以一個K2的名稱的藍(lán)牙音響為例。
我們來看下air log
EIR的雖然方便使用,不需要普通inquiry + HCI get remote name去配合獲取到remote的名字,但是在使用過程中要注意幾點:
1)Extern inquiry的結(jié)果會反復(fù)上來(有重復(fù)),需要協(xié)議棧過濾
可以看到同樣的藍(lán)牙地址,同樣的藍(lán)牙名稱,但是RSSI不同,在同一次搜索中會上來幾次
2)Extern inquiry的搜索可能有的時候不帶EIR數(shù)據(jù)
可以看到同樣的藍(lán)牙地址,有的時候并沒有上來EIR的data
?
總結(jié)
以上是生活随笔為你收集整理的蓝牙协议栈HCI EIR(EXTENDED INQUIRY RESPONSE)扩展搜索响应的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基础优化 标题优化 上下架注意事项 流量
- 下一篇: Flume之HDFS Sink 的参数解