adb概览及协议参考

本文详细介绍了Android Debug Bridge (ADB) 的工作原理和技术细节,包括其组成部分、服务功能及协议规范等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:https://github.com/android/platform_system_core/blob/master/adb/OVERVIEW.TXT)

Implementation notes regarding ADB.

ADB实现注解

1. General Overview:

1概要

The Android Debug Bridge (ADB) is used to:

ADB在以下情况下使用:

  • keep track of all Android devices and emulators instances connected to or running on a given host developer machine
  • 对所有连接到开发机器上的android真机和模拟器进行跟踪管理
  • implement various control commands (e.g. “adb shell”, “adb pull”, etc..) for the benefit of clients (command-line users, or helper programs like DDMS). These commands are what is called a ‘service’ in ADB.
  • 实现了大量的控制命令(比如: “adb shell”, “adb pull”,等等)来方便用户使用(包括命令行用户和助手类程序如ddms),这些命令往往被我们叫做adb中的一个‘服务’。

As a whole, everything works through the following components:

总而言之,所有的事情都是围绕着以下这几个模块进行的:

1.1 The ADB server

1.1 ADB服务器

This is a background process that runs on the host machine. Its purpose if to sense the USB ports to know when devices are attached/removed,as well as when emulator instances start/stop.

这是在主机设备(PC/开发机器)上运行的一个后台进程。它的目的是嗅探何时有设备在主机的usb口上挂载/移除,以及模拟器何时开启/关闭。

It thus maintains a list of “connected devices” and assigns a ‘state’ to each one of them: OFFLINE, BOOTLOADER, RECOVERY or ONLINE (more on this below).

因此它会维护着一个”已连接设备”列表,并且为每个设备指定一个‘状态’:OFFLINE, BOOTLOADER, RECOVERY 或 ONLINE (下文会详述)。

The ADB server is really one giant multiplexing loop whose purpose is to orchestrate the exchange of data (packets, really) between clients, services and devices.

ADB服务器确实可以称为是一个强大的多路路由,它的目的就是去协调组织客户端,各种服务和设备之间的数据交换(数据包,真实数据)。

1.2 The ADB daemon (adbd)

1.2 ADB守护进程(adbd)

The ‘adbd’ program runs as a background process within an Android device or emulated system. Its purpose is to connect to the ADB server (through USB for devices, through TCP for emulators) and provide a few services for clients that run on the host.

adbd是一个在android真实机器或者模拟器上运行的后台伺服程序。它的目的是为了连接pc端的adb服务器(真实机器用usb,模拟器用tcp协议(译者注:其实真实机器也可以用tcp来连接,这篇文章没有及时更新过来))并且为在主机pc上运行的adb客户端应用提供一些服务。

The ADB server considers that a device is ONLINE when it has successfully connected to the adbd program within it. Otherwise, the device is OFFLINE, meaning that the ADB server detected a new device/emulator, but could not connect to the adbd daemon.

当adb服务器成功连接上android机器上的adbd伺服程序的时候就会认为该设备已经online,否者就会认为该设备是offline,指的是adb服务器有检测到一个新的设备连接上来,但是却没有成功连接上该设备的的adbd。

the BOOTLOADER and RECOVERY states correspond to alternate states of devices when they are in the bootloader or recovery mode.

BOOTLOADER和RECOVERY着两个状态分别代表android设备处于bootloader或者recovery模式下的对应的可选状态。

 

1.3. The ADB command-line client

1.3 ADB命令行客户端

The ‘adb’ command-line program is used to run adb commands from a shell or a script. It first tries to locate the ADB server on the host machine, and will start one automatically if none is found.

adb命令行客户端是给shell或者脚本调用来跑各种adb命令的。它首先会尝试找到主机pc上运行的adb服务器,如果没有找到的话就会自动启动一个adb服务器。

then, the client sends its service requests to the ADB server. It doesn’t need to know.

然后该adb命令行客户端会往adb服务器发送服务请求,而这些对于adb服务器来说是无需知道的。

Currently, a single ‘adb’ binary is used for both the server and client. this makes distribution and starting the server easier.
就当前来说,adb服务器和adb客户端使用的其实是同一个二进制文件,这样使得发布和启动服务器会更方便。

1.4. Services

1.4. 服务

