当前位置:   article > 正文

蓝牙 ble连接流程及ellisys空包分析_传统蓝牙和ble建立连接过程

传统蓝牙和ble建立连接过程

随着ble设备的普及,众多品牌的手机和车载连接着各式各样的ble外设,接触多的有手环、手表、双模耳机、遥控器、鼠标、键盘或者智能家居设备等等

连接类问题一直是蓝牙开发的重要一环,不懂的人可能只会一个劲的问为什么,开发时遇到实际问题时可能也会苦于日志不全,无法确认问题原因,看完这一篇希望对你们有所帮助

基于android平台讲一下

一、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标注了广播类型,协议栈也有对应的解析,应用层也可以取到该类型

  1. system\bt\stack\btm\btm_ble_gap.cc
  2. if (legacy_evt_type == 0x00) {  // ADV_IND;
  3.       event_type = 0x0013;
  4.     } else if (legacy_evt_type == 0x01) {  // ADV_DIRECT_IND;
  5.       event_type = 0x0015;
  6.     } else if (legacy_evt_type == 0x02) {  // ADV_SCAN_IND;
  7.       event_type = 0x0012;
  8.     } else if (legacy_evt_type == 0x03) {  // ADV_NONCONN_IND;
  9.       event_type = 0x0010;
  10.     } else if (legacy_evt_type == 0x04) {  // SCAN_RSP;
  11.       // We can't distinguish between "SCAN_RSP to an ADV_IND", and "SCAN_RSP to
  12.       // an ADV_SCAN_IND", so always return "SCAN_RSP to an ADV_IND"
  13.       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不回包,建立失败,一部分是环境干扰,直接丢包,还有可能对方设备处理异常了,具体问题具体分析。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/820306
推荐阅读
相关标签
  

闽ICP备14008679号