当前位置: 首页 > news >正文

揭开Linux跨平台 adb调试原理神秘面纱

程序功能分析

核心功能

先从Android Debug Bridge (ADB) 的头文件开始了解:

#ifndef __ADB_H
#define __ADB_H
​
#include <limits.h>
​
#include "transport.h"  /* readx(), writex() */
​
#define MAX_PAYLOAD 4096  // 定义数据包最大载荷大小
​
// ADB协议命令定义(通过ASCII码的十六进制表示)
#define A_SYNC 0x434e5953  // 'SYNC' 的十六进制
#define A_CNXN 0x4e584e43  // 'CNXN' 的十六进制 - 连接命令
#define A_OPEN 0x4e45504f  // 'OPEN' 的十六进制 - 打开连接
#define A_OKAY 0x59414b4f  // 'OKAY' 的十六进制 - 确认响应
#define A_CLSE 0x45534c43  // 'CLSE' 的十六进制 - 关闭连接
#define A_WRTE 0x45545257  // 'WRTE' 的十六进制 - 写入数据
​
#define A_VERSION 0x01000000        // ADB协议版本
​
#define ADB_VERSION_MAJOR 1         // 用于帮助/版本信息的主版本号
#define ADB_VERSION_MINOR 0         // 用于帮助/版本信息的次版本号
​
#define ADB_SERVER_VERSION    29    // 当我们需要强制用户启动新的adb服务器时递增此值
​
// 前向声明各种结构体类型
typedef struct amessage amessage;
typedef struct apacket apacket;
typedef struct asocket asocket;
typedef struct alistener alistener;
typedef struct aservice aservice;
typedef struct atransport atransport;
typedef struct adisconnect  adisconnect;
typedef struct usb_handle usb_handle;
​
// ADB消息结构体定义
struct amessage {unsigned command;       /* 命令标识符常量 */unsigned arg0;          /* 第一个参数 */unsigned arg1;          /* 第二个参数 */unsigned data_length;   /* 载荷长度(允许为0) */unsigned data_check;    /* 数据载荷的校验和 */unsigned magic;         /* 命令 ^ 0xffffffff */
};
​
// ADB数据包结构体定义
struct apacket
{apacket *next;          // 指向下一个数据包的指针(用于链表)
​unsigned len;           // 数据长度unsigned char *ptr;     // 数据指针
​amessage msg;           // 消息头unsigned char data[MAX_PAYLOAD];  // 数据载荷缓冲区
};
​
/* asocket表示本地和远程实体之间连接的一端。
** 本地asocket绑定到文件描述符。
** 远程asocket绑定到协议引擎。
*/
struct asocket {/* 链式指针,用于asocket所在的本地/远程asocket列表*/asocket *next;asocket *prev;
​/* 此asocket的唯一标识符*/unsigned id;
​/* 标志:当socket的对端已关闭但数据包仍在排队等待传递时设置*/int    closing;
​/* 标志:当两端都关闭本地服务socket时退出adbd*/int    exit_on_close;
​/* 我们连接到的asocket*/asocket *peer;
​/* 对于本地asocket,fde用于将我们绑定到fd事件系统。** 对于远程asocket,这些字段不被使用。*/fdevent fde;            // 文件描述符事件int fd;                 // 文件描述符
​/* 等待写入的apacket队列*/apacket *pkt_first;     // 队列头apacket *pkt_last;      // 队列尾
​/* 当对端有数据给我们时调用enqueue。** 如果我们能接受更多数据应返回0,否则返回1。** 如果我们返回1,当我们再次准备好接收数据时必须调用peer->ready()。*/int (*enqueue)(asocket *s, apacket *pkt);
​/* 当对端准备好让我们再次通过enqueue发送数据时,由对端调用ready*/void (*ready)(asocket *s);
​/* 当对端消失时由对端调用close。** 一旦我们的close方法被调用,我们不允许再对对端进行任何调用。*/void (*close)(asocket *s);
​/* socket类型特定的额外数据 */void *extra;
​/* socket绑定到atransport */atransport *transport;
};
​
​
/* adisconnect结构体用于记录一个回调函数,
** 该回调函数将在传输断开时被调用(例如由用户断开)
** 这应该用于清理依赖于传输的对象
** (例如远程socket、监听器等)
*/
struct  adisconnect
{void        (*func)(void*  opaque, atransport*  t);  // 断开回调函数void*         opaque;          // 不透明数据指针adisconnect*  next;            // 链表下一个adisconnect*  prev;            // 链表上一个
};
​
​
/* 传输对象模型化到远程设备或模拟器的连接
** 每个连接的设备/模拟器有一个传输。
** "本地传输"通过TCP连接(用于模拟器),
** 而"USB传输"通过USB连接(用于真实设备)
**
** 注意kTransportHost并不真正对应一个真实的传输对象,
** 它是一个特殊值,用于指示客户端想要连接到ADB服务器本身实现的服务。
*/
typedef enum transport_type {kTransportUsb,      // USB传输类型kTransportLocal,    // 本地传输类型(TCP)kTransportAny,      // 任何传输类型kTransportHost,     // 主机传输类型
} transport_type;
​
// 传输结构体定义
struct atransport
{atransport *next;       // 链表下一个atransport *prev;       // 链表上一个
​// 传输操作函数指针int (*read_from_remote)(apacket *p, atransport *t);  // 从远程读取int (*write_to_remote)(apacket *p, atransport *t);   // 写入远程void (*close)(atransport *t);                        // 关闭传输void (*kick)(atransport *t);                         // 踢出传输
​int fd;                 // 文件描述符int transport_socket;   // 传输socketfdevent transport_fde;  // 传输文件描述符事件int ref_count;          // 引用计数unsigned sync_token;    // 同步令牌int connection_state;   // 连接状态transport_type type;    // 传输类型
​/* 根据需要使用的USB句柄或socket fd */usb_handle *usb;        // USB句柄int sfd;                // socket文件描述符
​/* 用于为客户端标识传输 */char *serial;           // 设备序列号char *product;          // 产品信息int adb_port;           // 用于模拟器(本地传输)
​/* 当传输被踢出时调用的adisconnect回调列表 */int          kicked;            // 踢出标志adisconnect  disconnects;       // 断开连接回调列表
};
​
​
/* 监听器是绑定到本地端口的实体,
** 并在该端口上接收到连接时,创建一个asocket
** 将新的本地连接连接到特定的远程服务。
**
** TODO:一些监听器从新连接读取以确定在远端要连接的确切服务。
*/
struct alistener
{alistener *next;        // 链表下一个alistener *prev;        // 链表上一个
​fdevent fde;            // 文件描述符事件int fd;                 // 文件描述符
​const char *local_name;     // 本地名称const char *connect_to;     // 连接目标atransport *transport;      // 关联的传输adisconnect  disconnect;    // 断开连接回调
};
​
​
// 函数声明
void print_packet(const char *label, apacket *p);  // 打印数据包信息
​
asocket *find_local_socket(unsigned id);           // 根据ID查找本地socket
void install_local_socket(asocket *s);             // 安装本地socket
void remove_socket(asocket *s);                    // 移除socket
void close_all_sockets(atransport *t);             // 关闭所有socket
​
#define  LOCAL_CLIENT_PREFIX  "emulator-"          // 本地客户端前缀
​
asocket *create_local_socket(int fd);                      // 创建本地socket
asocket *create_local_service_socket(const char *destination);  // 创建本地服务socket
​
asocket *create_remote_socket(unsigned id, atransport *t); // 创建远程socket
void connect_to_remote(asocket *s, const char *destination);    // 连接到远程
void connect_to_smartsocket(asocket *s);                       // 连接到智能socket
​
void fatal(const char *fmt, ...);                  // 致命错误处理
void fatal_errno(const char *fmt, ...);            // 带errno的致命错误处理
​
void handle_packet(apacket *p, atransport *t);     // 处理数据包
void send_packet(apacket *p, atransport *t);       // 发送数据包
​
void get_my_path(char *s, size_t maxLen);          // 获取自身路径
int launch_server(int server_port);                // 启动服务器
int adb_main(int is_daemon, int server_port);      // ADB主函数
​
​
/* 传输是引用计数的
** get_device_transport在返回前为您执行获取操作
*/
void init_transport_registration(void);                    // 初始化传输注册
int  list_transports(char *buf, size_t  bufsize);         // 列出传输
void update_transports(void);                             // 更新传输
​
asocket*  create_device_tracker(void);                    // 创建设备跟踪器
​
/* 从可用传输中获取一个传输。
** 如果state != CS_ANY,只考虑该状态的传输。
** 如果serial非NULL,则只选择具有该序列号的设备。
** 如果没有找到合适的传输,设置错误。
*/
atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char **error_out);
void   add_transport_disconnect( atransport*  t, adisconnect*  dis );     // 添加传输断开回调
void   remove_transport_disconnect( atransport*  t, adisconnect*  dis );  // 移除传输断开回调
void   run_transport_disconnects( atransport*  t );                       // 运行传输断开回调
void   kick_transport( atransport*  t );                                  // 踢出传输
​
/* 初始化传输对象的函数指针和状态 */
#if ADB_HOST
int get_available_local_transport_index();                // 获取可用本地传输索引
#endif
int  init_socket_transport(atransport *t, int s, int port, int local);  // 初始化socket传输
void init_usb_transport(atransport *t, usb_handle *usb, int state);     // 初始化USB传输
​
/* 用于MacOS X清理 */
void close_usb_devices();                                // 关闭USB设备
​
/* 导致新传输被初始化并添加到列表 */
void register_socket_transport(int s, const char *serial, int port, int local);  // 注册socket传输
​
/* 这些应仅用于"adb disconnect"命令 */
void unregister_transport(atransport *t);                // 注销传输
void unregister_all_tcp_transports();                    // 注销所有TCP传输
​
void register_usb_transport(usb_handle *h, const char *serial, unsigned writeable);  // 注册USB传输
​
/* 这应仅用于connection_state == CS_NOPERM的传输 */
void unregister_usb_transport(usb_handle *usb);          // 注销USB传输
​
atransport *find_transport(const char *serial);          // 根据序列号查找传输
#if ADB_HOST
atransport* find_emulator_transport_by_adb_port(int adb_port);  // 根据ADB端口查找模拟器传输
#endif
​
int service_to_fd(const char *name);                     // 服务名称转换为文件描述符
#if ADB_HOST
asocket *host_service_to_socket(const char*  name, const char *serial);  // 主机服务转换为socket
#endif
​
#if !ADB_HOST
int       init_jdwp(void);                               // 初始化JDWP
asocket*  create_jdwp_service_socket();                  // 创建JDWP服务socket
asocket*  create_jdwp_tracker_service_socket();          // 创建JDWP跟踪器服务socket
int       create_jdwp_connection_fd(int  jdwp_pid);      // 创建JDWP连接文件描述符
#endif
​
#if !ADB_HOST
typedef enum {BACKUP,     // 备份操作RESTORE     // 恢复操作
} BackupOperation;
int backup_service(BackupOperation operation, char* args);  // 备份服务
void framebuffer_service(int fd, void *cookie);           // 帧缓冲区服务
void log_service(int fd, void *cookie);                   // 日志服务
void remount_service(int fd, void *cookie);               // 重新挂载服务
char * get_log_file_path(const char * log_name);          // 获取日志文件路径
#endif
​
/* 数据包分配器 */
apacket *get_apacket(void);      // 获取数据包
void put_apacket(apacket *p);    // 释放数据包
​
int check_header(apacket *p);    // 检查数据包头
int check_data(apacket *p);      // 检查数据包数据
​
/* 定义ADB_TRACE为1启用跟踪支持,或0禁用它 */
#define  ADB_TRACE    1
​
/* 重要:如果您更改以下列表,不要忘记更新adb.c中实现的adb_trace_init()函数中相应的'tags'表 */
typedef enum {TRACE_ADB = 0,   /* 0x001 */  // ADB跟踪TRACE_SOCKETS,                 // Socket跟踪TRACE_PACKETS,                 // 数据包跟踪TRACE_TRANSPORT,               // 传输跟踪TRACE_RWX,       /* 0x010 */  // 读写执行跟踪TRACE_USB,                     // USB跟踪TRACE_SYNC,                    // 同步跟踪TRACE_SYSDEPS,                 // 系统依赖跟踪TRACE_JDWP,      /* 0x100 */  // JDWP跟踪TRACE_SERVICES,                // 服务跟踪
} AdbTrace;
​
#if ADB_TRACE
​
#if !ADB_HOST
/** 在模拟器内部运行时,客户机的adbd可以连接到'adb-debug'* qemud服务,该服务可以显示adb跟踪消息(条件是模拟器已使用'-debug adb'选项启动)。*/
​
/* 通过QEMU管道向模拟器传递跟踪消息。 */
void adb_qemu_trace(const char* fmt, ...);
/* 用于向模拟器发送ADB跟踪消息的宏。 */
#define DQ(...)    adb_qemu_trace(__VA_ARGS__)
#else
#define DQ(...) ((void)0)
#endif  /* !ADB_HOST */
​extern int     adb_trace_mask;                 // 跟踪掩码extern unsigned char    adb_trace_output_count; // 跟踪输出计数void    adb_trace_init(void);                  // 初始化跟踪
​
#  define ADB_TRACING  ((adb_trace_mask & (1 << TRACE_TAG)) != 0)  // 跟踪启用检查
​/* 在使用此宏之前必须定义TRACE_TAG */
#  define  D(...)                                      \do {                                           \if (ADB_TRACING) {                         \int save_errno = errno;                \adb_mutex_lock(&D_lock);               \fprintf(stderr, "%s::%s():",           \__FILE__, __FUNCTION__);       \errno = save_errno;                    \fprintf(stderr, __VA_ARGS__ );         \fflush(stderr);                        \adb_mutex_unlock(&D_lock);             \errno = save_errno;                    \}                                           \} while (0)
#  define  DR(...)                                     \do {                                           \if (ADB_TRACING) {                         \int save_errno = errno;                \adb_mutex_lock(&D_lock);               \errno = save_errno;                    \fprintf(stderr, __VA_ARGS__ );         \fflush(stderr);                        \adb_mutex_unlock(&D_lock);             \errno = save_errno;                    \}                                           \} while (0)
#else
#  define  D(...)          ((void)0)      // 空宏,跟踪禁用时
#  define  DR(...)         ((void)0)      // 空宏,跟踪禁用时
#  define  ADB_TRACING     0              // 跟踪禁用
#endif
​
​
#if !TRACE_PACKETS
#define print_packet(tag,p) do {} while (0)  // 空宏,数据包跟踪禁用时
#endif
​
#if ADB_HOST_ON_TARGET
/* adb和adbd在目标上共存,因此对adb使用5038端口以避免与adbd使用5037端口冲突 */
#  define DEFAULT_ADB_PORT 5038
#else
#  define DEFAULT_ADB_PORT 5037
#endif
​
#define DEFAULT_ADB_LOCAL_TRANSPORT_PORT 5555  // 默认ADB本地传输端口
​
#define ADB_CLASS              0xff    // ADB设备类
#define ADB_SUBCLASS           0x42    // ADB设备子类
#define ADB_PROTOCOL           0x1     // ADB设备协议
​
​
void local_init(int port);                              // 本地初始化
int  local_connect(int  port);                          // 本地连接
int  local_connect_arbitrary_ports(int console_port, int adb_port);  // 本地任意端口连接
​
/* USB主机/客户端接口 */
void usb_init();                                        // USB初始化
void usb_cleanup();                                     // USB清理
int usb_write(usb_handle *h, const void *data, int len);  // USB写入
int usb_read(usb_handle *h, void *data, int len);       // USB读取
int usb_close(usb_handle *h);                           // USB关闭
void usb_kick(usb_handle *h);                           // USB踢出
​
/* 用于USB设备检测 */
#if ADB_HOST
int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);  // 检查是否为ADB接口
#endif
​
unsigned host_to_le32(unsigned n);                      // 主机序转小端序
int adb_commandline(int argc, char **argv);             // ADB命令行处理
​
int connection_state(atransport *t);                    // 获取连接状态
​
// 连接状态常量定义
#define CS_ANY       -1      // 任何状态
#define CS_OFFLINE    0      // 离线状态
#define CS_BOOTLOADER 1      // 引导加载程序状态
#define CS_DEVICE     2      // 设备状态
#define CS_HOST       3      // 主机状态
#define CS_RECOVERY   4      // 恢复模式状态
#define CS_NOPERM     5      // 权限不足,无法与设备通信
#define CS_SIDELOAD   6      // 侧载状态
​
extern int HOST;                    // 主机标志
extern int SHELL_EXIT_NOTIFY_FD;    // Shell退出通知文件描述符
​
#define CHUNK_SIZE (64*1024)        // 数据块大小(64KB)
​
int sendfailmsg(int fd, const char *reason);                                  // 发送失败消息
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s);  // 处理主机请求
​
#endif

