问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

蓝牙BLE连接技术详解:扫描、广播与空包交互

创作时间:
2025-01-21 22:44:15
作者:
@小白创作中心

蓝牙BLE连接技术详解:扫描、广播与空包交互

随着蓝牙BLE设备的普及,蓝牙连接问题一直是蓝牙开发的重要一环。本文将从BLE的开启、扫描、广播类型、连接参数和流程等多个方面进行详细讲解,并结合具体案例和代码示例,帮助读者更好地理解BLE连接过程中的问题和解决方案。

一、BLE的开启

蓝牙service中在开启蓝牙时会读取(Android 12之前在package/app/bluetooth/res/value/config.xml,13在package/modules下)中的协议配置文件,去开启对应的协议service,BLE对应GATT,强制启用,源码流程中配置关闭GATT蓝牙启动不了,开启蓝牙仍然是BTSNOOP中下发一个HCI_RESET。

二、BLE扫描

发起扫描的接口有两个,一个是系统设置中调用的startdiscovery,传统蓝牙和BLE一起扫描,协议栈system/bt/stack/btm/btm_inq.cc可以改掉只扫描传统蓝牙,扫描结果都是从action_found广播发出,另一个就是各种BLE应用调用的GATT startscan,只用来发现外围的BLE设备广播,通过onscanResultBLE回调扫描结果,扫描指令下发前会通过Command: HCI_LE_Set_Scan_Parameters设置窗口、间隔、过滤policy等,这块实际应用遇到问题例如:外围设备广播以20ms间隔广播一次,中心设备设置扫描间隔100ms,扫描窗口为10ms,可能出现扫描设备要很久,或者某一次扫描无法扫到该设备,扫描的窗口碰不上对方设备广播的频率。扫描开启指令则通过Command: HCI_LE_Set_Scan_Enable下发,另外BLE也支持extends类型广播,相比传统BLE广播,支持的数据大小和参数都有变化。

三、BLE广播类型

BLE设备广播地址类型主要就是public address和random private address,由BLE是否支持私有模式决定。BLE广播通过event: HCI_LE_Advertising_Report上报到host,Event_Type标注了广播类型,协议栈也有对应的解析,应用层也可以取到该类型

system\bt\stack\btm\btm_ble_gap.cc
if (legacy_evt_type == 0x00) {  // ADV_IND;
  event_type = 0x0013;
} else if (legacy_evt_type == 0x01) {  // ADV_DIRECT_IND;
  event_type = 0x0015;
} else if (legacy_evt_type == 0x02) {  // ADV_SCAN_IND;
  event_type = 0x0012;
} else if (legacy_evt_type == 0x03) {  // ADV_NONCONN_IND;
  event_type = 0x0010;
} else if (legacy_evt_type == 0x04) {  // SCAN_RSP;
  // We can't distinguish between "SCAN_RSP to an ADV_IND", and "SCAN_RSP to
  // an ADV_SCAN_IND", so always return "SCAN_RSP to an ADV_IND"
  event_type = 0x001B;
  • ADV_IND:可连接广播
  • ADV_DIRECT_IND :定向广播,直连广播
  • ADV_SCAN_IND:扫描请求广播,获取对方更多数据,对应scn rsp
  • ADV_NONCONN_IND:不可连接广播,只用来广播一些特定数据
  • SCAN_RSP:回应scan req

四、BLE连接参数和流程

选择扫描到的可连接广播,创建连接,蓝牙协议5.4

连接完成事件会在触发创建连接后扫描到对方可连接广播并下发connect_ind,触发双方连接状态

完整连接流程图

五、结合协议具体看一下空包

对方设备发送可连接广播

整个连接包的交互主要为下图:在广播channel上收到可连接广播包,接收到后需在T_IFS(150us)内发出connect_ind连接包,然后在时间transmitWindowDelay+transmitWindowOffset到ransmitWindowDelay+transmitWindowOffset+transmitWindowSize时间内接着发出第一包数据(一般是empty package),对方在T_IFS时间内回复成功,链路连接正式建立完成,并且以第一包为锚点,之后在Connection Interval内进行数据交互。后续进行version、feature exchange,还有加密等不再细讲

发送connect_ind包后,紧接着发送empty package

empty package交互完成,连接建立ok

下图为第一包交互对方不响应会继续发送empty等待对方响应

遇到BLE连接问题可以抓空包分析下连接流程是否正常,经常出现第一包empty package不回包,建立失败,一部分是环境干扰,直接丢包,还有可能对方设备处理异常了,具体问题具体分析。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号