BT bluedroid scan 扫描

基于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执行完成;

相关推荐
思忖小下24 分钟前
梳理你的思路(从OOP到架构设计)_介绍GoF设计模式
设计模式·架构·eit
秀儿y44 分钟前
单机服务和微服务
java·开发语言·微服务·云原生·架构
爱数学的程序猿2 小时前
Python入门:6.深入解析Python中的序列
android·服务器·python
brhhh_sehe3 小时前
重生之我在异世界学编程之C语言:深入文件操作篇(下)
android·c语言·网络
zhangphil3 小时前
Android基于Path的addRoundRect,Canvas剪切clipPath简洁的圆形图实现,Kotlin(2)
android·kotlin
Calvin8808283 小时前
Android Studio 的革命性更新:Project Quartz 和 Gemini,开启 AI 开发新时代!
android·人工智能·android studio
敲代码敲到头发茂密4 小时前
【大语言模型】LangChain 核心模块介绍(Memorys)
android·语言模型·langchain
向上的车轮5 小时前
云边端架构的优势是什么?面临哪些挑战?
架构·云边端
FHYAAAX5 小时前
灾备方案和架构类型、跨区域
架构·华为云
北京_宏哥5 小时前
python接口自动化(四十二)- 项目架构设计之大结局(超详解)
python·架构·前端框架