BLE传统广播避坑指南

BLE传统广播避坑指南

前几天和同事一起讨论基于蓝牙BLE实现的current time profile功能,发现不少安卓源码问题。那这篇文章我们就来扒一扒安卓源码中涉及BLE广播的那些坑,为蓝牙开发者少走些弯路尽点绵薄之力。

对BLE传统广播还不了解的小伙伴建议提前了解相关知识,可以查看我前一篇文章《低功耗蓝牙BLE传统广播总结》。

使能一个传统BLE广播,需要设置参数、数据,使能广播这几个流程,每个流程执行成功才能真正将广播使能起来,那这其中的坑听我娓娓道来。

1、广播名字

广播数据中包含本端蓝牙设备的名字,方便扫描方发现该广播。所以在构造AdvertiseData数据时setIncludeDeviceName设置成true就可现实广播中加入蓝牙name。

但是如果你的蓝牙名字是中文字符,那大坑就在向你招手了。由于广播数据是有长度要求,被限制在最多31字节
在这里插入图片描述

安卓源码中也会在BluetoothLeAdvertiser.totalBytes()检测广播数据长度是否符合要求,但是计算蓝牙名字的长度时使用的是String .length(),这样中文名字的蓝牙名字有几个字符就是占几个字节,比如蓝牙名字是“一头老母猪”,那这边计算的长度为5。
在这里插入图片描述

但是最后在AdvertiseHelper.advertiseDataToBytes()方法中将AdvertiseData数据转换成byte[]型数组时采用String.getBytes(“UTF-8”)转换中文字符, "UTF-8"格式的编码转换在不同的系统中可以将一个中文字符转换成不同字节的数组。
在这里插入图片描述

安卓系统中通过"UTF-8"会将一个中文字符转换成三个字节的数据,所以蓝牙名称为“一头老母猪”经"UTF-8"转换后会得到一个15字节的数据。

这样会导致一个问题:在BluetoothLeAdvertiser检测符合要求的广播数据,在最终转换成byte[]型数组后的数据长度可能会超过31字节,这样发送广播数据时可能会丢失部分应用设置的初始数据。

2、广播数据

蓝牙协议中规定了传统BLE广播的数据长度最多就是31字节,可有时扫描广播却发现广播数据不对,平白无故多了些数据,这时问题可能出在使用的蓝牙协议栈bluedroid非原生协议栈。有些蓝牙协议栈供应商自己的协议栈会私自添加一些数据,导致广播数据变多,或丢失应用设置的部分初始数据,如下图是使用的非原生协议栈后发送的广播数据增加了AD Type = 0x12的数据:
在这里插入图片描述

所以使用第三方提供的蓝牙协议栈时需要多多了解他们的实现是否和原生有差异,避免像上面这样无缘无故地增加了些可有可无的数据,从而丢失了原始设置的数据。

3、广播参数Interval

广播参数Interval是一个范围值,interval_min ~ interval_max ,两者相处50,即interval_max = interval_min + 50,但是在传统广播的HCI定义中,interval的取值范围为:0x0020 ~ 0x4000
在这里插入图片描述

而且参数inteval的选取还在于设置广播参数选用的是哪个接口:
在这里插入图片描述

使能传统广播从上表可以得出以下结论:

  • startAdvertising,则interval只有三种选择,但都在HCI规定的范围内

  • startAdvertisingSet,则interval是一个范围值,大大增加了用户的可选项,但可能会超出传统广播定义的interval最大值0x4000。这一点应用使能传统广播时需重点关注。

源码学习无止境,发现源码相关bug有助于规避不必要的风险,本篇避坑指南就暂时指到这儿,以后的学习中发现源码bug会继续更新,感兴趣的小伙伴欢迎私信留言一起讨论源码bug。

更多互联互通技术,欢迎关注微信公众号:Connectivity
在这里插入图片描述

发布了15 篇原创文章 · 获赞 6 · 访问量 1250

猜你喜欢

转载自blog.csdn.net/weixin_44260005/article/details/105121783