news 2026/9/28 16:44:42

小米手机蓝牙HCI日志抓取与Wireshark解析实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
小米手机蓝牙HCI日志抓取与Wireshark解析实战指南

作为一名常年跟蓝牙外设打交道的开发,我太清楚那种“设备就在眼前,回连就是失败,Logcat翻了几百屏也看不出所以然”的滋味了。后来真正解决问题,靠的是小米手机上抓一份HCI log,再用Wireshark打开一帧一帧看协议栈底层的交互,问题基本半小时内就锁定了。这篇就把我一直用的小米手机HCI log抓取与解析流程完整写出来,含开关位置、导出命令、解析要点和避坑记录,照着做五分钟就能上手。

1. 先搞清楚HCI log到底在记录什么

1.1 一次真实的蓝牙调试现场

之前做一款BLE体重秤的适配,遇到一个特别诡异的问题:小米手机上App读历史记录经常超时,但同一台秤换iPhone就一切正常。我在Logcat里看了半天,只看到GATT回调偶尔报133错误,至于为什么报133、是手机发的读请求没到秤端,还是秤端回了数据但手机没收到,完全看不出来。

后来在小米手机上打开蓝牙HCI日志,重新复现了一次超时,导出日志用Wireshark打开,一帧一帧对照,发现是秤端返回的Read Response长度字段和实际数据长度不一致,手机协议栈直接丢弃了,根本没有上抛到应用层。这种问题,不到HCI层是绝对定位不了的。

1.2 HCI log和Logcat的分工

很多初学者容易把Logcat和HCI log混为一谈。简单说,Logcat是Android系统层面的日志,记录App调用、系统服务状态、各种print输出;HCI log则是蓝牙控制器(Controller)和蓝牙协议栈(Host)之间所有HCI报文的全量记录。

用生活类比,Logcat好比公司前台登记访客的记录,写着“谁来了、几点走的”;HCI log则是大厦监控视频,每一帧画面都在,谁按的电梯、在哪个楼层停留、门禁为什么没开,全部有据可查。

所以当问题发生在系统上层,比如权限没开、服务没绑定,Logcat基本够用;但当问题涉及连接建立、断开、配对、加密、断连重连这些协议栈层面的交互时,必须上HCI log。

1.3 什么场景必须依赖HCI log

根据我的经验,这几类问题在小米手机上排查时,HCI log几乎是唯一靠谱的突破口:

  • 连接时好时坏,回连成功率不稳定
  • 配对反复失败,或配对成功后重启又失效
  • 连接后不久自动断开,间隔没有明显规律
  • GATT读写超时,或偶尔返回133、257这类系统错误码
  • 多设备同时连接时的互相干扰问题
  • 不同品牌手机行为不一致,需要对比协议栈层面的差异

一句话:只要问题涉及“蓝牙链路本身”,先抓HCI log,别在Logcat里瞎猜。

2. 小米手机抓取HCI log:从开关到拿到文件

2.1 准备工作:开发者模式与日志开关

在小米手机上抓HCI log,第一步是先确保开发者选项已经打开。路径是“设置 → 我的设备 → 全部参数与信息 → 连续点击OS版本号(或MIUI版本号)7次”,直到提示已进入开发者模式。

接着进“设置 → 更多设置 → 开发者选项”,里面有几个开关容易让人晕,我逐个说清楚:

  • “日志抓取”或“日志分析”总开关:部分机型需要先打开这个,下面才会显示更多日志细分项
  • “蓝牙HCI日志”:这是核心开关,打开后系统会把HCI报文存到btsnoop文件
  • “蓝牙调试日志”:一些机型上是这个叫法,作用一致

需要注意的是,开启蓝牙HCI日志后,很多小米机型会先关闭蓝牙,需要在通知栏重新打开蓝牙。这不是故障,是在重置蓝牙芯片的日志记录上下文,保证后续新开的连接都会被完整记录下来。

2.2 开启HCI日志的两种方式

我平时常用的方式有两种,按场景选。

