低功耗蓝牙:Bluetooth Low Energy简称BLE,相较于传统蓝牙BT具有低功耗、低成本、小体积等优势,BLE和BT都是工作在全世界公开通用的2.4GHz无线频段上,但他们是完全不同的两种技术,只是蓝牙技术联盟SIG将其归入蓝牙门类下,从而称之为BLE技术。
蓝牙芯片当今有两种不同的模式:单模、双模
单模:蓝牙芯片只支持BT或BLE其中一种功能,但市面常见的单模为BLE芯片居多
双模:蓝牙芯片两种功能都支持,一般如手机蓝牙、PC蓝牙等
本篇我们就来重点聊聊BLE的广播,这是BLE功能开始的基础。
定向广播:不可被扫描,只能被特定地址的蓝牙BLE设备连接
高、低占空比:一个广播周期内广播占用时间多的为高占空比,否则为低占空比
使用扩展广播时,广播不能同时为可连接可扫描的广播
由于扩展广播受限于芯片是否支持(蓝牙协议5.x支持),所以我们接下来就以传统广播讲解下BLE的广播流程。
BLE广播的流程包含四个步骤:设置广播参数、设置广播数据、设置扫描回复数据、使能广播,我们分别加以说明。
从蓝牙协议最新版本《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传统广播就被使能起来了,下面我们以开启广播的时序图详细了解下相关流程:
从上面的时序图可以看出上层应用只需要将相关数据构造后调用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类型如下:
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;
从协议中可以知道AD Type占用一个字节,所以实际的AD Data数据长度为length-1个字节。
BLE的传统广播我们就分析到这儿,感兴趣的小伙伴欢迎私信留言一起讨论。