主要数据结构

1. 协议消息结构 (amessage)
  • 定义了ADB协议的6种命令类型

  • 包含命令、参数、数据长度、校验和等字段

  • 使用魔数进行协议验证

2. 数据包结构 (apacket)
  • 链表结构管理数据包

  • 包含消息头和4KB数据载荷

  • 支持数据包的分配和释放

3. Socket抽象 (asocket)
  • 统一的本地和远程socket接口

  • 支持双向数据流控制

  • 包含就绪、关闭等回调函数

4. 传输层抽象 (atransport)
  • 支持USB和TCP两种传输方式

  • 引用计数管理

  • 连接状态跟踪

设计模式应用

1. 抽象工厂模式
  • create_local_socket(), create_remote_socket()等创建函数

  • 统一的socket创建接口

2. 观察者模式
  • adisconnect回调机制

  • 传输断开时的通知系统

3. 策略模式
  • 不同的传输类型(USB、TCP)

  • 可插拔的传输实现

4. 状态模式
  • 连接状态管理(离线、设备、恢复模式等)

  • 状态相关的行为控制

运行效率特性

1. 内存管理
  • 数据包预分配机制

  • 固定大小的数据载荷(4KB)

  • 链表管理避免内存碎片

2. I/O优化
  • 大块数据传输(64KB块大小)

  • 非阻塞I/O支持

  • 批量数据包处理

