抓包工具入门:用 Ellisys 和 nRF Sniffer 定位断开时刻

做 BLE 开发,最怕什么?

我最怕那种「偶尔断一下,但就是找不到原因」的 bug。代码看了三遍,log 打了无数,设备就是不给面子。这时候,抓包工具就是你唯一的眼睛。

这一章,我带你把 Ellisys 和 nRF Sniffer 这两把刀磨快。咱们的目标很明确:抓到断开连接的那个瞬间,看清是谁发的断开包,原因码是什么。

为什么非得抓空中包?

你想想看,BLE 通信本质上是无线电波。代码里的 log 只能告诉你「我收到了断开事件」,但谁先发的断开请求?是 Master 还是 Slave?断开原因是什么?这些信息,log 往往给不全,甚至给错。

我在项目中遇到过好几次:客户说「你们的设备老是断连」,结果一抓包,发现是手机端主动断开的,原因码是 0x13(Remote User Terminated Connection)。这锅,咱不背。

核心原则: 不要相信 log,要相信空中包。抓包是 BLE 调试的「第一性原理」。

工具选型:Ellisys vs nRF Sniffer

目前主流就这两款。我个人的习惯是:

  • Ellisys:贵,但强。硬件解码、时序分析、多连接并发,都是顶级的。适合深度分析。
  • nRF Sniffer:免费,配合 Wireshark 使用。够用,但需要一点配置功夫。
对比项 Ellisys nRF Sniffer + Wireshark
价格 硬件 + 软件授权,较贵 硬件(nRF52840 DK)约 300 元,软件免费
易用性 开箱即用,自动解码 需要刷固件、配置 Wireshark
解码深度 LL、L2CAP、ATT、SM 全栈 基本全栈,但部分扩展特性支持弱
多连接支持 原生支持,自动跟踪 手动切换信道,较麻烦
适用场景 复杂问题、量产前验证 日常开发、快速定位
我的建议: 如果公司预算允许,买一台 Ellisys。如果只是个人学习或小团队开发,nRF Sniffer 完全够用。我自己是两把都备着——日常用 nRF,遇到疑难杂症上 Ellisys。

抓包前的准备工作

别急着开抓。先做三件事:

  1. 确认抓包器与被测设备在同一个物理空间。距离别超过 1 米,中间不要有金属障碍物。
  2. 关闭周围不必要的 BLE 设备。比如你的手机、手环、耳机。否则抓包文件里全是干扰包,你找断开包就像大海捞针。
  3. 设置好过滤条件。提前知道你要抓的设备的 MAC 地址或设备名。

嗯,这里要注意:nRF Sniffer 默认会抓所有信道上的包,但如果你只关心某个连接,最好在 Wireshark 里加上 btle.direction == 0 或 btle.direction == 1 来区分主从。

实战:抓取断开连接包

咱们以 nRF Sniffer + Wireshark 为例,走一遍完整流程。

步骤 1:启动抓包

把 nRF52840 DK 插上电脑,刷好 Sniffer 固件。打开 Wireshark,选择对应的串口。你会看到一堆 BLE 包刷屏——别慌,这是正常的。

步骤 2:过滤出目标设备

在 Wireshark 的过滤栏输入:

btle.advertising_address == 12:34:56:78:9a:bc

把地址换成你的设备地址。这样只显示该设备的广播包和连接包。

步骤 3:触发断开

让设备正常连接,然后手动触发断开(比如按按键、关电源、或者让程序主动断开)。

步骤 4:定位断开包

在 Wireshark 里,断开包通常是一个 LL_TERMINATE_IND 包。你可以直接过滤:

btle.ll_opcode == 0x02

或者更直观的:

btle.ll_terminate
关键信息: 找到 LL_TERMINATE_IND 包后,展开它的细节。你会看到两个重要字段:
  • Error Code:断开原因码。0x13 是用户主动断开,0x08 是连接超时,0x3E 是连接失败等等。
  • Initiator:谁发的这个包。如果是 Master,说明主机主动断开;如果是 Slave,说明从机主动断开。

Ellisys 的操作更简单

如果你用的是 Ellisys,那更省事。它自带一个「Connection」视图,所有连接状态变化都列在时间轴上。断开那一刻,会有一个红色的标记点。点一下,直接跳转到对应的 LL_TERMINATE_IND 包。

我记得有一次,客户说设备每 30 秒断一次。我用 Ellisys 一看,发现每次断开前都有一个 LL_CHANNEL_MAP_IND 包,然后紧接着就是断开。后来查出来是跳频算法有 bug,导致信道映射更新后连接参数不匹配。这种问题,用 nRF Sniffer 也能查,但 Ellisys 的时序视图让我一眼就看到了规律。

常见断开原因码速查表

抓到了断开包,下一步就是看原因码。这里列几个最常见的:

原因码 含义 常见场景
0x08 Connection Timeout 设备超出范围、干扰严重、连接间隔太长
0x13 Remote User Terminated 对端主动调用断开 API
0x16 Instant Passed 时序错误,常见于跳频或连接更新
0x22 LL Response Timeout 对端没响应,可能是死机或射频问题
0x3E Connection Failed to be Established 连接建立失败,常见于广播参数不匹配
避坑指南: 我曾经遇到过 0x08 断开,但抓包显示信号强度(RSSI)一直很好。后来发现是连接间隔设置得太长(超过 4 秒),而设备在某个时刻刚好错过了一个连接事件。所以,不要只看原因码,还要结合连接参数一起分析。

SVG:断开包定位流程

下面这张图,概括了从抓包到定位断开时刻的完整流程。你可以把它贴在工位上。

断开包定位流程 断开包定位流程 启动抓包 过滤目标设备 MAC 触发断开事件 过滤 btle.ll_terminate 读取 Error Code 提示:结合 RSSI 和连接间隔一起分析,不要只看原因码

常见问题与避坑

  • 抓包文件太大? 提前设置好过滤条件,只抓目标设备的包。或者用 Wireshark 的「捕获过滤器」而不是「显示过滤器」。
  • 找不到断开包? 检查一下抓包器是否跟上了跳频。nRF Sniffer 有时会丢包,尤其是多连接场景。这时候换 Ellisys 试试。
  • 断开原因码是 0x00? 0x00 表示「成功断开」,一般是正常流程。如果频繁出现,检查一下应用层的断开逻辑。
小技巧: 在 Wireshark 里,你可以右键点击 LL_TERMINATE_IND 包,选择「Follow → BLE Connection」。这样就能看到这个连接从建立到断开的完整生命周期,非常方便。