第一种是纯界面操作,适合临时抓一次日志。设置 → 开发者选项 → 打开“蓝牙HCI日志”,重新打开蓝牙,复现问题,然后到文件管理器里把日志导出来。日志默认在“内部存储 / MIUI / log / bluetooth /”目录下,文件名一般是btsnoop_hci.log或带时间戳的hci_xxx文件。

第二种是配合adb命令,适合需要长时间抓取或者自动化复现的场景。先把开发者选项里的USB调试打开,连接电脑后执行:

# 查看当前蓝牙HCI日志开关状态 adb shell settings get global bluetooth_hci_log # 打开HCI日志(部分平台支持) adb shell settings put global bluetooth_hci_log 1 # 重启蓝牙服务让其生效 adb shell service call bluetooth_manager 6

这里多说一句,service call bluetooth_manager 6这个写法在不同Android版本上可能不稳定,我一般直接在手机上手动关开一下蓝牙更省事。日志开关打开后,为了保险起见,我习惯再用命令确认一下配置有没有写进去。

导出日志时,我推荐用adb pull,比在手机上翻文件管理器可靠得多:

# 导出整个蓝牙日志目录 adb pull /sdcard/MIUI/log/bluetooth/ D:/bt_log/ # 如果目录不存在,试着找一下常见路径 adb shell ls /sdcard/MIUI/log/ adb shell ls /sdcard/Android/data/com.android.bluetooth/files/

部分小米机型权限收紧后,/sdcard/MIUI/log不一定直接可见,这时候可以先执行一次adb bugreport,把系统诊断包拉到电脑上,里面通常也会附带蓝牙HCI日志,只是路径更深,稍麻烦一点。

2.3 5分钟流程怎么安排最合理

很多人说的5分钟搞定,其实不是打开开关那一下,而是一条完整的操作链路。我自己的固定节奏是这样:

头1分钟:开启开发者选项里的蓝牙HCI日志,关闭再打开蓝牙,确认状态正常。

中间2分钟:按照预先想好的测试步骤“干净地”复现一次问题。注意不要在这个阶段做其他无关操作,比如切Wi-Fi、刷抖音,这些都有可能在日志里引入大量干扰帧。

最后2分钟:用adb pull或文件管理器把日志文件导出,拉到电脑上用Wireshark打开。整个过程看起来简单,但大部分人在第一步就栽了——没复现就切走了,导出来的日志里什么都没有。

另外,如果问题不是必现的,我建议把“蓝牙HCI日志”长期开着,日志文件会滚动覆盖,出问题时再导出,比临时打开等着复现有效得多。

3. 用Wireshark解析HCI log的实战细节

3.1 工具选择:为什么首选Wireshark

市面上能看btsnoop的工具有不少,Frontline、Ellisys这些商业方案功能很强,但价格不菲且上手成本高。对大部分Android开发者来说,Wireshark完全够用,而且免费、跨平台、对btsnoop格式支持得非常好。

小米手机抓出来的日志一般就是标准btsnoop格式,Wireshark可以直接打开。如果遇到文件后缀是.log但Wireshark识别不出来的情况,可以尝试在打开文件时手动选择“Bluetooth Snoop Capture”作为解析格式,多数时候能救回来。

3.2 打开文件与过滤器的使用

用Wireshark打开HCI log后,界面会直接按时间顺序显示所有蓝牙HCI报文。不熟悉的人第一眼会觉得很乱,因为里面全是HCI_Command、HCI_Event、HCI_ACL这种字样。

我的建议是先用过滤栏把协议类别分开。最常用的几个过滤器:

btl2cap 只看L2CAP层,适合分析连接建立和通道管理 btgatt 只看GATT层,适合分析服务发现和读写请求 bthci_evt 只看HCI事件,适合快速找连接、断开、配对状态变化 bthci_cmd 只看HCI命令,适合确认主机到底下发了什么指令 btsmp 只看安全管理层,适合定位配对和加密问题

