低功耗蓝牙BLE传统广播总结

低功耗蓝牙BLE传统广播总结


低功耗蓝牙:Bluetooth Low Energy简称BLE,相较于传统蓝牙BT具有低功耗、低成本、小体积等优势,BLE和BT都是工作在全世界公开通用的2.4GHz无线频段上,但他们是完全不同的两种技术,只是蓝牙技术联盟SIG将其归入蓝牙门类下,从而称之为BLE技术。


蓝牙芯片当今有两种不同的模式:单模、双模

单模:蓝牙芯片只支持BT或BLE其中一种功能,但市面常见的单模为BLE芯片居多双模:蓝牙芯片两种功能都支持,一般如手机蓝牙、PC蓝牙等


本篇我们就来重点聊聊BLE的广播,这是BLE功能开始的基础。


BLE广播分类:


BLE广播类型

定向广播:不可被扫描,只能被特定地址的蓝牙BLE设备连接高、低占空比:一个广播周期内广播占用时间多的为高占空比,否则为低占空比使用扩展广播时,广播不能同时为可连接可扫描的广播使用扩展广播时,可连接不可扫描的定向广播只能为低占空比


由于扩展广播受限于芯片是否支持(蓝牙协议5.x支持),所以我们接下来就以传统广播讲解下BLE的广播流程。


BLE广播的流程包含四个步骤:设置广播参数、设置广播数据、设置扫描回复数据、使能广播,我们分别加以说明。


步骤1:设置广播参数

从蓝牙协议最新版本《Core_v5.2.pdf》可以知晓该HCI命令的参数部分总共15字节。安卓系统对应的是AdvertiseSettings或AdvertisingSetParameters参数,这两个类都可以表示出广播参数,只不过AdvertisingSetParameters包含的内容更多,同时也使用与扩展广播,即如果你想使能一个扩展广播,则参数只能使用AdvertisingSetParameters来组织。


AdvertiseSettings组织参数,需要关注如下数据:


AdvertisingSetParameters组织参数,需要关注如下参数:

AdvertiseSettings参数经过BluetoothLeAdvertiser.startAdvertising()会重新组织成AdvertisingSetParameters参数,最终在JNI层会被转化成HCI命令中所需的参数。


步骤2:设置广播数据

广播数据就是对外广播时自带的相关data,这需要应用层主动设置好想广播的数据。

从协议规定可以看出设置的广播数据长度为31字节,所以应用层在设置广播data时需要考虑data长度,不然多余长度的数据是发不出去的。


步骤3:设置扫描回复数据

当有scanner扫描该广播时,需要回复给该scanner的数据。数据组成和广播数据相同,数据长度也是限制在31字节。


步骤4:使能广播

前面三个步骤相关参数设置成功后,开始广播。


到这儿,BLE传统广播就被使能起来了,下面我们以开启广播的时序图详细了解下相关流程:

BLE广播下发时序

从上面的时序图可以看出上层应用只需要将相关数据构造后调用BluetoothLeAdvertiser. startAdvertising()接口开始广播,底层使能广播是否成功通过回调的方式告知应用。


但应用层设置广播回调的方式有两种:

BluetoothLeAdvertiser. startAdvertising():回调使用AdvertiseCallback,这样回调给应用的信息只有当初设置的广播参数 AdvertiseSettings。优点是操作简单,缺点就是更改广播参数数据等需要停止广播,重新调用广播开始API。BluetoothLeAdvertiser. startAdvertisingSet():回调使用AdvertisingSetCallback,这样回调给应用的会有一个重要参数AdvertisingSet,应用可以通过该类操作当前的广播,方法很多比如开始广播关闭广播重置广播参数重置广播数据重置广播扫描回复数据获取广播使用的地址等等单一操作,不需要将所有数据一起下发给底层Controller,如此可以更方便应用层对广播的控制。


安卓原生的蓝牙协议栈在使能广播时,有些广播参数是被固定的,如下表:


广播数据和扫描回复数据的构造就会复杂些,但也是有相关规定的。数据格式如下图:

一个广播数据是由一系列构造AD Structure组成的,每个构造是长度length(一个字节)加上数据Data组成,而Data就是由AD Type + AD Data构成,AD Type的定义已在协议中规定好了,感兴趣的可以自行在蓝牙官网上查看assigned-numbers中的generic-access-profile协议中定义的内容。安卓源码中常用的AD Type类型如下:

<code>private static final int COMPLETE_LIST_16_BIT_SERVICE_UUIDS = 0X03;

private static final int COMPLETE_LIST_32_BIT_SERVICE_UUIDS = 0X05;

private static final int COMPLETE_LIST_128_BIT_SERVICE_UUIDS = 0X07;

private static final int SHORTENED_LOCAL_NAME = 0X08;

private static final int COMPLETE_LOCAL_NAME = 0X09;

private static final int TX_POWER_LEVEL = 0x0A;

private static final int SERVICE_DATA_16_BIT_UUID = 0X16;

private static final int SERVICE_DATA_32_BIT_UUID = 0X20;

private static final int SERVICE_DATA_128_BIT_UUID = 0X21;

private static final int MANUFACTURER_SPECIFIC_DATA = 0XFF;/<code>


从协议中可以知道AD Type占用一个字节,所以实际的AD Data数据长度为length-1个字节。


BLE的传统广播我们就分析到这儿,感兴趣的小伙伴欢迎私信留言一起讨论。