Description 翻译
原文
This command is used to start and stop scanning for legacy PDUs (but not extended PDUs, even if the device supports extended advertising). Scanning is used to discover advertising devices nearby.
翻译
这个命令用于启动和停止对Legacy PDU的扫描。
注意:它不用于扫描Extended PDU,即使设备支持 Extended Advertising,也不是通过这个命令来扫描 Extended Advertising。
扫描用于发现附近正在发送广播的设备。
也就是说:
LE Set Scan Enable只负责 Legacy Scanning 的开启和关闭。
如果是 Bluetooth 5 之后的 Extended Scanning,要看:
LE Set Extended Scan Enable原文
The Filter_Duplicates parameter controls whether the Link Layer should filter out duplicate advertising reports (Filtering_Enabled) to the Host, or if the Link Layer should generate advertising reports for each packet received (Filtering_Disabled).
翻译
Filter_Duplicates参数用于控制 Link Layer 是否要向 Host 过滤重复的广播报告。
如果启用重复过滤:
Filtering_Enabled那么 Link Layer 会过滤掉重复的 advertising report,不会每次收到重复广播包都上报给 Host。
如果关闭重复过滤:
Filtering_Disabled那么 Link Layer 会对每一个收到的广播包都生成 advertising report,并上报给 Host。
也就是:
Filter_Duplicates = 0x00 不去重,每收到一个广播包都可能上报 Filter_Duplicates = 0x01 去重,相同设备/相同广播报告可能只上报一次原文
If LE_Scan_Enable is set to 0x00 then Filter_Duplicates shall be ignored.
翻译
如果LE_Scan_Enable被设置为0x00,那么Filter_Duplicates应被忽略。
也就是说,当你关闭扫描时:
LE_Scan_Enable = 0x00此时Filter_Duplicates填什么都不重要,因为扫描都关闭了,谈不上是否过滤重复报告。
原文
If the LE_Scan_Enable parameter is set to 0x01 and scanning is already enabled, any change to the Filter_Duplicates setting shall take effect.
翻译
如果LE_Scan_Enable被设置为0x01,并且扫描已经处于启用状态,那么对Filter_Duplicates的任何修改都应生效。
这个点很重要。
意思是:扫描已经开启时,虽然你不能随便改扫描参数,比如LE_Scan_Type、LE_Scan_Interval、LE_Scan_Window,但是你可以再次发送:
LE Set Scan Enable然后只改变Filter_Duplicates的设置。
例如:
当前已经在扫描: LE_Scan_Enable = 0x01 Filter_Duplicates = 0x01 再次发送: LE_Scan_Enable = 0x01 Filter_Duplicates = 0x00这样可以在扫描过程中关闭重复过滤。
原文
Disabling scanning when it is disabled has no effect.
翻译
当扫描已经处于关闭状态时,再次关闭扫描不会产生任何影响。
也就是:
当前已经关闭扫描 再次发送 LE_Scan_Enable = 0x00不会报错,也不会产生额外影响,可以理解为无操作。
Errors 翻译
原文
See Section 4.5.2 for a list of error types and descriptions.
翻译
错误类型和描述列表请参考 4.5.2 节。
错误表格翻译
| Type | Condition | Error code |
|---|---|---|
| R | LE_Scan_Enable设置为0x01,扫描参数里的Own_Address_Type设置为0x00或0x02,但是设备没有 Public Address | Invalid HCI Command Parameters,0x12 |
| MC | LE_Scan_Enable设置为0x01,扫描参数里的Own_Address_Type设置为0x01或0x03,但是设备的 Random Address 还没有通过HCI_LE_Set_Random_Address命令初始化 | Invalid HCI Command Parameters,0x12 |
这两个错误都发生在:
LE_Scan_Enable = 0x01也就是准备开启扫描的时候。
第一种错误:
Own_Address_Type = 0x00 或 0x02这两个模式可能需要使用 Public Address。
但是设备没有 Public Address,于是开启扫描失败。
第二种错误:
Own_Address_Type = 0x01 或 0x03这两个模式可能需要使用 Random Address。
但是你还没有先调用:
HCI_LE_Set_Random_Address初始化随机地址,于是开启扫描失败。
LE_Scan_Enable
| Value | Parameter Description |
|---|---|
| 0x00 | 关闭扫描 |
| 0x01 | 开启扫描 |
| All other values | 保留,供将来使用 |
也就是说:
LE_Scan_Enable = 0x00 Stop Scanning LE_Scan_Enable = 0x01 Start ScanningFilter_Duplicates
| Value | Parameter Description |
|---|---|
| 0x00 | 关闭重复过滤 |
| 0x01 | 开启重复过滤 |
| All other values | 保留,供将来使用 |
也就是说:
Filter_Duplicates = 0x00 每次收到广播包都可能上报 Filter_Duplicates = 0x01 过滤重复广播报告Return parameters
| Value | Parameter Description |
|---|---|
| 0x00 | HCI_LE_Set_Scan_Enable命令执行成功 |
| 0x01 to 0xFF | HCI_LE_Set_Scan_Enable命令执行失败。错误码和描述请参考[Vol 1] Part F, Controller Error Codes |
也就是说:
Status = 0x00 开启/关闭扫描成功 Status != 0x00 开启/关闭扫描失败Event(s) generated
原文
When the HCI_LE_Set_Scan_Enable command has completed, an HCI_Command_Complete event shall be generated.
翻译
当HCI_LE_Set_Scan_Enable命令完成后,应生成一个:
HCI_Command_Complete Event也就是说,这个命令完成后,Controller 会通过 Command Complete Event 告诉 Host 命令执行结果。
流程是:
Host → Controller: HCI_LE_Set_Scan_Enable Controller → Host: HCI_Command_Complete Event └── Status原文
Zero or more HCI_LE_Advertising_Report events are generated by the Controller based on legacy advertising packets received and the duplicate filtering. More than one advertising packet may be reported in each HCI_LE_Advertising_Report event. No report shall be issued for extended advertising PDUs.
翻译
Controller 会根据收到的 Legacy Advertising Packet,以及重复过滤设置,生成零个或多个:
HCI_LE_Advertising_Report Event每个HCI_LE_Advertising_Report Event中可以报告多个 advertising packet。
不会为 Extended Advertising PDU 生成报告。
也就是说,开启扫描成功后,不一定马上有扫描结果。
可能是:
0 个 Advertising Report 1 个 Advertising Report 多个 Advertising Report而且一个HCI_LE_Advertising_Report Event里面,可能包含多个设备或多个广播报告。
但是这个命令只对应 Legacy Advertising Report,不对应 Extended Advertising。
原文
When the Scanning_Filter_Policy is set to 0x02 or 0x03 and a directed advertisement was received where the advertiser used a resolvable private address which the Controller is unable to resolve, an HCI_LE_Directed_Advertising_Report event shall be generated instead of an HCI_LE_Advertising_Report event.
翻译
当Scanning_Filter_Policy设置为0x02或0x03时,如果收到一个 directed advertisement,并且广播设备使用了 Controller 无法解析的 Resolvable Private Address,那么 Controller 应生成:
HCI_LE_Directed_Advertising_Report Event而不是:
HCI_LE_Advertising_Report Event简单理解:
如果涉及定向广播、隐私地址、地址解析失败,就可能不会走普通的 Advertising Report,而是走 Directed Advertising Report。
这部分可以先知道有这个特殊分支,后面结合 Privacy、Resolving List、Directed Advertising 再深入。
Tip 1:LE Set Scan Parameters 是“配置”,LE Set Scan Enable 是“开关”
这两个命令要配合看。
LE Set Scan Parameters 配置怎么扫描 LE Set Scan Enable 控制开始扫描 / 停止扫描典型流程:
HCI_LE_Set_Scan_Parameters ↓ HCI_LE_Set_Scan_Enable = 0x01 ↓ Controller 开始扫描 Legacy Advertising PDU ↓ Controller 上报 HCI_LE_Advertising_Report Event ↓ HCI_LE_Set_Scan_Enable = 0x00Tip 2:这个命令只扫描 Legacy PDU,不扫描 Extended PDU
截图原文说得很明确:
legacy PDUs, but not extended PDUs所以:
HCI_LE_Set_Scan_Enable对应的是 Legacy Scanning。
如果你想扫描 Bluetooth 5 Extended Advertising,要用:
HCI_LE_Set_Extended_Scan_Parameters HCI_LE_Set_Extended_Scan_Enable不要把 Legacy Scan Enable 和 Extended Scan Enable 混在一起。
Tip 3:Filter_Duplicates 影响的是 Controller 上报给 Host 的次数
Filter_Duplicates不是让空口上的广播包消失。
广播设备仍然在发广播。
这个参数影响的是:
Controller 收到广播包后,要不要把重复的 advertising report 上报给 Host也就是说:
Filter_Duplicates = 0x00 Controller 可能频繁上报同一个设备的广播 Filter_Duplicates = 0x01 Controller 会过滤重复报告,Host 看到的上报会少很多所以做扫描工具类 App 时,如果你想实时刷新 RSSI,通常不能只依赖去重后的报告。
因为去重之后,同一个设备可能不会频繁上报,RSSI 更新就会不及时。
Tip 4:Filter_Duplicates = 0x01 时,不代表永远只上报一次
很多人容易误解为:
Filter_Duplicates = 0x01 同一个设备永远只上报一次这个理解不严谨。
更准确地说,它是 Controller 的重复 advertising report 过滤策略。实际什么时候认为是重复、什么时候重新上报,会和 Controller 实现、扫描周期、广播数据变化、地址类型、过滤状态等有关。
所以从 App 表现看,可能是:
同一个设备上报次数明显减少但不要简单理解成“绝对只上报一次”。
Tip 5:关闭扫描时,Filter_Duplicates 会被忽略
如果:
LE_Scan_Enable = 0x00那么:
Filter_Duplicates无论填0x00还是0x01,都会被忽略。
因为此时是在关闭扫描,不涉及后续扫描报告的去重。
Tip 6:扫描已经开启时,可以改变 Filter_Duplicates
这一点很细,但很重要。
规范说:
如果 LE_Scan_Enable = 0x01,并且 scanning is already enabled, Filter_Duplicates 的变化应生效。也就是说,扫描已经开着时,你可以再次发送:
HCI_LE_Set_Scan_Enable来切换重复过滤策略。
例如:
// 已经开启扫描,并且开启去重 LE_Scan_Enable = 0x01 Filter_Duplicates = 0x01 // 不停止扫描,直接改成关闭去重 LE_Scan_Enable = 0x01 Filter_Duplicates = 0x00这种情况下,新的Filter_Duplicates设置应该生效。
Tip 7:如果 Own_Address_Type 选 Random Address,要先 Set Random Address
如果之前在LE Set Scan Parameters里面配置了:
Own_Address_Type = 0x01或者:
Own_Address_Type = 0x03那么开启扫描前,通常要先调用:
HCI_LE_Set_Random_Address否则开启扫描时可能失败:
Invalid HCI Command Parameters,0x12这就是截图里第二条错误。
正确顺序类似:
HCI_LE_Set_Random_Address ↓ HCI_LE_Set_Scan_Parameters ↓ HCI_LE_Set_Scan_Enable = 0x01如果使用 Public Address:
Own_Address_Type = 0x00一般不需要设置 Random Address。
Tip 8:Advertising Report 是扫描结果,不是 Command 返回值
LE Set Scan Enable的命令返回结果是:
HCI_Command_Complete Event └── Status这只能说明:
扫描开关命令是否执行成功真正的扫描结果是后续异步上报的:
HCI_LE_Advertising_Report Event所以不要把这两个混淆。
完整理解应该是:
Command Complete Event: 告诉你“扫描开关命令成功没有” LE Advertising Report Event: 告诉你“扫到了哪些广播设备”Tip 9:开启扫描后,可能没有任何 Advertising Report
规范写的是:
Zero or more HCI_LE_Advertising_Report events也就是“零个或多个”。
所以即使命令返回成功,也不代表一定能马上扫到设备。
原因可能包括:
附近没有广播设备 扫描窗口没覆盖到广播包 广播包碰撞 过滤策略过滤掉了设备 开启了重复过滤 设备使用 Extended Advertising,而当前命令只扫 Legacy PDU Controller / Host 事件 mask 配置影响Tip 10:一个 Advertising Report Event 里可以包含多个报告
规范说:
More than one advertising packet may be reported in each HCI_LE_Advertising_Report event.也就是说,一个 HCI Event 里面可能带多个 advertising report。
所以解析时不能假设:
一个 HCI_LE_Advertising_Report Event = 一个设备更准确应该是:
一个 HCI_LE_Advertising_Report Event └── Num_Reports ├── Report 1 ├── Report 2 └── Report N这对后面解析LE Advertising Report Event很重要。