Android Bluetooth HCI log 详解
0. 引子
对于蓝牙开发者来说,通过HCI log可以帮助我们更好地分析问题,理解蓝牙协议,就好像网络开发一定要会使用Wireshark分析网络协议一样。
本篇主要介绍HCI log的作用、如何抓取一份HCI log,并结合一个实际的例子来说明如何分析HCI log。
1. HCI log 介绍
1.1 HCI log 作用
HCI log是用来分析蓝牙设备之间的交互行为是否符合预期,是否符合蓝牙规范。在日常的开发中,通常使用HCI log来做这样几件事:
分析Bug:蓝牙打开后搜索不到设备,或者搜索到的设备没有名称只有蓝牙地址;Android手机不能向苹果手机传输文件 ... ...
需求分析:手机需要适配一款蓝牙自拍杆来控制拍照,通过HCI log可以观察竞品在实现这个功能时,使用的是什么Bluetooth Profile?只要知道了使用的Bluetooth Profile,我们就有了实现这个功能的思路。
蓝牙协议学习:通过HCI log辅助学习蓝牙协议,就好像学习TCP/IP时,通过wireshark抓包来学习TCP协议
1.2 蓝牙核心系统架构
说了这么多HCI log的用处,要想更好地理解HCI log,我们需要先来看下HCI在整个蓝牙核心系统架构中所处的位置。为了理解起来更简单,我这边将蓝牙核心系统架构抽象为3层:
User Application(Host):User Application即应用层,也被称为Host,我们调用Bluetooth API就属于应用层,例如,BluetoothAdapter中提供的接口。
HCI (Host controller Interface):上层在调用蓝牙API时,不会直接操作蓝牙底层(Controller)相关接口,而是通过HCI下发对应操作的Command给Controller,然后底层执行命令后返回执行结果,即Controller发送Event给HCI,HCI再通知给应用层,HCI起到了一个中间层的作用。
Controller:Controller是在最底层,可以理解为我们手机上的蓝牙芯片。
抽象后的蓝牙架构
完整的蓝牙核心系统架构比较复杂,这里我们就不再深入,感兴趣的同学可以参考蓝牙规范Core_v4.2.pdf,里面有详细的定义和介绍。我们后面在分析HCI log时,也会参考这个规范中定义的内容。
完整的蓝牙架构
2. 如何抓取HCI log
在开发者选项中打开启用蓝牙HCI信息收集日志开关,Android系统就开始自动地收集HCI log并保存到手机上。
启用蓝牙HCI信息收集日志
不同的平台存放HCI log的路径会不一样,MTK存放HCI log的路径为/sdcard/mtklog/btlog/btsnoop_hci.log,高通的存放路径为/sdcard/btsnoop_hci.log
MTK:/ $ ls -l /sdcard/mtklog/btlog/
total 816
-rw-rw---- 1 root sdcard_rw 412258 2016-02-28 00:39 btsnoop_hci.logshell@Qualcomm:/ $ ls -l /sdcard/btsnoop_hci.log
-rw-rw---- root sdcard_rw 12744 2017-06-16 15:43 btsnoop_hci.log
如果上面提到的路径下都没有HCI log,我们还可以通过手机上的蓝牙配置文件bt_stack.conf来查看路径,bt_stack.conf位于/etc/bluetooth/路径下。HCI log路径通过BtSnoopFileName=/sdcard/btsnoop_hci.log来进行设置的。
HCI log在手机上的路径
而bt_stack.conf是通过Android源码中的/system/bt/conf/bt_stack.conf来配置的。
// /system/bt/conf/bt_stack.conf
# BtSnoop log output file
BtSnoopFileName=/sdcard/btsnoop_hci.log
将抓取到的HCI log pull出来,直接用记事本打开,看到的都是乱码。我们还需要一个HCI log分析工具:Frontline ComProbe Protocol Analysis System
C:\Windows\System32>adb pull /sdcard/mtklog/btlog/btsnoop_hci.log C:\Users\admin\Desktop\hci
501 KB/s (4880 bytes in 0.009s)
3. HCI log分析工具
Frontline ComProbe Protocol Analysis System是Frontline提供的一款蓝牙协议log分析工具,Frontine这家公司主要是做抓取蓝牙Air sniff log设备的,我们后面再来说下什么是Air sniff log。购买他们的抓包工具就会附带log分析工具,也可以在Frontine官网上下载,下载的时候需要填一些信息,觉得麻烦的同学可以去其他非官网途径进行下载。
安装完成后,在开始菜单中找到Frontline ComProbe Protocol Analysis System,使用Capture File Viewer可以打开HCI log
ComProbe Protocol Analysis System
Step 1. 首先,选择要打开的HCI log,并选择log类型为BtSnoop Files,即以*.log结尾的文件。
还有一种方式是将btsnoop_hci.log的后缀修改为btsnoop_hci.cfa,就可以直接用Capture File Viewer打开。
Step 1. 打开的HCI log
选择log类型
Step 2. 打开log文件后,选择Frame Display就可以看到我们抓取的HCI log了
Step 2 . 选择Frame Display
Frame Display主界面
Step 3. Frame Display窗口中有很多Tab,将协议栈中各类协议分类显示,例如:HCI相关的log放在HCI的Tab中,Hands-Free(HFP)属于应用层的Bluetooth Profile,和HFP相关操作的log都放在Hands-Free这个Tab中。
Frame Display
- Air sniff log
Android设备上抓取的HCI log只能分析Host和Control之间的问题,当Host和Control之间交互是正常的,那就可能就是传输的过程中(Air Interface)出了问题,此时就需要分析Air sniff log。Air sniff log能够抓取的两个蓝牙设备在数据传输过程中的空中包,抓取Air sniff log需要专门的设备。
Air sniff log
4. HCI log 案例 - 蓝牙扫描设备过程分析
应用层在调用startDiscovery()进行设备扫描时,Host会通过HCI发送一个Inquiry HCI Command给Controller。接下来我们会通过分析HCI log,来学习Inquiry 的流程。在分析HCI log前,我们先来学习下HCI Command数据包的结构。
4.1 HCI Command 数据包结构
HCI Command数据包结构定义在蓝牙核心协议规范Core_v4.2.pdf中。
HCI Command数据包格式如下,开头的Opcode是区分不同类型的命令的唯一标识,Opcode由OpCode Group Field (OGF) 和 OpCode Command Field (OCF)组成。根据OGF的值,可以将HCI commands进行分类。OpCode 的计算公式为:** OpCode = OGF << 6 + OCF 。有了OpCode计算的方式,我们就可以通过OpCode过滤**HCI log里面的指定类型的HCI Command。
HCI Command Packet
OpCode计算方法
4.2 过滤Inquiry Command
Inquiry Command是Link Control command类型的command,通过查询Bluetooth Core Specification的中Vol 2->Part E->7.1 LINK CONTROL COMMANDS小节,可知Link Control command的OCF值为0x0001。
Bluetooth Core Specification目录
For the Link Control commands, the OGF is defined as 0x01
因此,Inquiry Command的Opcode为 0x0001 << 6 + 0x01 = 0x0401 ,通过0x0401就确定某条command为Inquiry Command,该命令的名称为HCI_Inquiry
Inquiry Command
ComProbe Protocol Analysis System支持过滤功能,通过设置filter可以过滤出Opcode为0x0401的log,设置方法如下图:
过滤HCI_Inquiry
4.3 扫描过程分析
1. 发送Inquiry请求
- Host发送HCI_Inquiry Command
应用层要进行蓝牙设备扫描啦,Host先发一条HCI_Inquiry的Command通知Controller
Host: HCI_Inquiry
- Controller回复HCI Event
Controller在收到HCI_Inquiry这条Command后,会回复一条Command Status的HCI Event,来表示Controller执行HCI_Inquiry后的状态,即Status:Success。仔细观察可以发现这两条HCI log的Frame标号是挨着的,HCI_Inquiry的帧号是196,Command Status的帧号是197。
Controller:Command_status、
2. 扫描结果
扫描完成后,Controller会发送Event:HCI Extended Inquiry Result。以列表中搜索到的Jabra Classic v0.5.3为例,它的HCI Extended Inquiry Result数据包中会包含它的设备名称、它所支持的Service的UUID,和设备类型:Wearable Headset device,因此,Jabra Classic v0.5.3的Icon是一个耳机的图标。
扫描结果
Jabra Classic v0.5.3的HCI Extended Inquiry Result
5. 参考
- Core_v4.2.pdf
- HCI Layer Tutorial
作者:伤口不该结疤
链接:https://www.jianshu.com/p/73f7366161d1
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Android Bluetooth HCI log 详解相关推荐
- android hid 编程,Android Bluetooth HID完成详解,androidhid
Android Bluetooth HID完成详解,androidhid Android Bluetooth HID落实详解 Android 关于蓝牙的局部运用的是BlueZ协定栈.然而直到眼前2.3 ...
- Android Bluetooth HID实现详解
Android Bluetooth HID实现详解 Android 关于蓝牙的部分使用的是BlueZ协议栈.但是直到目前2.3.3都没有扩展HID的profile,只是实现了最基本的Handset和d ...
- Android 蓝牙BLE开发详解
Android 蓝牙BLE开发详解 由于年初接手了个有关蓝牙BLE的项目,开始了对蓝牙ble的学习,经过长时间的慢慢学习(学得太慢,太拖了),终于了解了该怎么写蓝牙BLE,现在就给大家分享一下. 一. ...
- android jar 包 意见反馈功能,android重点jar包详解.docx
android重点jar包详解 深入理解View(一):从setContentView谈起 我们都知道?MVC,在Android中,这个?V?即指View,那我们今天就来探探View的究竟.在onCr ...
- Android应用坐标系统全面详解
Android应用坐标系统全面详解 原文链接:CSDN@工匠若水,http://blog.csdn.net/yanbober/article/details/50419117 1. 背景 去年有很多人 ...
- android ------- 开发者的 RxJava 详解
在正文开始之前的最后,放上 GitHub 链接和引入依赖的 gradle 代码: Github: https://github.com/ReactiveX/RxJava https://githu ...
- 宏锦软件 Android 的 ListView 使用详解
宏锦软件爱好者在开发Android软件时,对ListView的使用有点陌生,于是翻了许多资料,这里给大家一份比较好的教程,希望有用. 在android开发中ListView是比较常用的组件,它以 ...
- Android 系统(199)---Android事件分发机制详解
Android事件分发机制详解 前言 Android事件分发机制是Android开发者必须了解的基础 网上有大量关于Android事件分发机制的文章,但存在一些问题:内容不全.思路不清晰.无源码分析. ...
- Android多点触控详解
本文转载自GcsSloop的 安卓自定义View进阶-多点触控详解 的文章 Android 多点触控详解,在前面的几篇文章中我们大致了解了 Android 中的事件处理流程和一些简单的处理方案,本次带 ...
- Android 吸入动画效果详解(仿mac退出效果)
转载自:http://m.blog.csdn.net/blog/leehong2005/9127095 [转]Android 吸入动画效果详解 1,背景 吸入(Inhale)效果,最初我是在iOS上面 ...
最新文章
- Spring Boot 关于 @EnableConfigurationProperties 注解 —— 使用 @ConfigurationProperties 注解的类生效。
- Nginx虚拟机主机根据不同的域名使用不同的root路径
- 服务器能进安全模式进不去系统,远程服务器怎么进安全模式
- 使用java实现面向对象编程试题答案,面试题+笔记+项目实战
- python使用matplotlib画图,绘制三维、二维曲线。设置字体大小以及坐标系间距等
- Geek爱旅行 - 穿越时间的旅行
- 图卷积神经网络(part1)--卷积概述
- NSInteger,NSUInteger,NSNumber
- spring注解( @Autowired、@Qualifier、@Resource、@PostConstruct、@PreDestroy、 @Component、@Scope)-描述的比较清楚
- 蓝牙设置种常用的Intent
- 201507之佛山移动实习
- python中使用什么来实现异常捕捉_python 异常捕捉
- 《Effective Python 2nd》 读书笔记——函数
- 基于大数据的软件智能化开发方法与环境
- STM32+DWM1000开发uwb测距系列教程之三:使用官方例程实现p2p双向 twr测距
- 解决errno 256报错_wuli大世界_新浪博客
- 被使用次数最多的22个Python外部模块
- 使用机器学习进行语言翻译:神经网络和seq2seq为何效果非凡?
- 手机后端开发用php,【后端开发】php如何获取手机型号
- C++课程设计指导书