举个例子,如果怀疑是断连问题,直接在过滤栏输入bthci_evt && bthci_evt.code == 0x05,就能把所有Disconnection Complete事件筛出来,每条记录都会带Reason字段,那个数字就是断连原因码。

如果是GATT读写问题,建议用btgatt过滤,然后在“电话”右侧的协议详情里双击某条GATT请求,右键选择“Follow”可以追踪同一条ATT通道上的完整交互序列,很快就能看出是请求没发出去还是响应没回来。

3.3 三种典型故障在log里的样子

解析这块光讲理论容易飘,我拿三个真实遇到过的场景演示一下特征长什么样。

场景一是“扫描不到设备”。在HCI日志里,主机会周期性地下发LE Set Scan Parameters和LE Set Scan Enable命令,事件里会有LE Advertising Report。如果扫描命令正常下发但完全没有Advertising Report,说明手机射频或天线附近干扰严重,或者设备压根没在广播;如果连Scan Enable命令都没有,那问题在协议栈上层,跟设备端无关。

场景二是“配对失败”。配对过程里一定会出现SMP层的Command和Response,如果看到Pairing Failed,后面带一个Reason,例如0x05表示不支持的配对方式,0x08表示密钥或确认值不匹配,排查方向就非常明确了。我曾遇到过一个设备,HCI日志里反复出现Security Request后主机直接返回Negative Reply,一看就是设备端bonding信息没存住,每次都当成新配对来处理。

场景三是“连接建立后立刻断开”。一般会看到三条连续的记录:Connection Complete(成功)、随后不久出现Disconnection Complete、Reason指向0x08或0x13。0x08代表连接超时,常见于设备端没有及时回应握手包;0x13代表对端主动断开,常见于设备端业务逻辑主动踢人。这一步定位后,再联合设备端日志一起看,基本都能收敛。

4. 从HCI log反推根因:错误码与交互链

4.1 错误码速查与责任划分

HCI log最有价值的地方在于断连原因码不会说谎。我把开发中高频遇到的错误码整理成了速查表,解析时对照着看非常方便:

错误码含义一般指向
0x08Connection Timeout对端没有及时响应,链路超时
0x13Remote User Terminated Connection对端主动断开
0x16Connection Terminated by Local Host手机本地主动断开
0x0DConnection Rejected due to Limited Resources设备资源不足,常见于设备端连接数满
0x0EConnection Rejected due to Security Reasons安全机制拒绝连接
0x05PIN or Key Missing配对密钥丢失或未保存
0x3EConnection Failed to be Established连接建立失败,物理层或对端无响应

需要说明的是,不同蓝牙芯片厂商在错误码映射上可能存在细微差异,速查表只作为参考方向,拿到具体日志后还是要去对照相应IC的文档确认一次。

判断责任方的逻辑其实很简单:先看谁发的Disconnection Complete,本地芯片给的事件Reason代表手机协议栈或驱动那边的判断,远端断的一般会通过Link Loss或对端主动断开的Reason传回来。再结合时间点前后有没有对端发来的数据,基本就能确定是手机的问题、协议栈的问题还是设备端的问题。

4.2 时间轴对齐与GATT交互追踪

抓HCI log之后只做单看,往往还不够。我习惯把HCI log和Logcat按时间戳对齐来看,特别适合那种“应用层看起来卡了很久,但协议栈层面实际已经走完好几轮交互”的场景。

做法是先在HCI log里找到问题现象对应的时间点,记下时间戳,然后回到Logcat里把同一时间段的日志筛出来,看应用层收到回调的时机。如果HCI log显示数据早就到了,但Logcat回调一直没有触发,那就是数据在内部分发环节丢了;如果HCI log里显示一直在重传或等待ACK,那就要去查空包和干扰问题。

追踪GATT交互时,Wireshark的“电话”追踪功能很好用。两条GATT消息之间的时间间隔非常直观,只要间隔超过预期值几百毫秒甚至几秒,基本就是中间有重传或退避逻辑在作祟。

4.3 业务问题定位思路

