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

相关推荐
繁依Fanyi1 小时前
Animaster:一次由 CodeBuddy 主导的 CSS 动画编辑器诞生记
android·前端·css·编辑器·codebuddy首席试玩官
AI+程序员在路上1 小时前
REST架构风格介绍
物联网·架构·restful·web
奔跑吧 android3 小时前
【android bluetooth 框架分析 02】【Module详解 6】【StorageModule 模块介绍】
android·bluetooth·bt·aosp13·storagemodule
weifont6 小时前
聊一聊Electron中Chromium多进程架构
javascript·架构·electron
田一一一6 小时前
Android framework 中间件开发(三)
android·中间件·framework·jni
国际云,接待9 小时前
云服务器的运用自如
服务器·架构·云计算·腾讯云·量子计算
androidwork11 小时前
掌握 Kotlin Android 单元测试:MockK 框架深度实践指南
android·kotlin
田一一一11 小时前
Android framework 中间件开发(二)
android·中间件·framework
追随远方12 小时前
FFmpeg在Android开发中的核心价值是什么?
android·ffmpeg
好吃的肘子12 小时前
Elasticsearch架构原理
开发语言·算法·elasticsearch·架构·jenkins