There are essentially two kinds of services that a client can talk to.

本质上一个adb命令行客户端会和两类服务进行通信。

Host Services: these services run within the ADB Server and thus do not need to communicate with a device at all. A typical example is “adb devices” which is used to return the list of currently known devices and their state. They are a few couple other services though.

主机服务:这些服务是在adb服务器自身内部运行的所以根本不需要和任何的android设备进行交互。一个典型的命令就是列出当前连接的所有android设备和状态的命令“adb devices”。 当然还有一些其他的服务了。

命令 解释
host:version  
host:kill 停止server
host:devices  
host:track-devies  
host:emulator:<port>  
host:transport:<serial-number> 连接指定serial-number的设备或者模拟器
host:transport-usb 连接usb上的设备,如果usb上有不止一个设备,会失败。
host:transport-local 通过tcp方式连接模拟器,如果有多个模拟器在运行,会失败。
host:transport-any 连接usb设备或者模拟器都可以,但是如果有超过一个设备或模拟器,会失败。
host-serial:<serial-number>:<request>host-usb:<request>host-local:<request> 向指定的设备发送特定的请求。同样如果存在多个设备的冲突,会失败。
host:<request> 向当前连接的设备发送请求
<host-prefix>:get-serialno 获取设备的serial-number
<host-prefix>:get-state 获取设备状态
<host-prefix>:forward:<local>;<remote>  

 

Local Services: these services either run within the adbd daemon, or are started by it on the device. The ADB server is used to multiplex streams between the client and the service running in adbd. In this case its role is to initiate the connection, then of being a pass-through for the data.

本地服务:这类服务是在adbd这个守护进程自身内部运行的,或者是由它启动运行的。adb服务器会在客户端和这些adbd中运行的服务之间进行数据路由。在这种情况下adb服务器扮演着初始化各种连接以及数据路信使的角色。

命令 解释
shell:command arg1 arg2 … 在设备上执行命令行操作
shell: 参见commandline.c中的interactive_shell()
remount: 以读/写模式加载设备的文件系统
dev:<path> 为client打开设备上的特定路径,用于读写问题。有可能由于权限问题而失败。
tcp:<port> 尝试从设备连接本主机的某个tcp端口
tcp:<port>:<server-name> 尝试从设备连接特定主机名的某个tcp端口
local:<path> 尝试连接设备上的特定路径,路径是UNIX域名形式
localreserved:<path>localabstract:<path>localfilesystem:<path> 尝试连接设备上的特定路径。
log:<name> 打开设备上的特定日志文件,以便读取日志
framebuffer: 尝试获取framebuffer的快照。即涉笔的屏幕快照
dns:<server-name> 由serer执行来解析特定设备名
recover:<size> 更新设备的恢复镜像
jdwp:<pid> 连接特定VM进程上面的JDWP线程
track-jdwp  
sync: 同步设备和主机上的文件

