高级过滤技巧:BD_ADDR、PDU类型与RSSI

抓包这件事,说白了就是在一堆噪声里找到你要的信号。默认情况下,抓包工具会把空中所有BLE包都收进来——你想想看,办公室里可能有几十台手机、耳机、手环同时在广播,那个列表刷得飞快,根本没法看。

所以,过滤是第一步,也是最关键的一步。我个人习惯,每次开始抓包前,先想清楚三个问题:看哪个设备?看哪种包?信号要多强?这三个问题对应就是BD_ADDR过滤、PDU类型过滤和RSSI过滤。

基于BD_ADDR的过滤

这是最常用的过滤方式。你只关心某个特定设备,那就把它的蓝牙地址填进去,其他设备一概忽略。

BD_ADDR分两种:公共地址(Public Address)和随机地址(Random Address)。随机地址里又分静态随机和私有随机。我在项目中遇到过好几次,明明填了设备的MAC地址,但就是抓不到包——后来发现,设备用的是可解析私有地址(RPA),地址每隔几分钟就变一次。

避坑指南:我曾经花了一整个下午排查为什么抓不到某个手环的包。后来才发现,手环每次重连都会换一个随机地址。如果你遇到类似情况,试试用IRK(Identity Resolving Key)来过滤,而不是直接填地址。

不同工具的BD_ADDR过滤写法略有差异,但核心逻辑一样:

工具 过滤语法示例 说明
Wireshark + btle btle.advertising_address == 11:22:33:44:55:66 精确匹配广播地址
nRF Sniffer 在设备列表勾选目标设备 图形化操作,自动过滤
Ellisys 在Address Book添加设备 支持IRK解析
btmon (Linux) 配合btfilter工具 命令行方式
小技巧:如果你不确定设备地址类型,可以先不加过滤抓几秒,然后在抓包结果里找到目标设备的包,右键选择"Prepare as Filter"——工具会自动帮你生成正确的过滤表达式。

基于PDU类型的过滤

BLE的空中包有很多种类型。你想想看,如果只想看广播包,结果连扫描请求和连接请求也混进来,那分析起来就很乱。

PDU类型过滤,就是让你只关注某一种或某几种包。常见的PDU类型有:

  • ADV_IND:可连接的非定向广播,最常见的广播包
  • ADV_DIRECT_IND:定向广播,指定了目标设备
  • ADV_NONCONN_IND:不可连接的非定向广播,信标常用
  • SCAN_REQ / SCAN_RSP:扫描请求和扫描响应
  • CONNECT_REQ:连接请求,包含连接参数
  • AUX_ADV_IND:扩展广播包(BLE 5.0+)

我个人最常用的是ADV_IND + CONNECT_REQ的组合过滤。为什么?因为ADV_IND能让我看到设备在广播什么,CONNECT_REQ能让我看到连接建立的瞬间——这两个包基本能覆盖90%的调试场景。

实战场景:调试蓝牙耳机配对问题时,我通常会同时过滤ADV_IND和CONNECT_REQ。先看耳机广播的Service UUID对不对,再看手机发起的CONNECT_REQ里携带的连接参数是否合理。有一次发现耳机广播的Tx Power Level明显偏低,导致手机认为信号不好,主动降低了连接间隔——这就是典型的"广播参数影响连接质量"的案例。

在Wireshark里,PDU类型过滤可以这样写:

# 只看可连接广播
btle.advertising_header.pdu_type == 0

# 只看扫描请求
btle.advertising_header.pdu_type == 2

# 只看连接请求
btle.advertising_header.pdu_type == 5

# 组合过滤:广播 + 连接请求
btle.advertising_header.pdu_type == 0 || btle.advertising_header.pdu_type == 5

基于RSSI的过滤

RSSI过滤,说白了就是按信号强度筛包。这个功能在嘈杂环境里特别有用。

我记得有一次在展会上做演示,周围几十个蓝牙设备同时在工作,抓包界面完全被刷屏了。我直接把RSSI过滤设为-50 dBm以上,瞬间只剩下离我最近的那台设备——因为其他设备距离远,信号弱,直接被过滤掉了。

RSSI过滤的典型应用场景:

  • 近距离调试:设-40 dBm以上,只抓贴脸设备的包
  • 排除干扰:设-70 dBm以上,过滤掉远处的噪声设备
  • 信号覆盖测试:设-80 dBm以下,看哪些区域信号弱
注意:RSSI值受环境影响很大。同一台设备,隔一堵墙RSSI可能下降20 dBm。我建议你先不加RSSI过滤抓几秒,看看目标设备的RSSI大概在什么范围,再设置合理的阈值。别一上来就设-40 dBm,结果啥也抓不到。

Wireshark的RSSI过滤语法:

# 只看信号强度大于-60 dBm的包
btle.rssi > -60

# 只看信号强度在-50到-70之间的包
btle.rssi > -70 && btle.rssi < -50

# 组合过滤:特定设备 + 强信号
btle.advertising_address == 11:22:33:44:55:66 && btle.rssi > -60

三种过滤的协同使用

实际工作中,这三种过滤很少单独使用。我通常的做法是:先按BD_ADDR锁定设备,再按PDU类型缩小范围,最后用RSSI排除干扰。

举个例子,调试一个蓝牙门锁的广播问题:

  1. 先加BD_ADDR过滤,只看门锁的包
  2. 再加PDU类型过滤,只看ADV_IND(不看扫描和连接)
  3. 最后加RSSI过滤,只保留-60 dBm以上的包(排除远处同型号门锁的干扰)

这样组合下来,抓包界面通常就只剩几条干净的广播包,分析起来非常轻松。

我的习惯:我会把常用的过滤组合保存成配置文件。比如"门锁调试"、"耳机配对"、"信标测距"各存一份,下次直接加载,不用重新写过滤表达式。

知识体系总览

下面这张图,把三种过滤的关系和适用场景整理了一下:

BLE抓包过滤知识体系 三种过滤方式 BD_ADDR过滤 PDU类型过滤 RSSI过滤 公共地址 随机地址 IRK解析 ADV_IND SCAN_REQ CONNECT_REQ 阈值设定 环境校准 组合过滤 核心原则:先锁定设备 → 再缩小类型 → 最后排除噪声 三种过滤组合使用,效果远大于单独使用

嗯,到这里,三种过滤技巧就讲完了。你可能会问:这些过滤在实际项目中到底怎么用?别急,后面几章我会结合具体的抓包案例,一步步演示怎么用这些过滤技巧快速定位问题。