基于Android P版本分析
BT bluedroid SCAN
bluedroid scan
在scan阶段,其实可以分为两个步骤:
- HCI Command下发;
- HCI Event 上报;
整体的流转如下:
事件传递
- BTIF -> BTA -> BTM -> BTU -> HCI
获取数据后
- HCI->BTU->BTM->BTA->BTIF层层上传,将数据传传递到上层。
蓝牙扫描流程启动
在这个过程中,上层发送了startDiscovery指令之后,在底层其实存在两种扫描方式:
- BLE scan enable
- BR/EDR scan
BLE scan不依赖任何条件,直接就可以进行enable scan,但是针对BR/EDR扫描,需要先进行Filter的配置后才可以成功发起scan;
- BLE:低功耗蓝牙协议栈
- BR/EDR:传统蓝牙协议栈
我们主要分析BR/EDR场景下的scan,首先先将之前的过滤条件进行移除,然后重新添加新的过滤条件,这个command会下发到HCI层进行处理,该Command绑定的对应的Event为HCI_SET_EVENT_FILTER,并且对应了接收Event事件上报的函数btu_hcif_command_complete_evt,Controller处理完该Command之后,会向上层上报Event事件,对应的就是HCI_SET_EVENT_FILTER,然后该Event对应的处理函数来执行相应的逻辑;
在该过程中,涉及到了一个EVENT和对应执行函数的映射关系。在BTA_DmSearch函数中,主要是通过bta_sys_sendmsg、bta_sys_event以及bta_dm_search_sm_execute这3个函数决定是调用哪个处理函数,函数中对应的Event:BTA_DM_API_SEARCH_EVT,对应映射关系的绑定是在bluedroid enable的过程中建立的,通过bta_sys_register的方式注册;
蓝牙设备inquiry
Controller响应HCI_SET_EVENT_FILTER事件后,最终会执行到btu_hcif_hdl_command_complete函数;
在该函数中响应了多种Event,对应HCI_SET_EVENT_FILTER的函数处理为btm_event_filter_complete;
在接收到Set_Event_Fliter之后,会发送真正的用于scan的Command:HCI_INQUIRY,改指令用于底层搜索周围可见的蓝牙设备;
Inquiry
首先介绍一下和inquiry的相关的流程。
inquiry是从协议栈下发的一个HCI命令。其格式如下:
- LAP:蓝牙地址分为三部分:LAP(24位地址低端部分)、UAP(8位地址高端部分)和NAP(16位无意义地址部分),其中,NAP和UAP是生产厂商的唯一标识码,必须由蓝牙权威部门分配给不同的厂商,而LAP是由厂商内部自由分配。 对于某一种型号的手机或者设备,所有个体的NAP、UAP是固定的,可变的是LAP;
- 这里简单介绍下第二个参数,是inquiry的持续时间;
从上图看出 inquiry持续的时间是 设定值乘以1.28s,如果设定值是10,那么实际持续的时间就是12.8s
那么下了这个HCI命令之后,控制器端上传的event是什么呢?这个要看另外一个命令:
- HCI_Write_Inquiry_mode
我们主要关注一下其中的inquiry mode
Inquiry模式有3种,主要区别是返回值不一样;
- 第一种模式:标准返回格式,Standard Inquiry Result event format
- 第二种模式:查询结果返回带有RSSI格式,Inquiry Result format with RSSI
- 第三种模式:查询结果带有RSSI的格式或者额外的查询结果格式,Inquiry Result with RSSI format or Extended Inquiry Result format。Extended Inquiry Result format:除了带有RSSI,可能带有设备名字之类的信息。
对应的Inquiry scan 有两种扫描方式:
蓝牙设备found上报
这个过程比较简单,就是响应Inquiry指令的Response,在这个过程中,返回了Device(LocalHost Device)的信息,然后将指定的信息保存到对应的配置文件中,然后将Device Info封装到Result中,然后向上层上报,通过广播的方式发送给对应监听广播的进程中;
HCI Command
Start Discovery
LE Set Extended Scan Parameters
yaml
Bluetooth HCI Command - LE Set Extended Scan Parameters
Command Opcode: LE Set Extended Scan Parameters (0x2041)
0010 00.. .... .... = Opcode Group Field: LE Controller Commands (0x08)
.... ..00 0100 0001 = Opcode Command Field: LE Set Extended Scan Parameters (0x041)
Parameter Total Length: 8
Own Address Type: Random Device Address (0x01)
Scan Filter Policy: Accept all advertisements, except directed advertisements not addressed to this device (0x00)
Scanning PHYs: 0x01, LE 1M
0000 0.0. = Reserved: 0x00
.... .0.. = LE Coded: False
.... ...1 = LE 1M: True
Scanning PHY: LE 1M
Scan Type: Active (0x01)
Scan Interval: 8000 (5000 msec)
Scan Window: 8000 (5000 msec)
[Response in frame: 108]
[Command-Response Delta: 1.115ms]
该命令用于设置扩展扫描参数;
- Own Address Type:自身地址类型,这个值对应的就是 LE Set Random Address HCI Command的逻辑;
- Scan Filter Policy:Accept all advertisements, except directed advertisements not addressed to this device,接受所有的广播,除了不是针对本设备的定向广播,可以理解为不拦截任何广播;
- Scan Type:Active,启动
- Scan Interval:扫描间隔,8000 slots,即5000 ms;
- Scan Window:扫描周期,8000 slots,即5000 ms;
Interval & Window 关系
Response的Status为Success;
LE Set Extended Scan Enable
yaml
Bluetooth HCI Command - LE Set Extended Scan Enable
Command Opcode: LE Set Extended Scan Enable (0x2042)
0010 00.. .... .... = Opcode Group Field: LE Controller Commands (0x08)
.... ..00 0100 0010 = Opcode Command Field: LE Set Extended Scan Enable (0x042)
Parameter Total Length: 6
Scan Enable: true (0x01)
Filter Duplicates: false (0x00)
Duration: 0 (0 msec)
Period: 0 (0 sec)
[Response in frame: 110]
[Command-Response Delta: 1.061ms]
该命令用于开启LE扫描,该命令之前还有一个设置le扫描参数的命令,对应的就是上一个HCI Command:LE Set Extended Scan Parameters;
- Scan Enable:true;
- Filter Duplicates:false
Response的Status为Success;
Set Event Filter
sql
Bluetooth HCI Command - Set Event Filter
Command Opcode: Set Event Filter (0x0c05)
0000 11.. .... .... = Opcode Group Field: Host Controller & Baseband Commands (0x03)
.... ..00 0000 0101 = Opcode Command Field: Set Event Filter (0x005)
Parameter Total Length: 2
Filter Type: Inquiry Result (0x01)
Filter Condition Type: A new device responded (0x00)
[Response in frame: 106]
[Command-Response Delta: 1.739ms]
该命令是用于设置event过滤器,HCI reset之后,默认是没有任何过滤器,并且Auto_Accept_Flag=off,这个参数用来设置是否自动接受连接请求,如果event过滤器设置满了,则会报错:Memory Full error code;
- Filter Type = Inquiry Result
- Filter Condition Type = A new device responded
Filter Type 和 Filter Condition Type组合,共同定义Filter的状态;
Filter Type | Filter Condition Type | Desc |
---|---|---|
0x00 | 无 | 清理所有event过滤器 |
Inquiry Result(0x01) | 0x00 0x01 0x02 | 返回所有设备的Response 返回特定CoD设备的Response 返回特定BD_ADDR设备的Response |
Connection Setup(0x02) | 0x00 0x01 0x02 | 允许来自所有设备连接 允许特定的CoD设备的连接 允许特定的BD_ADDR设备的连接 |
如果Filter_Type == 0x00,发送这个命令会清空所有的event过滤器同时设置Auto_Accept_Flag=off,注意这时候只有Filter_Type一个参数,不能使用Filter_Condition_Type和Condition;
Response的Status为Success;
Write Current IAC LAP
yaml
Bluetooth HCI Command - Write Current IAC LAP
Command Opcode: Write Current IAC LAP (0x0c3a)
0000 11.. .... .... = Opcode Group Field: Host Controller & Baseband Commands (0x03)
.... ..00 0011 1010 = Opcode Command Field: Write Current IAC LAP (0x03a)
Parameter Total Length: 4
Number of Current IAC: 1
IAC LAP: 0x9e8b33
[Response in frame: 102]
[Command-Response Delta: 1.729ms]
该命令用于设置本地BR/EDR Controller可以同时监听的Inquiry Access Codecs(IAC),至少应该设置1个;
使用这个command时会清空已有的IACs同时存储Num_Current_IAC和设置的IAC_LAPs,如果Num_Current_IAC大于Num_Support_IAC时只有前面的Num_Support_IAC个IACs会被存储,但是Command Complete event中的status参数会设置成Success (0x00);
- Number of Current IAC:要设置的IACs的个数
- IAC_LAP[i]:要设置的IACs,0x9e8b33代表了general inquiry access code (GIAC),表明任意设备都会返回值
Response的Status为Success;
Write Scan Enable
yaml
Bluetooth HCI Command - Write Scan Enable
Command Opcode: Write Scan Enable (0x0c1a)
0000 11.. .... .... = Opcode Group Field: Host Controller & Baseband Commands (0x03)
.... ..00 0001 1010 = Opcode Command Field: Write Scan Enable (0x01a)
Parameter Total Length: 1
Scan Enable: Inquiry Scan enabled/Page Scan enabled (0x03)
[Response in frame: 104]
[Command-Response Delta: 1.351ms]
该命令主要是用于设置Scan Enable的值,其中包含了两种Scan:inquiry Scan、Page Scan;
-
Scan Enable
- Inquiry Scan:enabled
- Page Scan:enabled
Inquiry
yaml
Bluetooth HCI Command - Inquiry
Command Opcode: Inquiry (0x0401)
0000 01.. .... .... = Opcode Group Field: Link Control Commands (0x01)
.... ..00 0000 0001 = Opcode Command Field: Inquiry (0x001)
Parameter Total Length: 5
LAP: 0x9e8b33
Inquiry Length: 10 (12.8 sec)
Num Responses: 0
[Pending in frame: 114]
[Command-Pending Delta: 2.843ms]
[Response in frame: 141]
[Command-Response Delta: 13036.418ms]
该命令用于让BR/EDR芯片进入搜索模式,搜索周边的BR/EDR设备;
- LAP = 0x9e8b33:代表一般/无限制查询访问代码
LAP具体取值范围为是0x9E8B00 ~ 0x9E8B3F,但是只有 0x9E8B00和 0x9E8B33 这两个数字是有效的,其他值保留供将来使用;
LAP | Desc |
---|---|
0x9E8B33 | 代表一般/无限制查询访问代码(GIAC) |
0x9E8B00 | 代表有限的专用查询访问代码(LIAC) |
- Inquiry Length = 10 slots,即12.8 s:代表了查询模式的总持续时间,当此时间超时后查询将被停止;
- Num Responses = 0:代表在查询停止之前可以接受的响应数,当响应数量达到该值后,控制器 Controller 停止当前的查询,并上报 Host 查询完成 Event;
Num Responses Value | Desc |
---|---|
0x00 | 上报的查询结果没有数量限制 |
0xXX | 最大的查询结果响应数量 |
Response的Status为Success,代表了HCI Command指令发送完成;
ACTION_FOUND Device
底层上报Device Found Action;
Extended Inquiry Result
yaml
Bluetooth HCI Event - Extended Inquiry Result
Event Code: Extended Inquiry Result (0x2f)
Parameter Total Length: 255
Number of responses: 1
BD_ADDR: HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd)
Page Scan Repetition Mode: R1 (0x01)
Reserved: 0x00
Class of Device: 0x5a020c (Phone:Smartphone - services: Networking Capturing ObjectTransfer Telephony)
0000 11.. = Minor Device Class: Smartphone (0x03)
.... ..00 = Format Type: 0x0
0... .... .... .... = Major Service Classes: Information: False
.1.. .... .... .... = Major Service Classes: Telephony: True
..0. .... .... .... = Major Service Classes: Audio: False
...1 .... .... .... = Major Service Classes: Object Transfer: True
.... 1... .... .... = Major Service Classes: Capturing: True
.... .0.. .... .... = Major Service Classes: Rendering: False
.... ..1. .... .... = Major Service Classes: Networking: True
.... ...0 .... .... = Major Service Classes: Positioning: False
.... .... 00.. .... = Major Service Classes: Reserved: 0x0
.... .... ..0. .... = Major Service Classes: Limited Discoverable Mode: False
.... .... ...0 0010 = Major Device Class: Phone (0x02)
.001 0000 1101 0101 = Clock Offset: 0x10d5
RSSI: -81dBm
Extended Inquiry Response Data
Device Name: dupz
Length: 5
Type: Device Name (0x09)
Device Name: dupz
16-bit Service Class UUIDs
Length: 21
Type: 16-bit Service Class UUIDs (0x03)
UUID 16: OBEX Object Push (0x1105)
UUID 16: Audio Source (0x110a)
UUID 16: A/V Remote Control Target (0x110c)
UUID 16: Headset Audio Gateway (0x1112)
UUID 16: PAN PANU (0x1115)
UUID 16: PAN NAP (0x1116)
UUID 16: Handsfree Audio Gateway (0x111f)
UUID 16: Phonebook Access Server (0x112f)
UUID 16: PnP Information (0x1200)
UUID 16: Message Access Server (0x1132)
32-bit Service Class UUIDs
Length: 1
Type: 32-bit Service Class UUIDs (0x05)
128-bit Service Class UUIDs
Length: 1
Type: 128-bit Service Class UUIDs (0x07)
Unused
该HCI Event对应了HCI Inquiry Command,将Inquiry的结果返回;
-
Number of responses = 1:响应个数
-
BD_ADDR = HuaweiDe_42:c7:dd (30:aa:e4:42:c7:dd):RemoteDevice的蓝牙mac地址;
-
Class of Device:0x5a020c,设备类型
- Major Device Class = Phone (0x02):主设备类型为电话;
- Minor Device Class = Smartphone (0x03):对应主设备类型中的分类为智能手机;
- Major Service Classe:主要服务类型
-
Device Name:Remote Device Name
-
16-bit Service Class UUIDs:16位完整的服务列表
- OBEX Object Push
- Audio Source
- A/V Remote Control Target
- Headset Audio Gateway
- PAN PANU
- PAN NAP
- Handsfree Audio Gateway
- Phonebook Access Server
- PnP Information
- Message Access Server
Inquiry Complete
yaml
Bluetooth HCI Event - Inquiry Complete
Event Code: Inquiry Complete (0x01)
Parameter Total Length: 1
Status: Success (0x00)
[Command in frame: 188]
[Pending in frame: 189]
[Pending-Response Delta: 13036.02ms]
[Command-Response Delta: 13037.07ms]
代表了Inquiry Command执行完成;