3. 协议优化
  • 二进制协议减少解析开销

  • 校验和确保数据完整性

  • 魔数验证协议正确性

跨平台支持

  • 条件编译支持不同平台

  • 统一的抽象接口

  • 平台特定的实现封装

再分析这些接口实现

#define  TRACE_TAG   TRACE_ADB  // 定义调试跟踪标签
​
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
​
#include "sysdeps.h"  // 系统依赖头文件
#include "adb.h"      // ADB核心头文件
​
#if !ADB_HOST  // 设备端代码
#include <linux/capability.h>
#include <linux/prctl.h>
#else          // 主机端代码
#include "usb_vendors.h"
#endif
​
#if ADB_TRACE
ADB_MUTEX_DEFINE( D_lock );  // 调试跟踪互斥锁
#endif
​
#define ALLOW_ADBD_ROOT  // 允许ADB以root权限运行
int HOST = 0;  // 标识当前是主机端还是设备端
​
static const char *adb_device_banner = "device";  // 设备标识字符串
​
// 致命错误处理函数
void fatal(const char *fmt, ...)
{va_list ap;va_start(ap, fmt);fprintf(stderr, "error: ");vfprintf(stderr, fmt, ap);fprintf(stderr, "\n");va_end(ap);exit(-1);
}
​
// 带errno的致命错误处理
void fatal_errno(const char *fmt, ...)
{va_list ap;va_start(ap, fmt);fprintf(stderr, "error: %s: ", strerror(errno));vfprintf(stderr, fmt, ap);fprintf(stderr, "\n");va_end(ap);exit(-1);
}
​
int   adb_trace_mask;  // 调试跟踪掩码
​
/* 从ADB_TRACE环境变量读取逗号/空格分隔的标签列表* 并构建跟踪掩码。注意'1'和'all'是特殊情况,启用所有跟踪*/
void  adb_trace_init(void)
{const char*  p = getenv("ADB_TRACE");const char*  q;
​// 跟踪标签定义表static const struct {const char*  tag;int           flag;} tags[] = {{ "1", 0 },           // 特殊值:启用所有跟踪{ "all", 0 },         // 特殊值:启用所有跟踪{ "adb", TRACE_ADB },{ "sockets", TRACE_SOCKETS },{ "packets", TRACE_PACKETS },{ "rwx", TRACE_RWX },{ "usb", TRACE_USB },{ "sync", TRACE_SYNC },{ "sysdeps", TRACE_SYSDEPS },{ "transport", TRACE_TRANSPORT },{ "jdwp", TRACE_JDWP },{ "services", TRACE_SERVICES },{ NULL, 0 }};
​if (p == NULL)return;
​// 使用逗号/分号/空格分隔的列表while (*p) {int  len, tagn;
​q = strpbrk(p, " ,:;");  // 查找分隔符if (q == NULL) {q = p + strlen(p);}len = q - p;
​// 在标签表中查找匹配项for (tagn = 0; tags[tagn].tag != NULL; tagn++){int  taglen = strlen(tags[tagn].tag);
​if (len == taglen && !memcmp(tags[tagn].tag, p, len) ){int  flag = tags[tagn].flag;if (flag == 0) {  // 特殊标签:启用所有跟踪adb_trace_mask = ~0;return;}adb_trace_mask |= (1 << flag);  // 设置对应的跟踪位break;}}p = q;if (*p)p++;}
}
​
// 数据包管理函数
apacket *get_apacket(void)
{apacket *p = malloc(sizeof(apacket));if(p == 0) fatal("failed to allocate an apacket");memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);  // 清零除了数据负载的部分return p;
}
​
void put_apacket(apacket *p)
{free(p);  // 释放数据包内存
}
​
// 设备上线处理
void handle_online(void)
{D("adb: online\n");  // 调试输出
}
​
// 设备离线处理
void handle_offline(atransport *t)
{D("adb: offline\n");// 关闭相关的USB连接run_transport_disconnects(t);
}
​
#if TRACE_PACKETS  // 数据包跟踪功能
#define DUMPMAX 32
void print_packet(const char *label, apacket *p)
{char *tag;char *x;unsigned count;
​// 根据命令类型设置标签switch(p->msg.command){case A_SYNC: tag = "SYNC"; break;case A_CNXN: tag = "CNXN" ; break;case A_OPEN: tag = "OPEN"; break;case A_OKAY: tag = "OKAY"; break;case A_CLSE: tag = "CLSE"; break;case A_WRTE: tag = "WRTE"; break;default: tag = "????"; break;}
​// 打印数据包基本信息fprintf(stderr, "%s: %s %08x %08x %04x \"",label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);count = p->msg.data_length;x = (char*) p->data;if(count > DUMPMAX) {  // 限制输出长度count = DUMPMAX;tag = "\n";} else {tag = "\"\n";}// 打印数据内容(可打印字符显示原字符,不可打印字符显示点)while(count-- > 0){if((*x >= ' ') && (*x < 127)) {fputc(*x, stderr);} else {fputc('.', stderr);}x++;}fprintf(stderr, tag);
}
#endif
​
// 发送READY响应
static void send_ready(unsigned local, unsigned remote, atransport *t)
{D("Calling send_ready \n");apacket *p = get_apacket();p->msg.command = A_OKAY;p->msg.arg0 = local;p->msg.arg1 = remote;send_packet(p, t);
}
​
// 发送CLOSE请求
static void send_close(unsigned local, unsigned remote, atransport *t)
{D("Calling send_close \n");apacket *p = get_apacket();p->msg.command = A_CLSE;p->msg.arg0 = local;p->msg.arg1 = remote;send_packet(p, t);
}
​
// 发送CONNECT请求建立连接
static void send_connect(atransport *t)
{D("Calling send_connect \n");apacket *cp = get_apacket();cp->msg.command = A_CNXN;cp->msg.arg0 = A_VERSION;      // 协议版本cp->msg.arg1 = MAX_PAYLOAD;    // 最大负载大小snprintf((char*) cp->data, sizeof cp->data, "%s::",HOST ? "host" : adb_device_banner);  // 设备标识cp->msg.data_length = strlen((char*) cp->data) + 1;send_packet(cp, t);
#if ADB_HOST// 给设备时间响应连接消息adb_sleep_ms(1000);
#endif
}
​
// 获取连接状态名称
static char *connection_state_name(atransport *t)
{if (t == NULL) {return "unknown";}
​switch(t->connection_state) {case CS_BOOTLOADER:return "bootloader";case CS_DEVICE:return "device";case CS_OFFLINE:return "offline";default:return "unknown";}
}
​
// 解析设备标识横幅
void parse_banner(char *banner, atransport *t)
{char *type, *product, *end;
​D("parse_banner: %s\n", banner);type = banner;product = strchr(type, ':');if(product) {*product++ = 0;} else {product = "";}
​// 移除尾部冒号end = strchr(product, ':');if(end) *end = 0;
​// 在设备结构中保存产品名称if (t->product == NULL) {t->product = strdup(product);} else if (strcmp(product, t->product) != 0) {free(t->product);t->product = strdup(product);}
​// 根据设备类型设置连接状态if(!strcmp(type, "bootloader")){D("setting connection_state to CS_BOOTLOADER\n");t->connection_state = CS_BOOTLOADER;update_transports();return;}
​if(!strcmp(type, "device")) {D("setting connection_state to CS_DEVICE\n");t->connection_state = CS_DEVICE;update_transports();return;}
​if(!strcmp(type, "recovery")) {D("setting connection_state to CS_RECOVERY\n");t->connection_state = CS_RECOVERY;update_transports();return;}
​if(!strcmp(type, "sideload")) {D("setting connection_state to CS_SIDELOAD\n");t->connection_state = CS_SIDELOAD;update_transports();return;}
​t->connection_state = CS_HOST;
}
​
// 处理接收到的数据包(核心函数)
void handle_packet(apacket *p, atransport *t)
{asocket *s;
​D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],((char*) (&(p->msg.command)))[1],((char*) (&(p->msg.command)))[2],((char*) (&(p->msg.command)))[3]);print_packet("recv", p);
​switch(p->msg.command){case A_SYNC:  // 同步命令if(p->msg.arg0){send_packet(p, t);if(HOST) send_connect(t);} else {t->connection_state = CS_OFFLINE;handle_offline(t);send_packet(p, t);}return;
​case A_CNXN:  // 连接命令if(t->connection_state != CS_OFFLINE) {t->connection_state = CS_OFFLINE;handle_offline(t);}parse_banner((char*) p->data, t);  // 解析设备信息handle_online();                   // 处理上线if(!HOST) send_connect(t);         // 设备端回应连接break;
​case A_OPEN:  // 打开连接if(t->connection_state != CS_OFFLINE) {char *name = (char*) p->data;name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;s = create_local_service_socket(name);  // 创建本地服务socketif(s == 0) {send_close(0, p->msg.arg0, t);  // 创建失败则关闭} else {s->peer = create_remote_socket(p->msg.arg0, t);  // 创建对端sockets->peer->peer = s;send_ready(s->id, s->peer->id, t);  // 发送就绪信号s->ready(s);}}break;
​case A_OKAY:  // 就绪响应if(t->connection_state != CS_OFFLINE) {if((s = find_local_socket(p->msg.arg1))) {if(s->peer == 0) {s->peer = create_remote_socket(p->msg.arg0, t);s->peer->peer = s;}s->ready(s);  // 通知socket就绪}}break;
​case A_CLSE:  // 关闭连接if(t->connection_state != CS_OFFLINE) {if((s = find_local_socket(p->msg.arg1))) {s->close(s);  // 关闭socket}}break;
​case A_WRTE:  // 写入数据if(t->connection_state != CS_OFFLINE) {if((s = find_local_socket(p->msg.arg1))) {unsigned rid = p->msg.arg0;p->len = p->msg.data_length;
​if(s->enqueue(s, p) == 0) {  // 数据入队成功D("Enqueue the socket\n");send_ready(s->id, rid, t);  // 发送就绪信号}return;  // 不释放数据包,数据已传递}}break;
​default:printf("handle_packet: what is %08x?!\n", p->msg.command);}
​put_apacket(p);  // 释放数据包
}
​
// 监听器链表(双向循环链表)
alistener listener_list = {.next = &listener_list,.prev = &listener_list,
};
​
// 智能socket监听器事件处理
static void ss_listener_event_func(int _fd, unsigned ev, void *_l)
{asocket *s;
​if(ev & FDE_READ) {  // 可读事件struct sockaddr addr;socklen_t alen;int fd;
​alen = sizeof(addr);fd = adb_socket_accept(_fd, &addr, &alen);  // 接受连接if(fd < 0) return;
​adb_socket_setbufsize(fd, CHUNK_SIZE);  // 设置缓冲区大小
​s = create_local_socket(fd);if(s) {connect_to_smartsocket(s);  // 连接到智能socketreturn;}
​adb_close(fd);}
}
​
// 普通监听器事件处理
static void listener_event_func(int _fd, unsigned ev, void *_l)
{alistener *l = _l;asocket *s;
​if(ev & FDE_READ) {struct sockaddr addr;socklen_t alen;int fd;
​alen = sizeof(addr);fd = adb_socket_accept(_fd, &addr, &alen);if(fd < 0) return;
​s = create_local_socket(fd);if(s) {s->transport = l->transport;connect_to_remote(s, l->connect_to);  // 连接到远程return;}
​adb_close(fd);}
}
​
// 释放监听器资源
static void  free_listener(alistener*  l)
{if (l->next) {l->next->prev = l->prev;l->prev->next = l->next;l->next = l->prev = l;}
​// 移除文件描述符事件监听fdevent_remove(&l->fde);
​// 释放内存if (l->local_name)free((char*)l->local_name);
​if (l->connect_to)free((char*)l->connect_to);
​if (l->transport) {remove_transport_disconnect(l->transport, &l->disconnect);}free(l);
}
​
// 监听器断开连接处理
static void listener_disconnect(void*  _l, atransport*  t)
{alistener*  l = _l;free_listener(l);
}
​
// 本地名称转换为文件描述符
int local_name_to_fd(const char *name)
{int port;
​if(!strncmp("tcp:", name, 4)){  // TCP连接int  ret;port = atoi(name + 4);ret = socket_inaddr_any_server(port, SOCK_STREAM);  // 创建TCP服务器return ret;}
#ifndef HAVE_WIN32_IPC  // Win32没有Unix域socket// 本地抽象socketif(!strncmp(name, "local:", 6)) {return socket_local_server(name + 6,ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);} else if(!strncmp(name, "localabstract:", 14)) {return socket_local_server(name + 14,ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);} else if(!strncmp(name, "localfilesystem:", 16)) {return socket_local_server(name + 16,ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);}
#endifprintf("unknown local portname '%s'\n", name);return -1;
}
​
// 移除监听器
static int remove_listener(const char *local_name, const char *connect_to, atransport* transport)
{alistener *l;
​// 遍历监听器链表查找匹配项for (l = listener_list.next; l != &listener_list; l = l->next) {if (!strcmp(local_name, l->local_name) &&!strcmp(connect_to, l->connect_to) &&l->transport && l->transport == transport) {
​listener_disconnect(l, transport);return 0;}}
​return -1;
}
​
// 安装监听器
static int install_listener(const char *local_name, const char *connect_to, atransport* transport)
{alistener *l;
​printf("install_listener('%s','%s')\n", local_name, connect_to);
​// 检查是否已存在相同本地名称的监听器for(l = listener_list.next; l != &listener_list; l = l->next){if(strcmp(local_name, l->local_name) == 0) {char *cto;
​// 不能重新指定智能socketif(l->connect_to[0] == '*') {return -1;}
​cto = strdup(connect_to);if(cto == 0) {return -1;}
​// 重新绑定到新的连接目标free((void*) l->connect_to);l->connect_to = cto;if (l->transport != transport) {remove_transport_disconnect(l->transport, &l->disconnect);l->transport = transport;add_transport_disconnect(l->transport, &l->disconnect);}return 0;}}
​// 创建新的监听器if((l = calloc(1, sizeof(alistener))) == 0) goto nomem;if((l->local_name = strdup(local_name)) == 0) goto nomem;if((l->connect_to = strdup(connect_to)) == 0) goto nomem;
​l->fd = local_name_to_fd(local_name);if(l->fd < 0) {free((void*) l->local_name);free((void*) l->connect_to);free(l);printf("cannot bind '%s'\n", local_name);return -2;}
​close_on_exec(l->fd);  // 设置exec时关闭// 根据连接目标类型安装不同的事件处理器if(!strcmp(l->connect_to, "*smartsocket*")) {fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);} else {fdevent_install(&l->fde, l->fd, listener_event_func, l);}fdevent_set(&l->fde, FDE_READ);  // 设置读事件监听
​// 添加到监听器链表l->next = &listener_list;l->prev = listener_list.prev;l->next->prev = l;l->prev->next = l;l->transport = transport;
​if (transport) {l->disconnect.opaque = l;l->disconnect.func   = listener_disconnect;add_transport_disconnect(transport, &l->disconnect);}return 0;
​
nomem:fatal("cannot allocate listener");return 0;
}
​
// Windows Ctrl+C处理
#ifdef HAVE_WIN32_PROC
static BOOL WINAPI ctrlc_handler(DWORD type)
{exit(STATUS_CONTROL_C_EXIT);return TRUE;
}
#endif
​
// ADB清理函数
static void adb_cleanup(void)
{usb_cleanup();  // 清理USB资源
}
​
// 启动日志记录
void start_logging(void)
{
#ifdef HAVE_WIN32_PROC// Windows平台日志设置char    temp[ MAX_PATH ];FILE*   fnul;FILE*   flog;
​GetTempPath( sizeof(temp) - 8, temp );strcat( temp, "adb.log" );
​fnul = fopen( "NUL", "rt" );if (fnul != NULL)stdin[0] = fnul[0];
​flog = fopen( temp, "at" );if (flog == NULL)flog = fnul;
​setvbuf( flog, NULL, _IONBF, 0 );
​stdout[0] = flog[0];stderr[0] = flog[0];fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
#else// Unix平台日志设置int fd;
​fd = unix_open("/dev/null", O_RDONLY);dup2(fd, 0);  // 重定向标准输入到/dev/nulladb_close(fd);
​fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640);if(fd < 0) {fd = unix_open("/dev/null", O_WRONLY);}dup2(fd, 1);  // 重定向标准输出dup2(fd, 2);  // 重定向标准错误adb_close(fd);fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
#endif
}
​
#if !ADB_HOST
// 设备端启动日志
void start_device_log(void)
{int fd;char    path[PATH_MAX];struct tm now;time_t t;char value[PROPERTY_VALUE_MAX];
​// 从持久属性读取跟踪掩码property_get("persist.adb.trace_mask", value, "");if (sscanf(value, "%x", &adb_trace_mask) != 1)return;
​adb_mkdir("/data/adb", 0775);tzset();time(&t);localtime_r(&t, &now);// 生成带时间戳的日志文件名strftime(path, sizeof(path),"/data/adb/adb-%Y-%m-%d-%H-%M-%S.txt",&now);fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640);if (fd < 0)return;
​// 重定向标准输出和错误到日志文件dup2(fd, 1);dup2(fd, 2);fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());adb_close(fd);
​fd = unix_open("/dev/null", O_RDONLY);dup2(fd, 0);adb_close(fd);
}
#endif
​
#if ADB_HOST
// 启动ADB服务器
int launch_server(int server_port)
{
#ifdef HAVE_WIN32_PROC/* Windows平台服务器启动实现 */HANDLE                pipe_read, pipe_write;SECURITY_ATTRIBUTES   sa;STARTUPINFO           startup;PROCESS_INFORMATION   pinfo;char                  program_path[ MAX_PATH ];int                   ret;
​sa.nLength = sizeof(sa);sa.lpSecurityDescriptor = NULL;sa.bInheritHandle = TRUE;
​// 创建管道用于进程间通信ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );if (!ret) {fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );return -1;}
​SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
​ZeroMemory( &startup, sizeof(startup) );startup.cb = sizeof(startup);startup.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );startup.hStdOutput = pipe_write;  // 子进程输出到管道startup.hStdError  = GetStdHandle( STD_ERROR_HANDLE );startup.dwFlags    = STARTF_USESTDHANDLES;
​ZeroMemory( &pinfo, sizeof(pinfo) );
​// 获取当前程序路径GetModuleFileName( NULL, program_path, sizeof(program_path) );
​// 创建子进程ret = CreateProcess(program_path,"adb fork-server server",  // 启动fork-serverNULL,NULL,TRUE,DETACHED_PROCESS,NULL,NULL,&startup,&pinfo );
​CloseHandle( pipe_write );
​if (!ret) {fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );CloseHandle( pipe_read );return -1;}
​CloseHandle( pinfo.hProcess );CloseHandle( pinfo.hThread );
​// 等待服务器的"OK"消息{char  temp[3];DWORD  count;
​ret = ReadFile( pipe_read, temp, 3, &count, NULL );CloseHandle( pipe_read );if ( !ret ) {fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );return -1;}if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {fprintf(stderr, "ADB server didn't ACK\n" );return -1;}}
#elif defined(HAVE_FORKEXEC)/* Unix平台服务器启动实现 */char    path[PATH_MAX];int     fd[2];
​// 创建管道用于父子进程通信if (pipe(fd)) {fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);return -1;}get_my_path(path, PATH_MAX);pid_t pid = fork();if(pid < 0) return -1;
​if (pid == 0) {// 子进程adb_close(fd[0]);dup2(fd[1], STDERR_FILENO);  // 重定向标准错误到管道adb_close(fd[1]);
​// 执行adb服务器int result = execl(path, "adb", "fork-server", "server", NULL);fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);} else  {// 父进程char  temp[3];
​temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';// 等待服务器的"OK"消息adb_close(fd[1]);int ret = adb_read(fd[0], temp, 3);int saved_errno = errno;adb_close(fd[0]);if (ret < 0) {fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);return -1;}if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {fprintf(stderr, "ADB server didn't ACK\n" );return -1;}
​setsid();  // 创建新会话}
#else
#error "cannot implement background server start on this platform"
#endifreturn 0;
}
#endif
​
// 构建本地名称
void build_local_name(char* target_str, size_t target_size, int server_port)
{snprintf(target_str, target_size, "tcp:%d", server_port);
}
​
#if !ADB_HOST
// 检查是否应该降低权限
static int should_drop_privileges() {
#ifndef ALLOW_ADBD_ROOTreturn 1;  // 不允许root权限
#else /* ALLOW_ADBD_ROOT */int secure = 0;char value[PROPERTY_VALUE_MAX];
​/* 如果ro.secure设置且不在模拟器中,则以安全模式运行adbd */property_get("ro.kernel.qemu", value, "");if (strcmp(value, "1") != 0) {property_get("ro.secure", value, "1");if (strcmp(value, "1") == 0) {// 如果ro.secure设置,不以root运行...secure = 1;
​// ...除非在userdebug版本中且service.adb.root属性被设置property_get("ro.debuggable", value, "");if (strcmp(value, "1") == 0) {property_get("service.adb.root", value, "");if (strcmp(value, "1") == 0) {secure = 0;}}}}return 0;  // 实际返回0,允许root权限
#endif /* ALLOW_ADBD_ROOT */
}
#endif /* !ADB_HOST */
​
// ADB主函数
int adb_main(int is_daemon, int server_port)
{
#if !ADB_HOSTint port;char value[PROPERTY_VALUE_MAX];
​umask(000);  // 设置文件创建掩码
#endif
​atexit(adb_cleanup);  // 注册退出清理函数
#ifdef HAVE_WIN32_PROCSetConsoleCtrlHandler( ctrlc_handler, TRUE );
#elif defined(HAVE_FORKEXEC)signal(SIGPIPE, SIG_IGN);  // 忽略SIGPIPE信号
#endif
​init_transport_registration();  // 初始化传输注册
​
#if ADB_HOST// 主机端初始化HOST = 1;usb_vendors_init();  // 初始化USB厂商列表usb_init();          // 初始化USBlocal_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);  // 初始化本地传输
​char local_name[30];build_local_name(local_name, sizeof(local_name), server_port);if(install_listener(local_name, "*smartsocket*", NULL)) {exit(1);}
#else// 设备端初始化if (should_drop_privileges()) {// 降低权限的安全模式struct __user_cap_header_struct header;struct __user_cap_data_struct cap;
​if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {exit(1);}// 权限降低逻辑(当前被注释)} else {// 保持root权限char local_name[30];build_local_name(local_name, sizeof(local_name), server_port);if(install_listener(local_name, "*smartsocket*", NULL)) {exit(1);}}
​// 根据属性设置选择传输方式property_get("service.adb.tcp.port", value, "");if (!value[0])property_get("persist.adb.tcp.port", value, "");if (sscanf(value, "%d", &port) == 1 && port > 0) {// 监听TCP端口local_init(port);} else if (access("/dev/android_adb", F_OK) == 0) {// 监听USBusb_init();} else {// 监听默认端口local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);}D("adb_main(): pre init_jdwp()\n");init_jdwp();  // 初始化JDWP调试支持D("adb_main(): post init_jdwp()\n");
#endif
​if (is_daemon){// 守护进程模式:通知父进程已启动
#ifdef HAVE_WIN32_PROCDWORD  count;WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL );
#elif defined(HAVE_FORKEXEC)fprintf(stderr, "OK\n");
#endifstart_logging();  // 启动日志记录}D("Event loop starting\n");
​fdevent_loop();  // 进入事件循环
​usb_cleanup();   // 清理USB资源
​return 0;
}
​
#if ADB_HOST
// 连接设备函数
void connect_device(char* host, char* buffer, int buffer_size)
{int port, fd;char* portstr = strchr(host, ':');char hostbuf[100];char serial[100];
​strncpy(hostbuf, host, sizeof(hostbuf) - 1);if (portstr) {// 解析端口号if (portstr - host >= sizeof(hostbuf)) {snprintf(buffer, buffer_size, "bad host name %s", host);return;}hostbuf[portstr - host] = 0;if (sscanf(portstr + 1, "%d", &port) == 0) {snprintf(buffer, buffer_size, "bad port number %s", portstr);return;}} else {port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;  // 默认端口}
​snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port);if (find_transport(serial)) {snprintf(buffer, buffer_size, "already connected to %s", serial);return;}
​// 创建网络连接fd = socket_network_client(hostbuf, port, SOCK_STREAM);if (fd < 0) {snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port);return;}
​D("client: connected on remote on fd %d\n", fd);close_on_exec(fd);disable_tcp_nagle(fd);  // 禁用Nagle算法register_socket_transport(fd, serial, port, 0);  // 注册socket传输snprintf(buffer, buffer_size, "connected to %s", serial);
}
​
// 连接模拟器函数
void connect_emulator(char* port_spec, char* buffer, int buffer_size)
{char* port_separator = strchr(port_spec, ',');if (!port_separator) {snprintf(buffer, buffer_size,"unable to parse '%s' as <console port>,<adb port>",port_spec);return;}
​// 解析控制台端口和ADB端口*port_separator++ = 0;int console_port = strtol(port_spec, NULL, 0);int adb_port = strtol(port_separator, NULL, 0);if (!(console_port > 0 && adb_port > 0)) {*(port_separator - 1) = ',';snprintf(buffer, buffer_size,"Invalid port numbers: Expected positive numbers, got '%s'",port_spec);return;}
​// 检查模拟器是否已注册atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port);if (known_emulator != NULL) {snprintf(buffer, buffer_size,"Emulator on port %d already registered.", adb_port);return;}
​// 检查是否可以注册更多模拟器int candidate_slot = get_available_local_transport_index();if (candidate_slot < 0) {snprintf(buffer, buffer_size, "Cannot accept more emulators.");return;}
​// 连接到模拟器if (!local_connect_arbitrary_ports(console_port, adb_port)) {snprintf(buffer, buffer_size,"Connected to emulator on ports %d,%d", console_port, adb_port);} else {snprintf(buffer, buffer_size,"Could not connect to emulator on ports %d,%d",console_port, adb_port);}
}
#endif
​
// 处理主机请求
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
{atransport *transport = NULL;char buf[4096];
​if(!strcmp(service, "kill")) {// 杀死ADB服务器fprintf(stderr,"adb server killed by remote request\n");fflush(stdout);adb_write(reply_fd, "OKAY", 4);usb_cleanup();exit(0);}
​
#if ADB_HOST// 传输切换请求if (!strncmp(service, "transport", strlen("transport"))) {char* error_string = "unknown failure";transport_type type = kTransportAny;
​// 解析传输类型if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {type = kTransportUsb;} else if (!strncmp(service, "transport-local", strlen("transport-local"))) {type = kTransportLocal;} else if (!strncmp(service, "transport-any", strlen("transport-any"))) {type = kTransportAny;} else if (!strncmp(service, "transport:", strlen("transport:"))) {service += strlen("transport:");serial = service;}
​transport = acquire_one_transport(CS_ANY, type, serial, &error_string);
​if (transport) {s->transport = transport;adb_write(reply_fd, "OKAY", 4);} else {sendfailmsg(reply_fd, error_string);}return 1;}
​// 返回所有已连接设备列表if (!strcmp(service, "devices")) {char buffer[4096];memset(buf, 0, sizeof(buf));memset(buffer, 0, sizeof(buffer));D("Getting device list \n");list_transports(buffer, sizeof(buffer));snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);D("Wrote device list \n");writex(reply_fd, buf, strlen(buf));return 0;}
​// 添加新的TCP传输(设备或模拟器)if (!strncmp(service, "connect:", 8)) {char buffer[4096];char* host = service + 8;if (!strncmp(host, "emu:", 4)) {connect_emulator(host + 4, buffer, sizeof(buffer));} else {connect_device(host, buffer, sizeof(buffer));}snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);writex(reply_fd, buf, strlen(buf));return 0;}
​// 移除TCP传输if (!strncmp(service, "disconnect:", 11)) {char buffer[4096];memset(buffer, 0, sizeof(buffer));char* serial = service + 11;if (serial[0] == 0) {// 断开所有TCP设备unregister_all_tcp_transports();} else {char hostbuf[100];// 假设端口5555如果未指定if (!strchr(serial, ':')) {snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);serial = hostbuf;}atransport *t = find_transport(serial);
​if (t) {unregister_transport(t);} else {snprintf(buffer, sizeof(buffer), "No such device %s", serial);}}
​snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);writex(reply_fd, buf, strlen(buf));return 0;}
​// 返回ADB服务器版本if (!strcmp(service, "version")) {char version[12];snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version);writex(reply_fd, buf, strlen(buf));return 0;}
​// 获取序列号if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {char *out = "unknown";transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);if (transport && transport->serial) {out = transport->serial;}snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);writex(reply_fd, buf, strlen(buf));return 0;}// 新模拟器实例启动if (!strncmp(service,"emulator:",9)) {int  port = atoi(service+9);local_connect(port);return 0;}
#endif // ADB_HOST
​// 端口转发管理if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) {char *local, *remote, *err;int r;atransport *transport;
​int createForward = strncmp(service,"kill",4);  // 判断是创建还是删除转发
​local = service + (createForward ? 8 : 12);remote = strchr(local,';');if(remote == 0) {sendfailmsg(reply_fd, "malformed forward spec");return 0;}
​*remote++ = 0;if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){sendfailmsg(reply_fd, "malformed forward spec");return 0;}
​transport = acquire_one_transport(CS_ANY, ttype, serial, &err);if (!transport) {sendfailmsg(reply_fd, err);return 0;}
​if (createForward) {r = install_listener(local, remote, transport);  // 安装监听器} else {r = remove_listener(local, remote, transport);   // 移除监听器}if(r == 0) {writex(reply_fd, "OKAYOKAY", 8);  // 双重OKAY响应return 0;}
​if (createForward) {sendfailmsg(reply_fd, (r == -1) ? "cannot rebind smartsocket" : "cannot bind socket");} else {sendfailmsg(reply_fd, "cannot remove listener");}return 0;}
​// 获取设备状态if(!strncmp(service,"get-state",strlen("get-state"))) {transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);char *state = connection_state_name(transport);snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state);writex(reply_fd, buf, strlen(buf));return 0;}return -1;  // 未知服务
}
​
#if !ADB_HOST
int recovery_mode = 0;  // 恢复模式标志
#endif
​
// 程序主入口
int main(int argc, char **argv)
{
#if ADB_HOST// 主机端入口adb_sysdeps_init();  // 初始化系统依赖adb_trace_init();    // 初始化跟踪系统D("Handling commandline()\n");return adb_commandline(argc - 1, argv + 1);  // 处理命令行
#else// 设备端入口if((argc > 1) && (!strcmp(argv[1],"recovery"))) {adb_device_banner = "recovery";  // 恢复模式标识recovery_mode = 1;}
​start_device_log();  // 启动设备日志D("Handling main()\n");printf("-v- Handling main() -v-\n");return adb_main(0, DEFAULT_ADB_PORT);  // 进入ADB主循环
#endif
}
​
​

