蓝牙协议栈HCI EIR(EXTENDED INQUIRY RESPONSE)扩展搜索响应

蓝牙协议栈HCI EIR(EXTENDED INQUIRY RESPONSE)扩展搜索响应零 概述 本文章主要讲下蓝牙协议栈 HCI EIR 的搜索的注册 让别人搜索到我们的 EIR 以及主动搜索对方的 EIR 信息 一 声明 本专栏文章我们会以连载的方式持续更新 本专栏计划更新内容如下 第一篇 蓝牙综合介绍 主要介绍蓝牙的一些概念 产生背景 发展轨迹

大家好,我是讯享网,很高兴认识大家。

零. 概述

本文章主要讲下蓝牙协议栈HCI EIR的搜索的注册(让别人搜索到我们的EIR)以及主动搜索对方的EIR信息

一. 声明

本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下:


讯享网

第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。

第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的H4,H5,BCSP,基于USB的H2等

第三篇:传统蓝牙controller介绍,主要介绍传统蓝牙芯片的介绍,包括射频层(RF),基带层(baseband),链路管理层(LMP)等

第四篇:传统蓝牙host介绍,主要介绍传统蓝牙的协议栈,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的协议吧。

第五篇:低功耗蓝牙controller介绍,主要介绍低功耗蓝牙芯片,包括物理层(PHY),链路层(LL)

第六篇:低功耗蓝牙host介绍,低功耗蓝牙协议栈的介绍,包括HCI,L2CAP,ATT,GATT,SM等

第七篇:蓝牙芯片介绍,主要介绍一些蓝牙芯片的初始化流程,基于HCI vendor command的扩展

第八篇:附录,主要介绍以上常用名词的介绍以及一些特殊流程的介绍等。

另外,开发板如下所示,对于想学习蓝牙协议栈的最好人手一套。以便更好的学习蓝牙协议栈,相信我,学完这一套视频你将拥有修改任何协议栈的能力(比如Linux下的bluez,Android下的bluedroid)。

-------------------------------------------------------------------------------------------------------------------------

CSDN学院链接(进入选择你想要学习的课程):https://edu.csdn.net/lecturer/5352?spm=1002.2001.3001.4144

蓝牙交流扣扣群:

Github代码:https://github.com/sj/bluetooth_stack

入手开发板:https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22329603896.18.5aeb41f973iStr&id=622836061708

蓝牙学习目录:https://blog.csdn.net/XiaoXiaoPengBo/article/details/

--------------------------------------------------------------------------------------------------------------------------

二. EIR注册以及extern inquiry扫描对方的EIR

1. EIR概念介绍

在了解EIR之前,我们先来说下搜索,在之前我们也说过搜索分为3中类型,标准/RSSI/EIR

那区别在于标准搜索只会附带以下信息

那RSSI就是在标准搜索的基础上会附带RSSI,那么EIR(EXTENDED INQUIRY RESPONSE)就是在这些基础上会附带额外的一些信息,比如remote name,对方支持的UUID等(前提是对方注册了EIR)。

EIR信息不管是否有效数据是多少byte,最终都要240byte

EIR Data Structure的格式为:1Byte length+nByte type(一般是1byte)+n byte EIR raw data

其中length包括Type + raw data

EIR可以包含的信息有如下(并不是所有的都会用在EIR中,以下是SIG的data type):

Data Type Value Data Type Name Reference for Definition
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中,想详细看的可以看下

2. EIR注册,方便被对方搜索到 

假设我们仅仅支持HFP HF的UUID,那么我们仅仅注册HFP的UUID,蓝牙本地名称

1)EIR数据组包(我们只开了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_ENABLE len += 2; #endif #if PROFILE_HFP_ENABLE len += 2; #endif #if PROFILE_SPP_ENABLE len += 2; #endif #if PROFILE_A2DP_ENABLE len += 2; #endif #if PROFILE_AVRCP_ENABLE len += 2; #endif eir_data[data_pos++] = len; eir_data[data_pos++] = BT_DT_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS; #if PROFILE_DID_ENABLE eir_data[data_pos++] = BT_SERVICE_CLASS_PNP_INFORMATION & 0xff; eir_data[data_pos++] = (BT_SERVICE_CLASS_PNP_INFORMATION>>8) & 0xff; #endif #if PROFILE_HFP_ENABLE eir_data[data_pos++] = BT_SERVICE_CLASS_HANDSFREE & 0xff; eir_data[data_pos++] = (BT_SERVICE_CLASS_HANDSFREE>>8) & 0xff; #endif #if PROFILE_SPP_ENABLE eir_data[data_pos++] = BT_SERVICE_CLASS_SERIAL_PORT & 0xff; eir_data[data_pos++] = (BT_SERVICE_CLASS_SERIAL_PORT>>8) & 0xff; #endif #if PROFILE_A2DP_ENABLE eir_data[data_pos++] = BT_SERVICE_CLASS_AUDIO_SINK & 0xff; eir_data[data_pos++] = (BT_SERVICE_CLASS_AUDIO_SINK>>8) & 0xff; #endif #if PROFILE_AVRCP_ENABLE eir_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_ENABLE eir_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; #endif return 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的函数实现如下:

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; }

我们来看下转的btsnoop架设看一下我们用HCI写EIR的效果

可以看到我们设置上了Local Name以及HFP的UUID

我们来抓一个air log看下EIR数据

可以看到EIR data是在baseband(基带层)层抓到的

3. extern inquiry,搜索到对方的EIR信息

要实现Extern inquiry扫描,那么需要做三个步骤:

步骤 1) 在蓝牙初始化的时候write inquiry mode

我们首先来介绍下这个HCI command

参数: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; }

其中入参我们定义有以下类型,而我们选择INQUIRY_MODE_EIR

#define INQUIRY_MODE_STANDARD 0 #define INQUIRY_MODE_RSSI 1 #define INQUIRY_MODE_EIR 2

步骤2)执行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; else inqres->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的名称的蓝牙音响为例。

我们来看下air log

EIR的虽然方便使用,不需要普通inquiry + HCI get remote name去配合获取到remote的名字,但是在使用过程中要注意几点:

1)Extern inquiry的结果会反复上来(有重复),需要协议栈过滤

可以看到同样的蓝牙地址,同样的蓝牙名称,但是RSSI不同,在同一次搜索中会上来几次

2)Extern inquiry的搜索可能有的时候不带EIR数据

可以看到同样的蓝牙地址,有的时候并没有上来EIR的data

 

小讯
上一篇 2025-01-04 17:45
下一篇 2025-03-01 10:18

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/12252.html