ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

nRF52840 Dongle + Wireshark 低功耗蓝牙抓包实战全攻略

nRF52840 Dongle + Wireshark 低功耗蓝牙抓包实战全攻略 做蓝牙开发这几年我最大的感受是应用层出了问题能打日志协议栈内部出了问题就只能抓瞎。手机端的调试软件可以告诉你服务有哪些、特征值怎么读写可是设备在广播、连接、断线时空中到底发生了什么它看不到。nRF52840 Dongle加Wireshark这套组合就是解决这个问题最经济实用的入口。几十块钱的接收器配上免费开源的Wireshark就能把BLE空口数据包一帧一帧地抓下来看广播、扫描、连接请求、数据交互、加密握手全部可视化。这篇内容特别适合刚接触BLE开发的软硬件工程师或者正在做蓝牙外设联调、协议栈开发、低功耗优化的朋友。今天我把整套流程从头到尾捋一遍包括硬件怎么选、固件怎么刷、Wireshark怎么配、包怎么抓、怎么解密最后再把我自己踩过的坑全部摊开照着做应该不会再卡住。1. 为什么是nRF52840 Dongle抓包方案选型对比1.1 各种抓包方案的横向对比我第一次想抓BLE空口数据时先试的其实是手机端方案。用nRF Connect这类App确实能看广播内容也能连接设备之后读写特征值但它只能看到协议栈已经解析好的应用层数据。底层那个包长什么样、广播重发了几次、连接间隔实际是多少、加密是怎么握手的这些关键信息完全看不到。对于调试来说这种“半透明”状态还不如直接看日志来得快。后来我依次评估过几种方案。一是逻辑分析仪加解码插件精度和带宽跟不上2.4GHz的射频信号而且BLE是跳频的逻辑分析仪根本不知道频率跳到哪里去了。二是专业的蓝牙协议分析仪像Teledyne LeCroy、Ellisys这些功能确实强但价格动辄几万几十万个人开发者和小团队基本不用想。三是TI的CC2540 USB Dongle这是老一代方案便宜但只支持BLE 4.0跟不上现在的蓝牙5设备2M PHY和编码物理层CODED PHY都解不了。最后我选了nRF52840 Dongle。这块小板子几十块钱Nordic官方直接维护抓包固件和Wireshark插件支持BLE 5的新特性社区资料也全。对个人调试和中小团队来说没有比它更合适的方案了。1.2 nRF52840 Dongle的硬件底子与工作原理这个Dongle的官方型号是PCA10059外形就是个普通U盘上面有一块PCB天线、一个RGB状态灯、一个重置按键、一个用户按键USB接口直接连接到板子上的nRF52840芯片。nRF52840本身是一颗Cortex-M4F内核的低功耗蓝牙SoC支持BLE 5、802.15.4、私有2.4GHz协议Flash有1MBRAM有256KB拿来当抓包器完全是降维打击。关键点在于Dongle上的固件。出厂默认固件是蓝牙DFU Bootloader通过USB插上后会虚拟出一个串口。你需要把Nordic提供的Sniffer固件刷进去让这颗芯片进入“监听模式”。监听模式下的工作原理相当于一个24小时值班的窃听者——它不发起连接、不回应广播、不占用任何信道资源只是把空气中符合BLE规范的数据帧接收下来再通过USB虚拟串口把数据帧送到电脑上由Wireshark的nRF Sniffer插件完成解析和显示。这里有个容易误解的地方Dongle并不是在全部40个信道里同时听。BLE有40个2MHz带宽的信道其中37、38、39是广播信道其余37个是数据信道。Dongle在没有锁定目标时主要是在三个广播信道间轮询监听捕捉周围设备的广播包。当它捕获到一个连接请求之后会根据连接请求里携带的信道跳频表、跳频增量、连接事件间隔这些参数自动跟着设备的跳频序列走继续监听连接后的数据信道交互。正因为它能“跟随跳频”你才能完整抓到一对设备从广播到连接再到数据交互的全过程。这也是nRF Sniffer方案区别于普通无线抓包工具的核心理由。2. 开工前的完整准备从刷固件到Wireshark安装2.1 给Dongle刷写Sniffer固件的两种方法拿到一块全新的nRF52840 Dongle第一步不是打开Wireshark而是先刷Sniffer固件。这里提供两条路径任选一条。先说最省事的方式用nRF Connect for Desktop这个图形化工具。先到Nordic官网下载nRF Connect for Desktop以及nRF Sniffer for BLE的固件包。后者会包含一个hex格式的固件文件通常命名为类似nrf_sniffer_for_ble_xxx.hex推荐用最新版本兼容性好。安装好nRF Connect for Desktop后在App列表里找到Programmer这个应用打开它。接下来要让Dongle进入DFU模式。操作方法是按住Dongle上的重置按键不松手然后把Dongle插入电脑USB口等大概一两秒再松开。这时候RGB指示灯会变成红色并缓慢呼吸说明已经进入Bootloader模式。在Programmer界面里应该能看到一个识别为OpenDFU Bootloader的设备。选好设备后把刚才的hex固件拖进去点击Program按钮等待烧写完成。完成后重新插拔驱动装上后Dongle就变成一台BLE嗅探器了。第二条路径是命令行方式用Nordic官方提供的nrfutil工具。我个人在批量刷多块Dongle时会用这个方式效率更高。安装好nrfutil并确保能执行后进入DFU模式的步骤和上面一样然后执行类似这样的命令nrfutil dfu serial -pkg sniffer_dfu_package.zip -p COM8 -b 115200这里的sniffer_dfu_package.zip是Nordic固件包里的DFU升级包COM8是Dongle进入DFU模式后在设备管理器中生成的串口号。如果是在Linux或macOS下串口设备一般是/dev/ttyACM0或/dev/cu.usbmodem*这种按实际环境调整就行。2.2 Wireshark版本、Python环境与extcap插件配置固件刷好之后还需要让Wireshark认识这个Dongle。Wireshark建议直接装4.x版本越新越好老版本对蓝牙LE和nRF Sniffer插件的兼容性差很多。安装时注意勾选安装Npcap/USBPcap这些底层抓包驱动Windows下如果少了Npcap很多捕获功能会莫名其妙失效。装完Wireshark后还需要把nRF Sniffer for BLE安装包里的extcap插件复制进去。这个步骤很多人会漏掉导致Wireshark里找不到nRF Sniffer接口。打开你下载的nRF Sniffer for BLE固件包里面会有一个extcap目录。把其中所有内容复制到Wireshark的extcap插件目录里。Windows下通常在C:\Program Files\Wireshark\extcapmacOS一般在/Applications/Wireshark.app/Contents/PlugIns/wireshark/下对应位置Linux发行版的路径会因安装方式不同而有区别可以用whereis wireshark查一下。这里有个大坑nRF Sniffer的extcap插件本质是一个Python脚本Wireshark调用它时依赖系统里的Python解释器。如果你的电脑没装Python或者装了但没把Python加入系统PATH环境变量那么接口列表里即使显示了nRF Sniffer点击开始捕获也会直接报错。解决办法是装一个Python 3.9以上的版本安装时注意勾选“Add Python to PATH”。配置好之后重启Wireshark在主页的捕获接口列表里应该能看到一个名为nRF Sniffer for BLE的接口。前面带一个像螺丝刀一样的小图标这就是extcap插件提供的接口。2.3 接口识别与基本连通性验证第一次看到nRF Sniffer接口先别急着抓业务包我建议花一分钟做个连通性验证。把Dongle插好打开Wireshark选择nRF Sniffer接口点击开始捕获。这时候如果周围有正在广播的蓝牙设备主界面应该会不断滚出广播包。Wireshark状态栏会显示类似“Packets: xxx · Displayed: xxx”的动态数字说明USB通路、extcap脚本、数据解析链路都正常。如果一帧都没出现先看硬件层Dongle的RGB灯是什么颜色。正常监听模式下灯应该以特定颜色闪烁或长亮如果灯是红色呼吸状态说明Dongle还停留在DFU模式需要重新刷一遍Sniffer固件。如果灯正常但抓不到包可能把Dongle放到了一个信号很弱的位置或者周围确实没有活动设备可以拿手机开个广播热点再做测试。3. 实战抓包从广播到连接的最全操作流程3.1 抓取广播包快速定位目标设备的广播数据先看最基础的场景抓广播包。假设你现在想分析自己开发的低功耗设备它上电后会在广播信道周期性发送广播报文。这时候抓包非常直接——打开nRF Sniffer接口开始捕获就能看到周围所有设备的广播。Wireshark里每个广播包展开后可以看到完整的BLE链路层结构。广播包的Access Address是固定的0x8E89BED6这是BLE规范里广播信道专用的接入地址。再往下是PDU头里面的PDU Type字段标明了广播类型常见的有ADV_IND可连接无定向广播、ADV_DIRECT_IND定向广播、ADV_NONCONN_IND不可连接无定向广播、ADV_SCAN_IND可扫描无定向广播。然后是广播数据部分这就是你在手机App里看到的设备名、厂商数据、服务UUID列表等。不过建议直接用过滤器因为周围设备太多了手动翻包不现实。广播地址过滤是最常用的语法是btle.advertising_address XX:XX:XX:XX:XX:XX把XX:XX:XX:XX:XX:XX替换成你目标设备的广播地址。如果你不知道目标设备的地址可以先不用过滤器抓一会儿然后在包列表里找到设备名对应的广播包右键选择“作为过滤器应用”之类的选项快速生成过滤表达式。另外一个有用的查看字段是RSSI。在Wireshark的包详情树里nRF Sniffer插件会提供Nordic扩展信息里面能看到接收信号强度。这个数值能帮你判断Dongle和被测设备之间的无线环境是否理想。一般来说RSSI低于-80dBm时抓包质量会很差丢包率明显上升这时候应该把Dongle挪近一点或者调整设备天线的方向。3.2 抓取连接交互完整捕捉连接建立与数据交互广播包只是开胃菜真正有挑战的是抓取两个设备建立连接之后的数据交互。nRF Sniffer的杀手锏就在这里它能在捕获到连接请求包之后自动跟随设备的跳频序列把后续连接事件里的所有数据包都接住。具体操作流程是先开始捕获找到你关心的目标设备广播地址然后在Wireshark顶部nRF Sniffer工具栏里把这个地址填进去并点击Follow。之后让两个设备建立连接比如手机打开蓝牙App去连接开发板。Dongle会一直监听广播信道捕获到连接请求CONNECT_IND后立即解析其中的跳频参数然后跳到对应的数据信道上继续抓包。连接建立后你会看到一类完全不同的报文。它们的Access Address不再是广播固定的0x8E89BED6而是连接双方协商出来的一个随机值。PDU类型也不再是广播包而是链路层数据包Data Channel PDU里面会有LL Data PDU承载的ATT/GATT交互内容。抓连接包时有个重要经验一定要在连接建立之前就点击Follow让它提前锁定目标设备。如果连接建立之后再做FollowDongle已经错过了连接请求包不知道跳频表之后的数据信道包基本都抓不到。连接事件在Wireshark里可以看得很清楚。每次连接事件开始主设备和从设备会依次发送数据包空闲时用空包填充。你可以看到Connection Interval是否和配置一致是否有重传重传的成本有多大。这些信息对于低功耗优化极其有价值比如你明明把连接间隔设成了30ms但实际看抓包发现设备经常需要重传真实吞吐和功耗就会和理论值差很远。3.3 用过滤器快速筛选关键交互连接建立之后数据包会非常多尤其是有些设备交互频繁几秒钟就能刷出几百个包。这时候得有策略地用过滤器。按链路层地址过滤是最基本的但要注意连接发起后地址类型可能变化。如果设备开启了地址隐私功能广播地址和数据包里的地址也不相同这时候更稳妥的方式是直接用Access Address过滤btle.access_address 0xXXXXXXXX从任意一个连接数据包里复制Access Address值填进去就能只看这个连接的数据包。如果你更关心应用层交互可以按ATT和GATT层过滤。比如只想看客户端发起的写操作可以用btatt.opcode 0x12这里0x12是ATT Write Request的操作码是需要对端回写响应的请求。如果设备用的是“无响应写”Write Command操作码是另外的值。只想看服务器主动上报的通知可以过滤btatt.opcode 0x1b这是Handle Value Notification也就是最常见的GATT通知低功耗蓝牙的数据上报大多走这个通道。高速数据流场景下我一般会先用底层过滤器把噪声去掉再逐步深入。比如先btle.access_address 0xXXXXXXXX锁设备再叠加上btatt.opcode 0x1b只看通知这样抓包列表会清爽很多定位问题的速度也快得多。3.4 解密加密连接让抓包数据“可读”如果你连接的设备启用了加密抓到的ATT/GATT数据解析出来会是一堆乱码所有payload都是加密后的密文。这是BLE的Security机制在起作用默认的加密算法会保护链路数据。这时候要想看清明文内容需要把密钥告诉Wireshark。别慌这看起来复杂其实就是往Wireshark里填几个参数。首先密钥从哪里来通常由被测设备在完成配对后打印到日志里。如果你用的是nRF Connect SDK或者Zephyr在配对回调里获取到struct bt_conn_info后可以读出Long Term KeyLTK、Session Key DiversifierSKD和Initialization VectorIV。如果开发板没有打印这些信息就需要自己加两行日志输出。打开Wireshark的偏好设置Edit → Preferences → Protocols → BLE。在解密的配置区找到LL Privacy和Encryption相关配置项。需要填的字段主要有三个LTK16字节配对后双方协商出的长期密钥SKD8字节本次会话的会话密钥派生因子IV4字节初始向量每个字段都以十六进制字符串形式填写注意去掉空格和冒号分隔符。填完后要确保勾选了“Try to decrypt encrypted L2CAP data”之类的解密开关不同版本该选项名称略有差异但位置都在BLE协议的偏好设置里。这里有几个非常容易踩的坑。第一个是字节序问题。有的设备固件打印日志时是MSB在前有的回调返回的数组是LSB在前直接填进去很容易解密失败。建议先从简单的连接开始抓一次之后看能不能解出明文如果解不出尝试把LTK、SKD、IV的字节序全部反转再试。第二个坑是地址隐私LL Privacy。如果设备启用了RPAResolvable Private Address那么在抓包时你会看到这个设备的地址一直变化每次广播或连接用的都是一个看起来随机的地址。这时候即使抓到连接Wireshark也找不到关联关系。解决办法还是在BLE偏好设置里填IRKIdentity Resolving Key它可以让Wireshark把同一IRK派生出来的所有RPA都归到固定的身份地址上方便跟踪。第三个坑是即使填对了密钥有些版本的Wireshark对特定PHY或者特定Feature的支持仍有缺陷。如果遇到解密后payload依然乱码先确认是不是抓包时天线位置不好导致丢包丢包会直接破坏密文完整性这时候需要补充重传包才能解出来。4. 常见错误与问题排查实录4.1 Wireshark找不到nRF Sniffer接口或点击开始报错这个问题出现的频率非常高我群里几乎每周都有人问。先区分两种情况接口列表里根本没出现和接口出现了但点开始后报错。先看接口列表里没有的情况。可能性一Dongle没有处于Sniffer固件状态而是停在了DFU引导模式。检查RGB灯如果是红色呼吸重新插一次并确认固件烧写成功。可能性二extcap插件没有复制到正确目录或者Wireshark版本太老不认识这个插件。建议确认插件文件是否和Wireshark版本匹配必要时重装最新版Wireshark。可能性三Windows下没有安装Npcap或USBPcap底层驱动缺失会导致extcap接口异常。再看过接口出现了但开始报错的情况。最常见的是extcap调用Python失败。在Windows上如果你装Python时没有勾选“Add Python to PATH”Wireshark调用nrf_sniffer_ble.py时会找不到解释器。处理方式很直接重装Python并勾选加入PATH或者手动把Python安装目录加到系统环境变量里然后重启Wireshark。还有一个隐蔽原因USB口供电不足。nRF52840 Dongle本身的功耗不高但如果你把它插在USB Hub上而且这个Hub又挂了硬盘、键鼠之类设备偶尔会出现Dongle工作不稳定。直接在笔记本或台式机主板USB口上测试往往就好了。4.2 抓不到目标设备的任何数据包这个问题的排查顺序很重要。先确认目标设备有没有在广播。用手机上的nRF Connect App扫描一下如果手机能看到说明设备在发广播如果手机也看不到那就是目标设备本身没起来和抓包工具无关。然后确认是不是距离和天线的问题。2.4GHz信号的穿透能力很差Dongle的PCB天线方向性强如果设备放在金属外壳的壳子里或者离Dongle有一堵墙隔着信号强度会急剧下降。把设备拿到Dongle旁边最好20厘米以内天线尽量正对大多数抓不到的问题都能缓解。还有一种情况是目标设备在广播但广播类型是不可连接的。有些设备用ADV_NONCONN_IND或SCAN_REQ相关流程只发送不可连接的广播包这种包里可能没有设备名你在Wireshark里手动翻页不一定能找到。这时候用广播类型过滤或者先抓一段时间再按MAC地址段的规律去找会容易一些。最后提醒一个新手最容易犯的错误Dongle在广播信道监听时只能看到广播包和扫描请求看不到已经建立连接的设备的数据通信。如果你什么都没设置就点开始捕获然后奇怪为什么自己那对已经连接了好几分钟的设备的数据包一个都看不到——这不奇怪Dongle没有捕获到连接请求没有跳频表自然跟不上去。必须提前锁定设备从头抓连接过程。4.3 解密失败密钥填了但还是乱码如果你已经很确定LTK、SKD、IV都填对了但解密出来依然是乱码甚至展开包详情时提示你“Missing key”或者“Decryption failed”多半是这几个问题之一。最常见的是字节序。我在实际项目里遇到过一个设备固件打印LTK时是主机字节序而Wireshark期望的是小端存放。这两者如果不匹配解密必然失败。解决方式是先把三个密钥的字节序反转然后重新加载抓包文件。Wireshark的BLE配置是即时生效的改完配置后重新打开pcapng文件不用再次抓包。第二个是漏填IRK。设备启用了LL Privacy之后链路层的地址是加密随机地址Wireshark需要用IRK来解析真实身份。如果不填IRKWireshark虽然能抓到包但无法把密文和密钥关联起来。这时候在BLE偏好设置里填入IRK再配合LTK、SKD、IV四项同时生效解密成功率会大幅提升。第三个是抓包本身有丢包。加密连接的解密依赖完整的数据帧序列任何一个包的缺失都可能导致后续包解不出来。如果抓包时RSSI很低或者Dongle跟随跳频时偶尔掉队就会产生丢包。解决办法是回到物理层面缩短距离、调整天线位置、改用短连接事件间隔重新抓一次。4.4 数据包乱序、时间戳异常与USB稳定性抓包偶尔出现包序错乱、时间戳跳跃或者同一连接事件里主从设备数据包的先后顺序看起来不合理这通常是USB传输和Wireshark解析之间的时序抖动造成的不会影响协议分析但会让你对“先发还是后发”的判断产生误解。nRF Sniffer的extcap通过USB虚拟串口把原始数据包传给电脑串口的发送节奏和空中实际时序并不严格对应。分析时应该以BLE协议本身的事件结构为准比如在一个连接事件里主设备发的包应当排在从设备的响应包之前这是协议层顺序如果Wireshark里显示的顺序和这个基本逻辑矛盾再考虑是不是抓包丢失导致事件错位。如果异常特别频繁优先排查USB稳定性。换一个直连的USB口不要走Hub把Dongle插到USB 2.0口就够用不用刻意用3.0检查电脑是不是有省电模式把USB口挂起。Windows的设备管理器中找到这个USB串行设备在电源管理选项卡里取消“允许计算机关闭此设备以节约电源”。实操过程中的一些心得最后分享几个我自己用下来的经验和习惯算是个补充。第一抓包前先把Wireshark的自动滚动开关和显示过滤器设好不然大量数据包涌入时界面会卡成幻灯片。第二重要场景抓包时尽量用有线连接电脑不要在虚拟机里跑Wireshark虚拟机的USB串口转发会把时间戳搞得很离谱。第三抓到一次有效会话后建议立即导出为pcapng文件存档文件名里注明项目、设备角色、日期这个习惯在后面对比不同固件版本行为时非常有用。如果你后续要做更深入的协议分析还可以试试Wireshark的“Follow”功能以及nRF Sniffer自带的信道选择功能。固定在某个数据信道上监听可以观察特定信道上的重传和干扰情况这在排查无线环境问题时作用很大。这套nRF52840 Dongle加Wireshark的方案说实话已经把个人开发者的蓝牙抓包门槛降得很低了。设备便宜、文档齐全、操作链路短只要把固件刷对、插件装好、密钥填对大部分BLE调试场景都能覆盖。希望这篇教程能帮你少走点弯路抓包顺利。
返回列表