转载:http://blog.csdn.net/kc58236582/article/details/51132674
adbd之前看过一次,觉得代码太复杂然后,又是adb client adb server adbd交织在一起感觉看起来太累,最近项目需要把它大致看完了,梳理下,感觉从adbd能学到很多东西,在此总结下,adbd的代码。
我只分析我看懂了,不可能面面俱到。而且主要注重在通信方面,以及一些命令处理等。
一、adb主函数
我们先来看下主函数:
- int main(int argc, char **argv) {
- #if ADB_HOST
-
- adb_sysdeps_init();
- adb_trace_init();
- D("Handling commandline()\n");
- return adb_commandline(argc - 1, const_cast<const char**>(argv + 1));
- #else
-
- while (true) {
- static struct option opts[] = {
- {"root_seclabel", required_argument, nullptr, 's'},
- {"device_banner", required_argument, nullptr, 'b'},
- {"version", no_argument, nullptr, 'v'},
- };
-
- int option_index = 0;
- int c = getopt_long(argc, argv, "", opts, &option_index);
- if (c == -1)
- break;
- switch (c) {
- case 's':
- root_seclabel = optarg;
- break;
- case 'b':
- adb_device_banner = optarg;
- break;
- case 'v':
- printf("Android Debug Bridge Daemon version %d.%d.%d %s\n",
- ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION,
- ADB_REVISION);
- return 0;
- default:
- break;
- }
- }
-
- close_stdin();
-
- adb_trace_init();
-
-
-
- adb_qemu_trace_init();
-
- D("Handling main()\n");
- return adb_main(0, DEFAULT_ADB_PORT);
- #endif
ADB_HOST宏直接用来区分是pc上的还是手机上的,pc上的直接用adb_commandline函数处理各种命令,我们就不看了,我们主要分析adbd。
adbd主要调用了adb_main方法
- int adb_main(int is_daemon, int server_port)
- {
- #if !ADB_HOST
- int port;
- char value[PROPERTY_VALUE_MAX];
-
- umask(000);
- #endif
-
- atexit(adb_cleanup);
- #if defined(_WIN32)
- SetConsoleCtrlHandler( ctrlc_handler, TRUE );
- #else
-
- signal(SIGPIPE, SIG_IGN);
- #endif
-
- init_transport_registration();
-
- #if ADB_HOST
- HOST = 1;
-
- #ifdef WORKAROUND_BUG6558362
- if(is_daemon) adb_set_affinity();
- #endif
- usb_init();
看下adb_main代码我们先看下init_transport_registration函数
- void init_transport_registration(void)
- {
- int s[2];
-
- if(adb_socketpair(s)){
- fatal_errno("cannot open transport registration socketpair");
- }
- D("socketpair: (%d,%d)", s[0], s[1]);
-
- transport_registration_send = s[0];
- transport_registration_recv = s[1];
-
- fdevent_install(&transport_registration_fde,
- transport_registration_recv,
- transport_registration_func,
- 0);
-
- fdevent_set(&transport_registration_fde, FDE_READ);
- }
调用了socketpair,一端有数据后会调用transport_registration_func函数,我们先来看下什么时候transport_registration_recv会有数据过来,也就要看下transport_registration_send 什么时候会有数据发送。
二、usb、adb的驱动初始化
下面我们再来看下adb驱动的节点的初始化
继续看上面adb_main的usb_init函数:
- void usb_init()
- {
- if (access(USB_FFS_ADB_EP0, F_OK) == 0)
- usb_ffs_init();
- else
- usb_adb_init();
- }
我们这边调用的是usb_adb_init()
- static void usb_adb_init()
- {
- usb_handle* h = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
- if (h == nullptr) fatal("couldn't allocate usb_handle");
-
- h->write = usb_adb_write;
- h->read = usb_adb_read;
- h->kick = usb_adb_kick;
- h->fd = -1;
-
- adb_cond_init(&h->notify, 0);
- adb_mutex_init(&h->lock, 0);
-
-
-
-
-
-
- int fd = unix_open("/dev/android_adb_enable", O_RDWR);
- if (fd < 0) {
- D("failed to open /dev/android_adb_enable\n");
- } else {
- close_on_exec(fd);
- }
-
- D("[ usb_init - starting thread ]\n");
- adb_thread_t tid;
- if(adb_thread_create(&tid, usb_adb_open_thread, h)){
- fatal_errno("cannot create usb thread");
- }
- }
这个函数中打开android_adb_enable节点只是enableadb usb而已,之后开了一个线程调用usb_adb_open_thread
- static void *usb_adb_open_thread(void *x)
- {
- struct usb_handle *usb = (struct usb_handle *)x;
- int fd;
-
- while (true) {
-
- adb_mutex_lock(&usb->lock);
- while (usb->fd != -1)
- adb_cond_wait(&usb->notify, &usb->lock);
- adb_mutex_unlock(&usb->lock);
-
- D("[ usb_thread - opening device ]\n");
- do {
-
- fd = unix_open("/dev/android_adb", O_RDWR);
- if (fd < 0) {
-
- fd = unix_open("/dev/android", O_RDWR);
- }
- if (fd < 0) {
- adb_sleep_ms(1000);
- }
- } while (fd < 0);
-
- close_on_exec(fd);
- usb->fd = fd;
-
- D("[ usb_thread - registering device ]\n");
- register_usb_transport(usb, 0, 0, 1);
- }
-
-
- return 0;
- }
这个函数中主要打开adb节点,调用register_usb_transport函数来注册usb传输。
- void register_usb_transport(usb_handle *usb, const char *serial, const char *devpath, unsigned writeable)
- {
- atransport *t = reinterpret_cast<atransport*>(calloc(1, sizeof(atransport)));
- if (t == nullptr) fatal("cannot allocate USB atransport");
- D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
- serial ? serial : "");
- init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM));
- if(serial) {
- t->serial = strdup(serial);
- }
- if(devpath) {
- t->devpath = strdup(devpath);
- }
-
- adb_mutex_lock(&transport_lock);
- t->next = &pending_list;
- t->prev = pending_list.prev;
- t->next->prev = t;
- t->prev->next = t;
- adb_mutex_unlock(&transport_lock);
-
- register_transport(t);
- }
这个函数先调用了init_usb_transport函数,把atransport初始化了,并且把usb_handle也赋给它了,我们主要看下register_transport函数。
- static void register_transport(atransport *transport)
- {
- tmsg m;
- m.transport = transport;
- m.action = 1;
- D("transport: %s registered\n", transport->serial);
- if(transport_write_action(transport_registration_send, &m)) {
- fatal_errno("cannot write transport registration socket\n");
- }
- }
这个函数把atransport 封装起来,传出去了,我们来看下transport_write_action函数,我们注意看第一个参数transport_registration_send就是我们之前的sockpair的send端
transport_write_action函数就是把transport发给transport_registration_recv端。
- static int
- transport_write_action(int fd, struct tmsg* m)
- {
- char *p = (char*)m;
- int len = sizeof(*m);
- int r;
-
- while(len > 0) {
- r = adb_write(fd, p, len);
- if(r > 0) {
- len -= r;
- p += r;
- } else {
- if((r < 0) && (errno == EINTR)) continue;
- D("transport_write_action: on fd %d, error %d: %s\n",
- fd, errno, strerror(errno));
- #if !ADB_HOST
- __android_log_print(ANDROID_LOG_INFO, __FUNCTION__,
- "transport_write_action: on fd %d, error %d: %s\n",
- fd, errno, strerror(errno));
- #endif
- return -1;
- }
- }
- return 0;
- }
这样当读到adb驱动节点后,会把驱动传输的transport传给transport_registration_recv端,接下来我们就看下这块代码。
三、开启线程接受adb数据
还记得我们前面分析的这个函数嘛,当transport_registration_recv有数据时,就会调用transport_registration_func函数
- void init_transport_registration(void)
- {
- int s[2];
-
- if(adb_socketpair(s)){
- fatal_errno("cannot open transport registration socketpair");
- }
- D("socketpair: (%d,%d)", s[0], s[1]);
-
- transport_registration_send = s[0];
- transport_registration_recv = s[1];
-
- fdevent_install(&transport_registration_fde,
- transport_registration_recv,
- transport_registration_func,
- 0);
-
- fdevent_set(&transport_registration_fde, FDE_READ);
- }
我们来看下transport_registration_func这个函数
- static void transport_registration_func(int _fd, unsigned ev, void *data)
- {
- tmsg m;
- adb_thread_t output_thread_ptr;
- adb_thread_t input_thread_ptr;
- int s[2];
- atransport *t;
-
- if(!(ev & FDE_READ)) {
- return;
- }
-
- if(transport_read_action(_fd, &m)) {
- fatal_errno("cannot read transport registration socket");
- }
-
- t = m.transport;
它先调用了transport_read_action来读取transport_registration_recv的数据,也就是之前transport_registration_send发来的adb驱动节点的数据。然后把它保存在t这个变量中。
下面我们再来看看transport_registration_func函数中的另一段代码
- if (t->connection_state != CS_NOPERM) {
-
- t->ref_count = 2;
-
- if(adb_socketpair(s)) {
- fatal_errno("cannot open transport socketpair");
- }
-
- D("transport: %s socketpair: (%d,%d) starting", t->serial, s[0], s[1]);
-
- t->transport_socket = s[0];
- t->fd = s[1];
-
- fdevent_install(&(t->transport_fde),
- t->transport_socket,
- transport_socket_events,
- t);
-
- fdevent_set(&(t->transport_fde), FDE_READ);
-
- if(adb_thread_create(&input_thread_ptr, input_thread, t)){
- fatal_errno("cannot create input thread");
- }
-
- if(adb_thread_create(&output_thread_ptr, output_thread, t)){
- fatal_errno("cannot create output thread");
- }
- }
上面这段代码建立了一对socketpair,然后开启了两个线程,我们来看下这两个线程
3.1 output_thread收adb驱动数据
我们先来看下output_thread这个线程:
- static void *output_thread(void *_t)
- {
- atransport *t = reinterpret_cast<atransport*>(_t);
- apacket *p;
-
- D("%s: starting transport output thread on fd %d, SYNC online (%d)\n",
- t->serial, t->fd, t->sync_token + 1);
- p = get_apacket();
- p->msg.command = A_SYNC;
- p->msg.arg0 = 1;
- p->msg.arg1 = ++(t->sync_token);
- p->msg.magic = A_SYNC ^ 0xffffffff;
- if(write_packet(t->fd, t->serial, &p)) {
- put_apacket(p);
- D("%s: failed to write SYNC packet\n", t->serial);
- goto oops;
- }
-
- D("%s: data pump started\n", t->serial);
- for(;;) {
- p = get_apacket();
- if(t->read_from_remote(p, t) == 0){
-
- if(write_packet(t->fd, t->serial, &p)){
- put_apacket(p);
- D("%s: failed to write apacket to transport\n", t->serial);
- goto oops;
- }
- } else {
- D("%s: remote read failed for transport\n", t->serial);
- put_apacket(p);
- break;
- }
- }
-
- D("%s: SYNC offline for transport\n", t->serial);
- p = get_apacket();
- p->msg.command = A_SYNC;
- p->msg.arg0 = 0;
- p->msg.arg1 = 0;
- p->msg.magic = A_SYNC ^ 0xffffffff;
- if(write_packet(t->fd, t->serial, &p)) {
- put_apacket(p);
- D("%s: failed to write SYNC apacket to transport", t->serial);
- }
-
- oops:
- D("%s: transport output thread is exiting\n", t->serial);
- kick_transport(t);
- transport_unref(t);
- return 0;
- }
这个线程主要是从adb驱动读取数据,然后让socketpair的一端写入 从adb驱动读取的数据。
我们先看下read_from_remote这个函数,跟下如何从adb驱动读取数据的
在之前register_usb_transport的时候先调用了init_usb_transport,来初始化transport的一些函数等。
- void init_usb_transport(atransport *t, usb_handle *h, int state)
- {
- D("transport: usb\n");
- t->close = remote_close;
- t->kick = remote_kick;
- t->read_from_remote = remote_read;
- t->write_to_remote = remote_write;
- t->sync_token = 1;
- t->connection_state = state;
- t->type = kTransportUsb;
- t->usb = h;
-
- #if ADB_HOST
- HOST = 1;
- #else
- HOST = 0;
- #endif
- }
read_from_remote 函数也就是remote_read函数:
- static int remote_read(apacket *p, atransport *t)
- {
- if(usb_read(t->usb, &p->msg, sizeof(amessage))){
- D("remote usb: read terminated (message)\n");
- return -1;
- }
-
- if(check_header(p)) {
- D("remote usb: check_header failed\n");
- return -1;
- }
-
- if(p->msg.data_length) {
- if(usb_read(t->usb, p->data, p->msg.data_length)){
- D("remote usb: terminated (data)\n");
- return -1;
- }
- }
-
- if(check_data(p)) {
- D("remote usb: check_data failed\n");
- return -1;
- }
-
-
- return 0;
- }
在之前usb_adb_init函数中有如下代码:
- static void usb_adb_init()
- {
- usb_handle* h = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
- if (h == nullptr) fatal("couldn't allocate usb_handle");
-
- h->write = usb_adb_write;
- h->read = usb_adb_read;
- h->kick = usb_adb_kick;
- h->fd = -1;
因此最后调用read是调用了usb_adb_read函数,也就是读adb驱动里的内容。
usb_adb_read函数就是调用adb_read读取adb驱动数据,而adb_read就是从h->fd中去读取adb驱动数据。这个h->fd就是前面usb_adb_open_thread函数中打开/dev/android_adb(adb驱动节点)。
- static int usb_adb_read(usb_handle *h, void *data, int len)
- {
- int n;
-
- D("about to read (fd=%d, len=%d)\n", h->fd, len);
- n = adb_read(h->fd, data, len);
- if(n != len) {
- D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
- h->fd, n, errno, strerror(errno));
- for (int i = 0; i < n; i++) {
- char print = (char)*((char*)data + i);
- LOG("%x ", print);
- }
- return -1;
- }
- D("[ done fd=%d ]\n", h->fd);
- return 0;
- }
3.2 output_thread数据发送数据后,处理数据
在output_thread中,读取了adb驱动的数据后,就调用write_packet(t->fd, t->serial, &p)函数,把数据网socketpair的一侧写。
这会导致socketpair的另一侧有数据,另一侧有数据会调用transport_socket_events函数来处理数据
- static void transport_socket_events(int fd, unsigned events, void *_t)
- {
- atransport *t = reinterpret_cast<atransport*>(_t);
- D("transport_socket_events(fd=%d, events=%04x,...)\n", fd, events);
- if(events & FDE_READ){
- apacket *p = 0;
- if(read_packet(fd, t->serial, &p)){
- D("%s: failed to read packet from transport socket on fd %d\n", t->serial, fd);
- } else {
- handle_packet(p, (atransport *) _t);
- }
- }
- }
四、总结
我们主要分析了adb驱动节点初始化,驱动节点开启成功后会开启线程读取adb驱动节点的内容。
处理数据部分我们在下篇博客继续分析。