除了协议栈层面的问题,HCI log还能帮我们反向验证业务层逻辑是否正确。比如低功耗蓝牙设备常见的电量上报、步数同步、固件升级这类业务,本质上都是GATT上的一次次读写和通知。

排查时先把台账拉出来:连接是哪个设备、服务发现是否完成、MTU协商到了多少、每次Write和Notification的字节数是否符合预期。这些信息在HCI log里全部都有。

我之前遇到一个OTA升级到一半总失败的问题,就是通过HCI log发现每次大包传输时,设备端在收到Write Request后都没有回Write Response,直到主机端触发了超时才中止。看log的时候那个等待时间序列特别明显,几乎是一帧一个hole。后来定位到是设备端Flash写入耗时过长,完全依赖主机的流控保护,手机蓝牙协议栈只要稍调一下连接参数就扛不住了。这种问题,不抓HCI log,单看应用层回调是真的看不出来。

5. 小米手机HCI log抓取的常见问题排查实录

5.1 开关找不到或日志抓不到

这是我被问过最多的问题,没有之一。在小米手机上,开发者选项里如果没有“蓝牙HCI日志”这个选项,先不要急着怪系统,大概率是日志抓取总开关没有打开。先到开发者选项里找到“日志抓取”或“日志分析”,把它打开,有些网上放出的教程会管它叫“日志捕获”,小米澎湃OS上的入口名称可能还会变,多留意一下。

如果总开关已经打开还是看不到蓝牙日志选项,可以试试插上USB线连电脑,开启USB调试后输入:

adb shell settings put global ble_log_on 1 adb shell settings put global bt_hci_log_on 1

然后重新开关蓝牙。部分开发版系统支持这两个全局配置项,稳定版不一定全有,但值得一试。

还有一种情况是日志开关都开了,文件也生成了,但内容只有几百字节。这个大概率是打开日志开关之后没有重新开关蓝牙,导致蓝牙芯片的日志功能没有实际加入新的会话。处理方法就是先关掉蓝牙,再打开蓝牙,然后重新连接设备复现问题。

5.2 文件异常与解析失败

Wireshark打不开日志文件,先别急着换工具。btsnoop文件有个固定文件头,如果文件被截断或者中间有坏块,Wireshark就会报错。这时可以用十六进制工具打开看看文件头是不是62 74 73 6E 6F 6F 70,也就是字符btsnoop,如果是,基本没救不了;如果不是,有可能文件被系统转换过格式或者只抓到了部分包,可以试试用text2pcap工具把纯文本的日志转换成pcap格式再打开。

另外,在小米手机上如果用文件管理器直接查看日志文件,有可能会看到两个相似文件,一个带后缀.cfa或.tmp,一个才是当前可用的。优先导出不带后缀修改时间最新的那个。

文本模式下的HCI log解析是另一个坑。小米部分机型导出的日志不是标准btsnoop二进制,而是类似HCI RX、HCI TX开头的人类可读文本。这时候直接拖进Wireshark是打不开的,可以用text2pcap转一下,或者干脆换用Android Studio自带的Device File Explorer从/data/misc/bluetooth/logs/目录导出原始文件。

5.3 容易混淆的细节与经验技巧

最后分享几个我在实际过程中踩过坑才总结出来的经验,每一条都对应过一次真实的加班:

第一,抓HCI log时尽量把手机上的其他蓝牙设备断开。小米手机经常会同时连着耳机、手表、手环这些设备,这些设备产生的周期性连接和断连信息会把日志搞得很杂,分析时很难聚焦到目标设备上。如果条件允许,清空其他配对记录再抓,否则后期过滤时很痛苦。

第二,HCI log里没有“应用名”这个概念,只有蓝牙设备地址。想在日志里定位到自己的设备,先在Logcat里找到目标设备地址,再在Wireshark里用设备地址过滤,而不是盯着日志翻。