(注:以上两表整理来自网友 arm-linux:http://www.cnblogs.com/armlinux/archive/2011/02/16/2396845.html)

 

2 Protocol details:

2 协议细节

2.1 Client <-> Server protocol:

2.1 客户端<—>服务器端

This details the protocol used between ADB clients and the ADB server itself. The ADB server listens on TCP:localhost:5037.

以下细节描述的是主机pc中adb客户端和adb服务器端通信用到的协议。adb服务器端会监听TCP:localhost:5037

A client sends a request using the following format:
客户端使用以下的协议格式发送请求:

  • 1. A 4-byte hexadecimal string giving the length of the payload
  • 1. 前面是一个4字节的十六进制用来指定请求命令的长度
  • 2. Followed by the payload itself.
  • 2. 紧跟着请求命令自身的内容

For example, to query the ADB server for its internal version number, the client will do the following:

比如,为了得到adb服务器的内部版本号,客户端会做以下动作:

  • 1. Connect to tcp:localhost:5037
  • 1. 连接到 tcp:localhost:5037
  • 2. Send the string “000Chost:version” to the corresponding socket
  • 2. 发送字串”000Chost:version”到对应套接字(译者注:十六进制000C就是十进制12,”host:version”刚好12个字节)

The ‘host:’ prefix is used to indicate that the request is addressed to the server itself (we will talk about other kinds of requests later). The content length is encoded in ASCII for easier debugging.

‘host’这个前缀是用来指定这个请求是发送给服务器自身的(我们晚点会谈下其他的请求类型),为了方便调试,请求内容长度是用ASCII编码的。

The server should answer a request with one of the following:

服务器端将会用以下的一种方式进行应答:

  • 1. For success, the 4-byte “OKAY” string
  • 1. 成功:应答一个4字节的”OKAY”字串
  • 2. For failure, the 4-byte “FAIL” string, followed by a 4-byte hex length, followed by a string giving the reason for failure.
  • 2.失败:应答一个4字节的”FAIL”字串,紧跟着一个4字节十六进制描述错误描述内容长度,然后是描述错误的内容字串。
  • 3. As a special exception, for ‘host:version’, a 4-byte hex string corresponding to the server’s internal version number
  • 3. 例外:’host:version’的返回将会是一个4字节字串代表着服务器的内部版本号。

Note that the connection is still alive after an OKAY, which allows the client to make other requests. But in certain cases, an OKAY will even change the state of the connection.

注意客户端和服务器端的连接在接收到OKAY的应答后将会继续保持,以便客户端继续其他请求。但在一些特定的情况下,OKAY应答会改变连接的状态。

For example, the case of the ‘host:transport:<serialnumber>’ request, where ‘<serialnumber>’ is used to identify a given device/emulator; after the “OKAY” answer, all further requests made by the client will go directly to the corresponding adbd daemon.

比如,以命令’host:transport:<serialnumber>‘请求为例(其中 '<serialnumber>’用来指定一个指定的设备/模拟器),收到’OKAY’应答后,客户端往后的所有请求都将会直接发送到对应的设备/模拟器的adbd守护进程。

The file SERVICES.TXT lists all services currently implemented by ADB.

文件SERVICES.TXT列出了adb当前已经实现的所有服务(译者注:大家请自行google)。

 

2.2. Transports:

An ADB transport models a connection between the ADB server and one device or emulator. There are currently two kinds of transports:

adb传输指的是adb服务器和一个设备/模拟器之间的连接模型。当前有以下两种传输模型:

  • USB transports, for physical devices through USB
  • USB传输:真实机器通过usb连接的情况下
  • Local transports, for emulators running on the host, connected to the server through TCP
  • 本地传输:本机上的模拟器通过tcp连接到adb服务器的情况下

In theory, it should be possible to write a local transport that proxies a connection between an ADB server and a device/emulator connected to/ running on another machine. This hasn’t been done yet though.

理论上说,我们可以编写一个本地运行的传输代理来处理adb服务器和连接/运行在其他主机pc上的设备/模拟器的连接,但这个还没有实现。

Each transport can carry one or more multiplexed streams between clients and the device/emulator they point to. The ADB server must handle unexpected transport disconnections (e.g. when a device is physically unplugged) properly.

每一种传输方式都可以承载多路客户端和其指定的设备/模拟器之间的数据流传输。adb服务器必须合理的处理传输断开等异常(比如:当一个设备从pc主机上拔掉的情况)

解释下 03-08 15:04:15.132513 4296 4420 D bt_shim_hci: [hci_layer.cc(203)] OnTransmitPacketCommandComplete: Received cmd complete for SNIFF_SUBRATING 03-08 15:04:15.132665 4296 4381 E bt_btu_hcif: btu_hcif.cc:1046 btu_hcif_hdl_command_complete: Command complete for opcode:0x811 should not be handled here 03-08 15:04:15.133179 1054 2232 D SpeechDriverNormal: sendMailbox(), msg_id: 0x2f51 03-08 15:04:15.133811 4296 4672 V bt_btif_hf: btif_hf.cc:1542 AtResponse: BTHF ok 03-08 15:04:15.133897 4296 4672 V bt_btif_hf: [btif_hf.cc(1555)] AtResponse: AtResponse: response_code= 1 is_atd_received: 0 error_code: 0 03-08 15:04:15.134083 4296 4672 D HeadsetStateMachine: handleMessage: X 03-08 15:04:15.134149 4296 4381 D bluetooth: bta_ag_main.cc:560 bta_ag_api_result: Audio gateway event for one client handle:1 scb:codec_updated=0, codec_fallback=0, nrec=0sco_codec=2, peer_codec=3, cvsd_settings=1, msbc_settings=0, lc3_settings=0, device=xx:xx:xx:xx:6f:8c 03-08 15:04:15.134184 4296 4381 D bluetooth: bta_ag_main.cc:786 bta_ag_sm_execute: Execute AG event handle:0x0001 bd_addr:xx:xx:xx:xx:6f:8c state:BTA_AG_OPEN_ST[0x02] event:BTA_AG_API_RESULT_EVT[0x0506] result:BTA_AG_UNAT_RES[0x14] 03-08 15:04:15.134203 4296 4381 D bta_ag_cmd: bta_ag_cmd.cc:1724 bta_ag_hfp_result: HFP connection result:result:BTA_AG_UNAT_RES 03-08 15:04:15.134222 4296 4381 V bt_port_api: port_api.cc:1066 PORT_WriteData: PORT_WriteData() max_len:6 03-08 15:04:15.134321 4296 4381 V bt_port_api: port_api.cc:1150 PORT_WriteData: PORT_WriteData 6 bytes 03-08 15:04:15.134336 4296 4381 V bt_port_api: port_api.cc:883 port_write: PORT_Write : Data is being sent
03-15
<think>嗯,用户现在需要我帮忙解析另一段日志。看起来他们可能是在处理蓝牙相关的问题,或者是在开发过程中遇到了蓝牙模块的调试问题。之前的对话中,用户已经询问过关于AT指令的日志分析,现在转向蓝牙日志,可能是在同一项目中遇到了不同的模块问题。 首先,我需要仔细查看用户提供的日志内容。这些日志条目包含了时间戳、进程ID、线程ID、日志级别(如D、E、V)、组件名称以及具体的日志信息。用户可能希望了解这些日志的含义,尤其是错误和调试信息,以定位问题所在。 用户提供的日志中有多个条目,涉及不同的蓝牙组件,比如bt_shim_hci、bt_btu_hcif、bt_btif_hf等。需要逐一分析每个条目的含义,并指出可能的问题点。例如,有错误日志提到“Command complete for opcode:0x811 should not be handled here”,这可能表明某个命令在不该处理的地方被处理,需要进一步检查协议或代码实现。 另外,用户可能关心日志中的错误码和状态码,比如BTA_AG_UNAT_RES,这些代码的具体含义需要参考蓝牙协议文档,但根据常见情况可以推测其可能代表某种未预期的响应或结果。同时,注意到有些日志涉及音频网关(Audio Gateway)事件,这可能与蓝牙耳机或免提设备相关,用户可能在测试语音功能时遇到问题。 在回答时,需要保持结构清晰,分模块解析,可能的问题点,以及调试建议。由于用户之前得到了关于AT指令的详细解析,这次应该同样提供类似的层次结构,帮助用户逐步理解每个日志条目的意义,并指导他们如何进行下一步的调试。 还要注意用户可能的深层需求:他们可能正在开发或维护一个涉及蓝牙功能的应用程序,遇到了连接稳定性、指令处理错误或音频相关问题。因此,除了解析日志,提供调试步骤和常见原因分析会更有帮助,比如建议检查协议兼容性、权限设置、硬件支持等。 最后,需要确认是否需要更多的上下文信息,比如设备型号、蓝牙协议版本或相关配置,以便更准确地定位问题。但根据现有信息,应尽可能给出合理的推测和解决方案。</think>以下是对蓝牙相关日志的逐条解析与技术分析,结合蓝牙协议栈模块与常见问题场景: --- ### **1. 日志结构概览** | 时间戳 | 进程ID | 线程ID | 日志级别 | 模块/组件 | 关键信息 | |--------|--------|--------|----------|------------|----------| | `03-08 15:04:15.132513` | 4296 | 4420 | D (Debug) | `bt_shim_hci` | HCI层命令完成事件(SNIFF_SUBRATING) | | `03-08 15:04:15.132665` | 4296 | 4381 | E (Error) | `bt_btu_hcif` | 命令`0x811`处理位置错误 | | `03-08 15:04:15.133179` | 1054 | 2232 | D (Debug) | `SpeechDriverNormal` | 语音驱动发送消息(ID `0x2f51`) | | `03-08 15:04:15.133811` | 4296 | 4672 | V (Verbose) | `bt_btif_hf` | 蓝牙免提协议(HFP)AT响应成功(`OK`) | | `03-08 15:04:15.134083` | 4296 | 4672 | D (Debug) | `HeadsetStateMachine` | 状态机处理完成 | | `03-08 15:04:15.134149` | 4296 | 4381 | D (Debug) | `bluetooth` | 音频网关事件(设备地址`xx:xx:xx:xx:6f:8c`) | --- ### **2. 关键日志解析** #### **(1) HCI层事件处理** ```log 03-08 15:04:15.132513 D bt_shim_hci: [hci_layer.cc(203)] OnTransmitPacketCommandComplete: Received cmd complete for SNIFF_SUBRATING ``` - **SNIFF_SUBRATING**:蓝牙低功耗模式(Sniff Subrating),用于优化连接间隔以降低功耗。 - **潜在问题**:若频繁触发此事件,可能因设备尝试省电导致连接不稳定。 --- #### **(2) 错误日志:命令处理异常** ```log 03-08 15:04:15.132665 E bt_btu_hcif: btu_hcif.cc:1046 ... Command complete for opcode:0x811 should not be handled here ``` - **Opcode `0x811`**:蓝牙协议栈内部命令编码,需查HCI规范(例如可能为`HCI_SNIFF_SUBRATING`)。 - **错误原因**:命令被错误路由到非目标模块(`bt_btu_hcif`非预期处理该命令)。 - **调试建议**: 1. 检查蓝牙协议栈版本兼容性。 2. 验证HCI层与上层模块的接口实现。 --- #### **(3) 蓝牙免提协议(HFP)交互** ```log 03-08 15:04:15.133811 V bt_btif_hf: AtResponse: BTHF ok 03-08 15:04:15.133897 V bt_btif_hf: AtResponse: response_code=1 ... error_code:0 ``` - **BTHF**:蓝牙免提配置文件(Hands-Free Profile)。 - **response_code=1**:表示`OK`响应(例如AT指令执行成功)。 - **error_code=0**:无错误。 --- #### **(4) 音频网关(AG)事件** ```log 03-08 15:04:15.134149 D bluetooth: bta_ag_main.cc:560 ... Audio gateway event ... sco_codec=2, peer_codec=3 ``` - **sco_codec=2**:设备使用的音频编码(例如`CVSD`)。 - **peer_codec=3**:对端设备支持的编码(例如`mSBC`)。 - **潜在冲突**:编码不匹配可能导致通话质量差或连接失败。 --- ### **3. 问题定位与调试建议** #### **可能问题** 1. **HCI命令路由错误**(Opcode `0x811`): - 协议栈版本不一致(如HCI层与控制器固件不兼容)。 - 多线程竞争导致命令被错误线程处理。 2. **音频编码协商失败**(sco_codec vs peer_codec): - 设备不支持对端编解码(如缺少`mSBC`支持)。 - 蓝牙芯片硬件限制(仅支持CVSD)。 --- #### **调试步骤** 1. **确认HCI命令定义**: - 查询蓝牙核心规范文档,明确`Opcode 0x811`的功能。 - 检查协议栈源码中`btu_hcif_hdl_command_complete`的逻辑。 2. **音频编码兼容性测试**: - 使用`AT+BAUDIO`指令强制指定编解码(需设备支持)。 - 抓取HCI日志(如使用Wireshark)分析SCO链路建立过程。 3. **稳定性验证**: - 监控`SNIFF_SUBRATING`事件频率,调整连接参数(如`HCI_Write_Connection_Accept_Timeout`)。 --- ### **4. 扩展知识:蓝牙协议栈分层** | 层级 | 模块示例 | 功能 | |------|----------|------| | **应用层** | `bt_btif_hf` | 实现配置文件(如HFP、A2DP) | | **主机层** | `bt_shim_hci` | HCI协议封装/解析 | | **控制器层** | 蓝牙芯片固件 | RF/基带处理 | --- 如需进一步分析,请提供以下信息: 1. 蓝牙芯片型号(如Broadcom/Qualcomm) 2. Android版本与蓝牙协议栈版本(`adb shell dumpsys bluetooth_manager`) 3. 完整HCI日志(使用`btmon`或第三方工具抓取)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值