BLE Legacy 广播【过滤地址配置】

📅 2026/6/30 10:52:00
BLE Legacy 广播【过滤地址配置】
在 BLE Legacy 广播中有一个很重要但容易被忽略的概念Filter Accept List。它以前在很多资料里也叫White List也就是我们常说的白名单不过在新版 BLE 规范中更推荐使用Filter Accept List可以把它理解为 Controller 内部维护的一张“允许设备列表”。Host 可以通过 HCI Command 把某些设备地址添加到 Controller 的 Filter Accept List 中然后在广播、扫描、发起连接等流程里通过对应的 Filter Policy 参数让 Controller 只接受名单里的设备。本篇主要理解这四个命令LE Read Filter Accept List Size command LE Clear Filter Accept List command LE Add Device To Filter Accept List command LE Remove Device From Filter Accept List command对应 HCI Command 名称分别是HCI_LE_Read_Filter_Accept_List_Size HCI_LE_Clear_Filter_Accept_List HCI_LE_Add_Device_To_Filter_Accept_List HCI_LE_Remove_Device_From_Filter_Accept_List一、Filter Accept List 是什么Filter Accept List 是 BLE Controller 内部保存的一张设备地址列表。列表中的每一项通常包含Address_Type Address也就是地址类型 设备地址例如Address_Type 0x00 Address AA:BB:CC:DD:EE:FF表示添加一个 Public Device Address 设备。或者Address_Type 0x01 Address C1:22:33:44:55:66表示添加一个 Random Device Address 设备。注意Filter Accept List 本身只是“名单”真正让这张名单生效的是其他 HCI Command 中的 Filter Policy 参数。例如Advertising_Filter_Policy Scanning_Filter_Policy Initiator_Filter_Policy可以简单理解为Filter Accept List 名单本身 Filter Policy 是否使用这张名单以及怎么使用这张名单二、LE Clear Filter Accept List command 翻译命令名称HCI_LE_Clear_Filter_Accept_ListOCF0x0010命令参数none返回参数Status1. Description 翻译这个命令用于清除 Controller 中保存的 Filter Accept List。也就是说它会把 Controller 里面的过滤地址列表全部清空。这个命令不应在以下情况下使用第一如果某个 advertising filter policy 正在使用 Filter Accept List并且 advertising 已经启用。第二如果 scanning filter policy 正在使用 Filter Accept List并且 scanning 已经启用。第三如果 initiator filter policy 正在使用 Filter Accept List并且HCI_LE_Create_Connection或HCI_LE_Extended_Create_Connection命令正在等待完成。换句话说如果当前广播、扫描、发起连接流程正在使用 Filter Accept List就不应该直接清空这张表。2. Command parameters 翻译命令参数None也就是该命令没有命令参数。3. Return parameters 翻译返回参数Status大小1 octet返回值说明0x00表示HCI_LE_Clear_Filter_Accept_List command succeeded.也就是清空 Filter Accept List 成功。0x01 to 0xFF表示HCI_LE_Clear_Filter_Accept_List command failed.也就是命令执行失败具体失败原因需要查看 Controller Error Codes。4. Event 翻译当HCI_LE_Clear_Filter_Accept_List命令完成后Controller 会产生HCI_Command_Complete event前提是该事件没有被屏蔽掉。三、LE Add Device To Filter Accept List command 翻译命令名称HCI_LE_Add_Device_To_Filter_Accept_ListOCF0x0011命令参数Address_Type Address返回参数Status1. Description 翻译这个命令用于向 Controller 中保存的 Filter Accept List 添加一个设备。也就是说每执行一次该命令就添加一个设备地址到 Filter Accept List。这个命令不应在以下情况下使用第一如果某个 advertising filter policy 正在使用 Filter Accept List并且 advertising 已经启用。第二如果 scanning filter policy 正在使用 Filter Accept List并且 scanning 已经启用。第三如果 initiator filter policy 正在使用 Filter Accept List并且HCI_LE_Create_Connection或HCI_LE_Extended_Create_Connection命令正在等待完成。如果该设备已经在 Filter Accept List 中那么 Controller 不应该再次添加该设备并且应该返回成功。也就是说重复添加同一个设备时规范期望 Controller 不重复添加但仍然返回成功。当Address_Type设置为0xFF时Address参数应被忽略。2. Errors 翻译如果 Controller 因为没有可用空间无法再向 Filter Accept List 添加设备那么会返回Memory Capacity Exceeded错误码0x07也就是说Filter Accept List 的容量不是无限的。如果列表已经满了再添加设备就会失败。3. Command parameters 翻译Address_Type大小1 octet取值如下0x00Public Device Address 0x01Random Device Address 0xFFDevices sending anonymous advertisements 其他值Reserved for future use翻译如下0x00公共设备地址 0x01随机设备地址 0xFF发送匿名广播的设备 其他值保留供未来使用这里要注意Address_Type不是随便填的它决定后面的Address应该按什么类型来理解。Address大小6 octets参数含义Public Device Address or Random Device Address of the device to be added to the Filter Accept List.翻译要添加到 Filter Accept List 中的设备的 Public Device Address 或 Random Device Address。也就是说Address是一个 48-bit 蓝牙设备地址。格式示例0xXXXXXXXXXXXX但是如果Address_Type 0xFF表示添加“发送匿名广播的设备”这一类情况此时Address参数会被忽略。4. Return parameters 翻译返回参数Status大小1 octet返回值说明0x00表示HCI_LE_Add_Device_To_Filter_Accept_List command succeeded.也就是添加设备到 Filter Accept List 成功。0x01 to 0xFF表示HCI_LE_Add_Device_To_Filter_Accept_List command failed.也就是命令执行失败具体失败原因需要查看 Controller Error Codes。5. Event 翻译当HCI_LE_Add_Device_To_Filter_Accept_List命令完成后Controller 会产生HCI_Command_Complete event前提是该事件没有被屏蔽掉。四、LE Remove Device From Filter Accept List command 翻译命令名称HCI_LE_Remove_Device_From_Filter_Accept_ListOCF0x0012命令参数Address_Type Address返回参数Status1. Description 翻译这个命令用于从 Controller 中保存的 Filter Accept List 删除一个设备。也就是说每执行一次该命令就从 Filter Accept List 中删除一个指定设备地址。这个命令不应在以下情况下使用第一如果某个 advertising filter policy 正在使用 Filter Accept List并且 advertising 已经启用。第二如果 scanning filter policy 正在使用 Filter Accept List并且 scanning 已经启用。第三如果 initiator filter policy 正在使用 Filter Accept List并且HCI_LE_Create_Connection或HCI_LE_Extended_Create_Connection命令正在等待完成。当Address_Type设置为0xFF时Address参数应被忽略。2. Command parameters 翻译Address_Type大小1 octet取值如下0x00Public Device Address 0x01Random Device Address 0xFFDevices sending anonymous advertisements 其他值Reserved for future use翻译如下0x00公共设备地址 0x01随机设备地址 0xFF发送匿名广播的设备 其他值保留供未来使用Address大小6 octets参数含义Public Device Address or Random Device Address of the device to be removed from the Filter Accept List.翻译要从 Filter Accept List 中删除的设备的 Public Device Address 或 Random Device Address。也就是说删除时也需要同时指定Address_Type Address只有类型和值对应上Controller 才能知道你要删除的是哪一个设备。如果Address_Type 0xFF那么Address参数会被忽略。3. Return parameters 翻译返回参数Status大小1 octet返回值说明0x00表示HCI_LE_Remove_Device_From_Filter_Accept_List command succeeded.也就是从 Filter Accept List 中删除设备成功。0x01 to 0xFF表示HCI_LE_Remove_Device_From_Filter_Accept_List command failed.也就是命令执行失败具体失败原因需要查看 Controller Error Codes。4. Event 翻译当HCI_LE_Remove_Device_From_Filter_Accept_List命令完成后Controller 会产生HCI_Command_Complete event前提是该事件没有被屏蔽掉。五、LE Read Filter Accept List Size command 翻译命令名称HCI_LE_Read_Filter_Accept_List_SizeOCF0x000F命令参数none返回参数Status Filter_Accept_List_Size1. Description 翻译这个命令用于读取 Controller 当前可以存储的 Filter Accept List 条目数量。注意这里说的数量包括已经存储在 Filter Accept List 里面的条目。也就是说它读取的是Controller 当前能够保存的 Filter Accept List entry 总数量而不是当前已经添加了多少个设备规范中特别说明可存储的条目数量不是固定的Controller 可以在任何时候改变这个数量。例如存储 Filter Accept List 所使用的内存也可能被用于其他用途。所以这个容量值可能会随着 Controller 内部资源状态变化而变化。2. Command parameters 翻译命令参数None也就是该命令没有命令参数。3. Return parameters 翻译返回参数包括Status Filter_Accept_List_SizeStatus大小1 octet返回值说明0x00表示HCI_LE_Read_Filter_Accept_List_Size command succeeded.也就是读取 Filter Accept List Size 成功。0x01 to 0xFF表示HCI_LE_Read_Filter_Accept_List_Size command failed.也就是命令执行失败具体失败原因需要查看 Controller Error Codes。Filter_Accept_List_Size大小1 octet取值说明0x01 to 0xFF Controller 中可以存储的 Filter Accept List entry 总数量 0x00 Reserved for future use也就是说如果返回Filter_Accept_List_Size 0x08表示 Controller 当前可以保存 8 个 Filter Accept List 条目。注意它不是“当前已经保存了 8 个设备”而是“最多可以保存 8 个条目”。4. Event 翻译当HCI_LE_Read_Filter_Accept_List_Size命令完成后Controller 会产生HCI_Command_Complete event前提是该事件没有被屏蔽掉。六、这四个命令的关系这四个命令都是用来管理 Controller 中的 Filter Accept List。可以这样理解LE Filter Accept List 管理命令 ├── LE Read Filter Accept List Size │ └── 读取 Controller 当前可存储的 Filter Accept List 条目总数量 ├── LE Clear Filter Accept List │ └── 清空整个 Filter Accept List ├── LE Add Device To Filter Accept List │ └── 向 Filter Accept List 添加一个设备 └── LE Remove Device From Filter Accept List └── 从 Filter Accept List 删除一个设备它们本身只负责“维护名单”并不直接决定广播、扫描、连接流程如何过滤设备。真正让这张名单参与过滤的是Advertising_Filter_Policy Scanning_Filter_Policy Initiator_Filter_Policy七、Filter Accept List 在 Legacy 广播中的作用在 Legacy Advertising 中Filter Accept List 主要通过LE Set Advertising Parameters command里的Advertising_Filter_Policy来使用。Advertising_Filter_Policy可以决定是否允许任意设备发送 Scan Request 是否允许任意设备发送 Connect Request 是否只允许 Filter Accept List 中的设备发送 Scan Request 是否只允许 Filter Accept List 中的设备发送 Connect Request也就是说Peripheral 设备在广播时可以通过 Filter Accept List 控制谁可以扫描我 谁可以连接我例如只允许 Filter Accept List 中的设备扫描 只允许 Filter Accept List 中的设备连接这对于一些需要限制连接对象的设备很有用。八、典型场景外设只允许指定中心设备连接假设一个 BLE Peripheral 只希望某个 Central 设备连接自己。那么可以大致这样配置1. 关闭广播 HCI_LE_Set_Advertising_Enable Advertising_Enable 0x00 2. 清空 Filter Accept List HCI_LE_Clear_Filter_Accept_List 3. 添加允许连接的 Central 地址 HCI_LE_Add_Device_To_Filter_Accept_List Address_Type 0x00 或 0x01 Address Central 的设备地址 4. 配置 Legacy 广播参数 HCI_LE_Set_Advertising_Parameters Advertising_Filter_Policy 只允许 Filter Accept List 中的设备连接 5. 配置广播数据 HCI_LE_Set_Advertising_Data 6. 配置扫描响应数据可选 HCI_LE_Set_Scan_Response_Data 7. 开启广播 HCI_LE_Set_Advertising_Enable Advertising_Enable 0x01这样 Controller 在链路层就可以根据 Filter Accept List 过滤对端设备。如果对端设备不在名单里它的连接请求就不会被接受。九、典型场景中心设备只扫描指定外设虽然这篇文章标题是 Legacy 广播但 Filter Accept List 不只用于广播也可以用于扫描。Central 设备扫描时可以通过LE Set Scan Parameters command里的Scanning_Filter_Policy来使用 Filter Accept List。例如只扫描名单中的设备1. 关闭扫描 HCI_LE_Set_Scan_Enable LE_Scan_Enable 0x00 2. 清空 Filter Accept List HCI_LE_Clear_Filter_Accept_List 3. 添加目标外设地址 HCI_LE_Add_Device_To_Filter_Accept_List Address_Type 0x00 或 0x01 Address Peripheral 的设备地址 4. 配置扫描参数 HCI_LE_Set_Scan_Parameters Scanning_Filter_Policy 只接收 Filter Accept List 中设备的广播 5. 开启扫描 HCI_LE_Set_Scan_Enable LE_Scan_Enable 0x01这样 Controller 可以在扫描阶段过滤掉不在名单里的广播设备。十、典型场景中心设备从名单中发起连接Central 设备发起连接时也可以通过LE Create Connection command里的Initiator_Filter_Policy来使用 Filter Accept List。如果Initiator_Filter_Policy配置为使用 Filter Accept List那么 Initiator 可以从名单中的设备里选择目标发起连接。大致流程是1. 清空 Filter Accept List 2. 添加一个或多个目标设备地址 3. 配置 LE Create Connection Initiator_Filter_Policy 使用 Filter Accept List 4. Controller 根据名单中的设备尝试创建连接这和指定单个 Peer_Address 发起连接不同。指定 Peer_Address 是连接某一个明确设备。使用 Filter Accept List 则是看到名单里的设备就可以尝试发起连接十一、修改 Filter Accept List 前为什么要关闭广播/扫描/连接流程规范中反复强调Clear / Add / Remove Filter Accept List不应该在以下场景执行1. 广播过滤策略正在使用 Filter Accept List并且广播已经开启 2. 扫描过滤策略正在使用 Filter Accept List并且扫描已经开启 3. 发起连接过滤策略正在使用 Filter Accept List并且连接创建命令正在等待完成原因很简单Filter Accept List 正在被 Controller 用于实时过滤。如果这个时候 Host 又去清空、添加、删除名单Controller 当前的过滤行为可能变得不确定。所以规范要求不要这样使用。实际开发中建议要修改 Filter Accept List 先 Disable 当前相关流程 再 Clear / Add / Remove 最后重新 Enable 对应流程例如修改广播用的 Filter Accept List先关闭广播 修改 Filter Accept List 重新配置 Advertising_Filter_Policy 再开启广播修改扫描用的 Filter Accept List先关闭扫描 修改 Filter Accept List 重新配置 Scanning_Filter_Policy 再开启扫描修改发起连接用的 Filter Accept List确保当前没有 pending 的 Create Connection 再修改 Filter Accept List十二、Address_Type 0xFF 是什么意思在 Add 和 Remove 命令中Address_Type有一个特殊值0xFF它表示Devices sending anonymous advertisements也就是发送匿名广播的设备当Address_Type 0xFF时Address 参数会被忽略原因也很好理解匿名广播本身不携带可用于识别的设备地址所以这里不是添加某一个具体地址而是针对“发送匿名广播的设备”这一类情况。对于普通 Legacy 广播学习来说最常见的还是0x00Public Device Address 0x01Random Device Address0xFF可以先知道有这个特殊值不需要一开始就过度展开。十三、重复添加同一个设备会怎样规范中明确说如果设备已经在 Filter Accept List 里面那么 Controller 不应该再次添加该设备并且应该返回成功。也就是说重复添加同一个Address_Type Address时期望结果是不重复添加 返回 success这点对 Host 侧实现比较友好。不过实际开发中Host 侧最好还是自己维护一份列表避免频繁重复添加。十四、LE Read Filter Accept List Size 不是读取当前名单内容这个点非常容易误解。LE Read Filter Accept List Size读取的是Controller 当前可以存储多少个 Filter Accept List entry它不是读取当前 Filter Accept List 里面有哪些设备也不是读取当前已经添加了几个设备标准 HCI Command 中通常没有一个命令可以直接把当前 Filter Accept List 的完整内容读出来。所以 Host 侧如果关心当前名单内容应该自己维护一份同步记录。例如Host 侧维护 [ { Address_Type: 0x00, Address: AA:BB:CC:DD:EE:FF }, { Address_Type: 0x01, Address: C1:22:33:44:55:66 } ]然后每次 Add / Remove 成功后Host 同步更新自己的记录。十五、Filter Accept List Size 也不是永远固定不变规范中特别提到The number of entries that can be stored is not fixed.也就是说Controller 可以存储的 Filter Accept List 条目数量不是固定的。原因是 Controller 内部内存资源可能被多个功能共用。例如Filter Accept List Resolving List 其他 Controller 内部用途可能都会占用内部资源。所以Filter_Accept_List_Size表示的是Controller 当前这个时间点可以存储的条目数量而不是永久固定容量。因此在比较严谨的实现中可以在使用前读取一次容量然后根据返回值决定最多添加多少个设备。十六、Add 失败常见原因Memory Capacity Exceeded添加设备到 Filter Accept List 时最典型的失败原因是Memory Capacity Exceeded错误码0x07含义是Controller 没有足够空间继续添加设备所以如果添加失败不要只怀疑地址格式错误也要考虑Filter Accept List 是否已经满了 Controller 当前可用资源是否不足可以先执行HCI_LE_Read_Filter_Accept_List_Size看一下 Controller 当前支持的容量再决定添加策略。十七、Filter Accept List 和 Random Address 的关系Filter Accept List 中可以添加Public Device Address Random Device Address而 BLE 设备自身也可能使用 Random Device Address 进行广播。但是这里要区分两个概念LE Set Random Address 设置本设备自己的随机地址 LE Add Device To Filter Accept List 添加对端设备的地址到过滤名单举例你的模块作为 Peripheral 广播它通过HCI_LE_Set_Random_Address设置自己的随机地址。而它通过HCI_LE_Add_Device_To_Filter_Accept_List添加的是允许扫描或连接自己的 Central 设备地址。所以两者不是一回事Set Random Address配置“我是谁” Filter Accept List配置“我接受谁”十八、Filter Accept List 和 Resolving List 的关系Filter Accept List 也不是 Resolving List。Filter Accept List 用于过滤设备决定是否接受某个对端设备 Resolving List 用于解析 Resolvable Private Address决定某个变化的 RPA 是否属于已知设备如果对端设备使用的是 Public Device Address 或 Static Random Address那么把它的地址加入 Filter Accept List 比较容易理解。但如果对端设备使用的是 Resolvable Private Address也就是 RPA那么情况就复杂一些。因为 RPA 会变化。这时仅仅把当前看到的 RPA 地址加入 Filter Accept List通常不能长期稳定识别这个设备。更完整的隐私地址识别会涉及IRK Resolving List Address Resolution Identity Address所以要记住Filter Accept List 负责过滤 Resolving List 负责解析隐私地址它们可以配合使用但不是同一个东西。十九、在 Legacy 广播中的推荐配置流程如果你要让 Peripheral 在 Legacy 广播中只允许指定设备扫描或连接可以按这个思路配置1. 关闭广播 HCI_LE_Set_Advertising_Enable Advertising_Enable 0x00 2. 读取 Filter Accept List 容量可选 HCI_LE_Read_Filter_Accept_List_Size 3. 清空 Filter Accept List HCI_LE_Clear_Filter_Accept_List 4. 添加允许的对端设备 HCI_LE_Add_Device_To_Filter_Accept_List Address_Type 0x00 或 0x01 Address 对端设备地址 5. 配置 Legacy 广播参数 HCI_LE_Set_Advertising_Parameters Advertising_Filter_Policy 使用 Filter Accept List 的策略 6. 配置广播数据 HCI_LE_Set_Advertising_Data 7. 配置扫描响应数据可选 HCI_LE_Set_Scan_Response_Data 8. 开启广播 HCI_LE_Set_Advertising_Enable Advertising_Enable 0x01重点不是 Add 命令本身而是Add 只是把地址放进名单 Advertising_Filter_Policy 才决定广播时怎么使用这张名单二十、常见误区总结误区一Filter Accept List 配置后一定生效不一定。Filter Accept List 只是名单本身。是否生效要看对应流程的 Filter Policy 是否使用它。例如 Legacy 广播中要看Advertising_Filter_Policy扫描中要看Scanning_Filter_Policy发起连接中要看Initiator_Filter_Policy误区二Read Filter Accept List Size 可以读取当前名单内容不能。它只能读取 Controller 当前可以存储的条目总数量。它不能告诉你当前名单里有哪些设备 当前已经添加了几个设备这些信息通常要 Host 自己维护。误区三广播开启后可以随便修改 Filter Accept List不建议也不符合规范约束。如果广播过滤策略正在使用 Filter Accept List并且广播已经开启那么不应该 Clear / Add / Remove。正确做法是先关闭广播 再修改 Filter Accept List 再重新开启广播误区四Address_Type 只看地址值就行不对。Filter Accept List 的条目要同时看Address_Type Address同一个 48-bit 地址值如果 Address_Type 不同语义也不同。所以添加和删除时都要同时指定地址类型和地址值。误区五Filter Accept List 可以长期识别所有随机地址设备不一定。如果对端使用的是 Static Random Address相对容易。如果对端使用的是 Resolvable Private Address它会变化需要结合 IRK、Resolving List、Address Resolution 等机制理解。不能简单认为把当前看到的随机地址加入 Filter Accept List以后就永远能识别它二十一、总结这四个命令的核心作用是维护 Controller 中的 Filter Accept ListHCI_LE_Read_Filter_Accept_List_Size 读取 Controller 当前可以保存多少个 Filter Accept List 条目 HCI_LE_Clear_Filter_Accept_List 清空 Filter Accept List HCI_LE_Add_Device_To_Filter_Accept_List 添加一个设备到 Filter Accept List HCI_LE_Remove_Device_From_Filter_Accept_List 从 Filter Accept List 删除一个设备但是它们只是“名单管理命令”并不直接决定广播、扫描、连接是否过滤。真正让名单生效的是Advertising_Filter_Policy Scanning_Filter_Policy Initiator_Filter_Policy在 BLE Legacy 广播中如果你想限制谁可以扫描你、谁可以连接你核心思路就是1. 先维护 Filter Accept List 2. 再在 Advertising_Filter_Policy 中选择使用 Filter Accept List 3. 最后开启 Legacy Advertising一句话总结Filter Accept List 负责保存“允许的对端设备” Filter Policy 负责决定“当前广播、扫描、连接流程是否使用这张名单”。