http://www.dtcms.com/a/540932.html

相关文章:

  • 零基础学jsp网站开发自己做的网站链接
  • 根据参数动态配置多数据源
  • 帝国cms小程序获取分类的api接口
  • 黄冈网站建设有哪些某互联网公司开发官网的首页
  • 前端与Node.js
  • 怎样做电商网站好视频教学ps做网站页面设置为多大
  • 肇庆市住房和城乡建设局网站企业网站维护工作内容
  • 芯片选型避坑指南:如何根据需求快速筛选MCU
  • 【MATLAB代码】基于噪声协方差自适应的互补滤波器方法vs标准互补滤波,用于估计角度,附完整代码
  • 金仓数据库替代MongoDB实战:政务电子证照系统的国产化转型之路
  • 深度学习超材料逆向设计专题学习
  • 基于Matlab的批处理最小二乘法参数估计
  • 自己做书画交易网站北京网页设计如何创意
  • 鸿蒙应用开发:华为静默登录解决方案
  • 【Linux Oracle】批量抽取数据库特定条件的数据
  • 公司网站一年费用wordpress 球员
  • 百度建立企业网站建设的目的用h5开发的网站模板
  • Windows下C语言连接瀚高数据库
  • 现代 Python 学习笔记:Statements Syntax
  • Debian、Ubuntu、CentOS:Linux 三大发行版的核心区别
  • 石家庄桥西网站制作公司阮一峰wordpress
  • WordPress网站接入公众号设计参考图网站
  • Spring Boot 中 controller层注解
  • 润滑油东莞网站建设技术支持网页美工培训中心
  • Jmeter:接口测试流程(附图)
  • 大模型面试题:简述GPT和BERT的区别?
  • myalsa仓库体验
  • 全域互联,统一管控:EasyCVR构建多区域视频监控“一网统管”新范式
  • 使用 Fast GraphRAG 和 LM Studio 搭建本地技术文档分析系统
  • 【技术变迁脉络解析】Axure RP 介绍、版本历史及推荐