蓝牙扫描想必是蓝牙使用者最常操作的动作吧,那大家了解传统扫描和BLE扫描的区别吗?本篇我们就简单聊聊BLE扫描(scan)那点事。
BLE扫描常见分为两种
蓝牙设备被动扫描周围环境中对等设备发送出来的广播包并直接上报到Host


被动扫描的特点:
如果只是接收对端设备的广播数据包(广播包),可以使用被动扫描
可以配置参数如下:
1.扫描类型------可设置为主动扫描或被动扫描
2.扫描间隔------控制器间隔多长事件扫描一次
3.扫描窗口-----每一次扫描的持续时间
4.扫描策略----接受任何的广播数据包或仅仅接受白名单设备的广播数据-
蓝牙设备主动扫描来获取更多对端设备的信息上报Host,为后续建立链路做准备


主动扫描的特点:
主动扫描不仅仅可以扫描到对端设备的广播数据包,还可以捕获对端设备的响应包(回应包)
在参数配置和启动扫描方面。主动扫描和被动扫描的命令完全是一样的。不过,因为控制器要发送SCAN_REQ数据包给对端设备,以便获取扫描响应数据包,而这些数据包需要包含设备的地址,因此,在使用LE set scan parameters 命令时需要配置一个额外参数,决定链路层的数据包使用固定地址抑或随机地址
Host设置BLE扫描所必须的参数到Controller,这样Controller才知晓扫描上报哪类低功耗设备信息。

/// Ble scan type
typedef enum {
// 主动扫描,主动扫描的设备会发送ScanReq给到广播设备要求更多数据
BLE_SCAN_TYPE_PASSIVE = 0x0, /*!< Passive scan */
// 被动扫描,仅仅接收广播,不会去主动要求更多数据
BLE_SCAN_TYPE_ACTIVE = 0x1, /*!< Active scan */
} esp_ble_scan_type_t;
LE_Scan_Interval扫描间隔,两个连续的扫描窗口的起始时间之间的时间差,包括扫描休息的时间和扫描进行的时间

Own_Address_Type扫描窗口,一次扫描进行的时间宽度。
扫描事件内时间大小,表示在(37、38、39)信道上周期运行的时间

LE_Scan_Window 本端设备的扫描请求数据包中使用的地址类型
/// BLE device address type
typedef enum {
// 公有地址,一般是芯片硬件MAC地址
BLE_ADDR_TYPE_PUBLIC = 0x00,
// 随机地址,通过软件随机生成的一个地址,安全性更高
BLE_ADDR_TYPE_RANDOM = 0x01,
BLE_ADDR_TYPE_RPA_PUBLIC = 0x02,
BLE_ADDR_TYPE_RPA_RANDOM = 0x03,
} esp_ble_addr_type_t;
/// Ble scan filter type
typedef enum {
// 1.除了不包含扫描者地址的可连接定向广播数据包之外,其他广播数据包都会处理(默认情况)
BLE_SCAN_FILTER_ALLOW_ALL = 0x0, /*!< Accept all :
1. advertisement packets except directed advertising packets not addressed to this device (default). */
// 1.只处理在扫描地址白名单里面存在对应地址的广播数据包
// 2.或者发给自己的可连接定向广播数据包
BLE_SCAN_FILTER_ALLOW_ONLY_WLST = 0x1, /*!< Accept only :
1. advertisement packets from devices where the advertiser’s address is in the White list.
2. Directed advertising packets which are not addressed for this device shall be ignored. */
// 1、处理所有非定向广播数据包
// 2、处理指向当前扫描者地址的可连接定向广播数据包
// 3、处理初始者地址为可解析私有地址的可连接定向广播数据包
BLE_SCAN_FILTER_ALLOW_UND_RPA_DIR = 0x2, /*!< Accept all :
1. undirected advertisement packets, and
2. directed advertising packets where the initiator address is a resolvable private address, and
3. directed advertising packets addressed to this device. */
// 1、只处理设备地址在扫描白名单里面的广播数据包
// 2、处理初始者地址为可解析私有地址的可连接定向广播数据包
// 3、处理指向当前扫描者地址的可连接定向广播数据包
BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR = 0x3, /*!< Accept all :
1. advertisement packets from devices where the advertiser’s address is in the White list, and
2. directed advertising packets where the initiator address is a resolvable private address, and
3. directed advertising packets addressed to this device.*/
} esp_ble_scan_filter_t;
可以针对使用各种过滤方法,
- 2 扫描停止和开始
Host启动和停止扫描,启动扫描后Controller发现周围环境中的广播设备。

LE_Scan_Enable:使能还是停止扫描,使能—1、停止—0
Filter_Duplicates:是否开启广播重复过滤,开启enable—1、关闭disable—0,开启后可避免Host在BLE扫描期间接收到重复的低功耗设备信息,该值只有在扫描使能才会生效
BLE扫描过程中一个或多个低功耗蓝牙设备对主动扫描作出了响应,或者在被动扫描期间收到了广播。控制器Controller依次将扫描到的这些设备信息上报给Host。


AdvA:6字节,广播地址;
ScanRspData:0-31字节,扫描回复数据。

可以看出广播数据格式由多个AD Structure组成,每个AD Structure由3部分构成,Length、AD Type、AD
Data组成;Length为1字节,表示AD Type和AD Data的总长度;现有的AD Type也都是一字节的。

可以看出广播数据是28字节,总共3个AD Structure;这里要注意,扫描回复数据不能超过31字节。