基于STM BlueNRG-MS的BLE外设仅允许已知设备连接实现咨询
BlueNRG-MS BLE外设连接过滤问题解决方案
1. 中心设备BDAddr动态变化的解决方法
你遇到的地址变更问题是因为当前主流移动系统(iOS、安卓)默认使用可解析私有地址(RPA),通常每15分钟更换一次,直接存储BDAddr做校验必然失效。
标准实现方案
- 配对绑定阶段不要只存对端BDAddr,要同时存储对端的身份解析密钥(IRK)、地址类型、长期密钥(LTK)等完整绑定信息
- 广播保持通用可发现模式,连接过滤采用「IRK地址解析+白名单」组合方案:能被本地存储的IRK成功解析的RPA设备,才允许发起连接
- 你原来在
EVT_LE_CONN_COMPLETE回调中校验的逻辑有缺陷:该事件触发时连接已经建立,校验不通过时需要主动调用断开命令,示例如下:
case EVT_LE_CONN_COMPLETE: { evt_le_connection_complete *cc = (void *)evt->data; uint8_t is_authorized = 0; // 优先用存储的IRK解析对端RPA,或者校验是否处于配对模式 if(acceptNewPairing || check_peer_authorized(cc->peer_bdaddr, cc->peer_bdaddr_type)){ is_authorized = 1; if(acceptNewPairing){ // 配对模式下保存对端完整绑定信息到非易失存储 save_bonded_device(cc->peer_bdaddr, cc->peer_bdaddr_type, get_peer_irk()); } GAP_ConnectionComplete_CB(cc->peer_bdaddr, cc->handle); } if(!is_authorized){ // 未授权设备直接断开连接 hci_disconnect(cc->handle, HCI_REMOTE_USER_TERMINATED_CONNECTION); } } break;
如果要实现更高效的过滤,直接用协议栈白名单能力即可,不需要在连接完成后再判断。
2. 白名单持久化与aci_gap_configure_whitelist函数说明
白名单持久化实现
蓝牙协议栈的白名单存储在RAM中,掉电自然丢失,持久化方案如下:
- 把所有已绑定设备的
bdaddr_type、bdaddr、IRK信息存储到BlueNRG-MS的内部Flash或者外挂EEPROM中 - 设备上电初始化协议栈之后,遍历本地存储的所有已绑定设备,挨个调用
hci_le_add_device_to_white_list()加载到协议栈白名单中即可
aci_gap_configure_whitelist函数作用
该函数用来配置白名单的过滤范围,调用时会清空当前已有白名单,正确调用顺序为:
- 调用
hci_le_clear_white_list()清空协议栈现有白名单 - 遍历本地存储的授权设备,挨个调用
hci_le_add_device_to_white_list()添加 - 最后调用
aci_gap_configure_whitelist()配置过滤规则:如果要实现「所有设备可发现、仅授权设备可连接」,参数配置为仅过滤连接请求即可,不要过滤扫描请求。
3. 解析列表函数替代方案
BlueNRG-MS的官方SDK没有单独的aci_gap_add_device_to_resolving_list函数,对应功能替代方案如下:
- 调用
aci_gap_set_privacy_mode()开启隐私地址解析功能,配置为允许已绑定设备的RPA解析即可,协议栈会自动用绑定过程中存储的IRK解析对端地址 - 如果使用的SDK版本过低不支持该功能,也可以手动实现RPA解析逻辑:按照蓝牙核心规范的RPA生成算法,用本地存储的IRK逐个匹配对端发来的RPA,匹配成功即判定为已授权设备
内容的提问来源于stack exchange,提问作者po.pe
相关产品推荐
相关产品推荐