第三,抓日志前关闭蓝牙后重开,不只是为了让功能生效,更是为了拿到一条“干净的连接时间线”。从扫描到连接、服务发现、MTU协商再到业务发送,完整走一遍,后面任何一环出问题都能顺着时间线往前找。

第四,动态调整连接参数的问题。如果问题表现为偶尔卡顿、时延忽高忽低,可以重点看HCI log里LE Connection Update Complete事件前后的连接间隔和从机延迟参数。小米手机在系统负载变化时会调整蓝牙参数,这在某些芯片上是正常行为,但如果你做的是对时延敏感的音频或运动数据设备,就得在设备端做兼容。

6. 最后再分享一个小技巧:日志自动化保存

如果你的日常工作需要经常复现蓝牙问题,我强烈建议在小米手机上做一次“半自动化”的日志习惯:把“蓝牙HCI日志”长期开启,手机存储充裕的情况下它会滚动覆盖,问题出现时再快速导出,问题没出现时也不用管它。

导出时除了HCI log,最好同时导出adb bugreport的压缩包,里面有系统版本、蓝牙协议栈版本、已配对设备列表等信息。排查问题时这些资料往往是HCI log之外最有力的佐证。

我自己还会在电脑上建立一个按日期命名的日志归档目录,每份日志都附一段文字描述,记下现象、操作步骤、设备型号和系统版本。坚持一段时间后,你会发现很多“偶发问题”其实是同类原因反复出现,只是之前从没把日志留存下来做对比分析。

小米手机上抓HCI log这件事,难度真的不大,关键是要养成“先抓日志再分析”的习惯。协议栈底下的报文不会说谎,数据在哪、卡在哪、谁拒绝了谁,全部一清二楚。希望这篇内容能帮你少走一些弯路。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 16:44:21

ESP-IDF离线安装Python依赖:跨平台兼容性解决方案

1. 项目概述:为什么离线装Python依赖成了ESP-IDF开发者的“第一道鬼门关” 你刚下载完ESP-IDF官方安装包,解压、配置环境变量、打开VSCode,满怀期待点下“ESP-IDF: Configure ESP-IDF extension”——结果卡在“Installing Python packages……

作者头像 李华
网站建设 2026/9/28 16:43:55

AI看不见的劳动:多模态数据采集与过程标注实战

1. 一个被忽视的真相:AI眼中的世界缺了一块前阵子跟几个做数据标注和模型训练的朋友吃饭,席间有人抛出一个问题:现在的大模型能写代码、能画图、能分析财报,但它知不知道你楼下那家早餐店的包子是怎么从面粉变成成品的&#xff1f…

作者头像 李华
网站建设 2026/9/28 16:43:46

AI辅助学术写作实战:人机协作流程、幻觉规避与工具选型指南

1. 为什么我想聊聊用AI写论文这件事去年秋天,我接了一个综述章节的撰写任务,截稿日期给得很紧,手头同时压着三个实验的数据分析。那段时间我几乎每天凌晨两点还在对着屏幕改段落,改到后面自己都不知道在写什么。后来一个做计算化学…

作者头像 李华
网站建设 2026/9/28 16:43:33

箱体目标检测数据集实战:从压缩包到YOLO训练全流程

简介:箱体目标检测数据集面向物流仓储、工业制造、机器人抓取及运输零售等场景的算法开发者与研究人员,提供可直接用于YOLO系列模型训练的标注数据,帮助快速搭建箱体识别与跟踪应用。资源包共1568个文件,包含783张jpg图像、783个同…

作者头像 李华
网站建设 2026/9/28 16:43:27

VS Code 插件推荐(第一期):用 TaoToken 统一 Key 打通 AI 编程工具链

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 16:43:09

Kaggle共享单车需求预测实战:神经网络回归与特征工程避坑指南

简介:这份资源是面向计算机相关专业学生与初学者的Kaggle入门实战项目,围绕城市自行车共享系统的使用状况分析与预测展开,适合用作课程设计、毕业设计或初期项目立项的参考案例。压缩包共8个文件,约823KB,包含3个csv数…

作者头像 李华