ADB通信

1.ADB Server,ADB Client, ADB Daemon的关系

ADB通信分为两部分:ADB Server和ADB Client;ADB Server和ADB Daemon。

ADB Server:运行在PC上的后台程序,目的是检测USB借口何时连接或者移除设备。ADB Server维护着一个“已连接的设备的链表”,并且为每一个设备标记了一个状态:offline,bootloader,recovery或者online;Server一直在做一些循环和等待,以协调client和Server还有daemon之间的通信。

ADBD(daemon):adbd作为后台进程运行在手机上,所用是连接到adb server(通过USB或者TCP/IP),并且为运行在PC上的client提供一些服务。当手机正确俩捏到PC上,并且adb server能够连接上daemon时,server将手机的状态标记为online,否则为offline,这意味着server发现了一个新设备,但是不能成功连接到daemon。

ADB Client:其实就是shell,用来发送命令给Server。发送命令时,首先检测PC上有没有启动Server,如果后台没有Server,则自动启动一个Server,然后将命令发送到Server,并不关心命令发送过去以后会怎样。目前一个adb就包含了client和server两部分。

三者之间的通信:两条通讯通道。Client<--->Server<---->Daemon。Client发送的命令分为三种:adb version和adb help不经过server处理就能够成功的;和Server通讯但是不需要和手机通讯的命令:adb devices;需要Daemon进行处理的命令。

ADB Server对本地的TCP5037端口进行监听,等待ADB Client的命令。ADB Client每个命令都包含两个部分,前一部分包含固定四个字节,以十六进制的方式指明指令的长度;后一部分才是真正的指令内容;发送命令的借口为writex,最终调用_fh_socket_write,通过send发送出去,因此这两部分至少需要发送两个tcp包。

2.pc端判断怎样和手机进行连接?手机adbd进入哪个模式?

 

PC端的其实只在server启动的时候有一步检测,检测有没有配置环境变量ADBHOST=192.168.100.2。当我们定义了这个环境变量的时候才可以通过TCP/IP来连通手机。server起来以后便不再进行检测,所以当我们定义了这个变量然后再启动server才能连接上手机。但这又牵扯出来一个问题,我们这个时候在运行 sudo adb devices 是找不到设备的,即使在root里面设置了环境变量ADBHOST这条命令也是无法找到设备的。在代码里面加上log可以发现并没有找到这个环境变量,所以还是系统环境变量的问题导致的ADB找不到设备,而不是ADB本身的问题。       其实在进行环境变量的检测以前就进行了usb设备的检测,而且这是fork了一个进程来轮询扫描的,当找到以后就建立连接。所以是可以同时发现物理设备和虚拟设备的。这里说明一下,usb设备是轮询来检测的,但是在发现网络设备的时候只进行了一次循环检测。所以当我们在ADB模式下拔掉手机然后在进入ADB模式还可以发现设备,但是NET模式下则不能发现了。

adbd起来以后进行检测,看/dev目录下有没有 android/android_adb 两个文件,如果有其中一个,则进行ADB模式,那么NET模式将不会进行初始化。注意这里的初始化和PC上是不一样的,PC上是一个顺序结构,而手机上则是一个选择的分支结构。(结尾有简单流程图)

但是这个时候 如果 touch android 或 android_adb. 将会怎么样?

                       i.             NET 模式将不能进入。

                     ii.             创建以后,第一次进如ADB 模式,能够发现设备,但是设备状态是 offline

这是因为adbd在进行文件检测的时候,只进行文件是否存在的检测,而不关心文件的属性。所以当他看到我们touch出来的文件时,不管我们选择哪个模式都会进行adb的初始化,相当于adbd进入了ADB模式, 然而这个时候的ADB模式并不是我们选择ADB时进入的模式,他没有加载adb驱动,反而是加载的NET的驱动,PC设别的不出来USB设备,识别出来的是一个网络设备,这个时候PC端的ADB是废掉的。所以即使配置即使我们发现了usb0,并且配置好usb0和ADBHOST正确,也不能正常连接。这两个节点本应该是 加载 android adb driver时创建的(其实只创建android_adb一个),但是我们人为的创建以后,driver 就不会再次创建,这个空文件没有设备文件收发数据的功能,所以不能正常工作。但是在卸载驱动的时候, 会去删除这个设备文件,所一就把我们touch的文件给删除了,再次进入ADB模式的时候会正常创建。这个时候就又能正常使用ADB模式了。

来看一下这两个文件的一些信息:

-crw-rw---- adb     adb                      android_adb   ----> driver

-rw-rw-rw- root     root                            android_adb   ----> touch

 

Design:

a.      在进行检测文件是否存在的同时检测文件的属性和权限。

b.     驱动加载的时候进行检测看是否有同名文件,有则删除。


3.为什进行adb模式现相连接,第一次运行adb命令要sudo?

当我们执行adb命令的时候几乎都会进行server是否启动的一个检测,如果server没有起来,那么他会起server。这里的sudo其实是用来起server的。也就是说我们要让server拥有root权限。

这是因为server起来以后,要去读写系统创建在/dev/bus/usb下面的设备节点来和phone上的daemon进行通讯。但是这个节点是由root用户创建。普通用户的权限是受到限制的。
       我们可以看一下。首先lsusb来看一下我们的设备。

Bus003 Device 042: ID 18d1:dddd

这就是系统给我们设备创建的节点了,然后找到设备节点进一步看他的一些属性

ls  -l  /dev/bus/usb/003/042

crw-rw-r--   1   root  root  189, 297   2009-11-18   17:15

普通用户运行的adb当然就不能去和设备进行通讯.

              Design:

a.       用chmod 命令来改变节点的读写权限。(当让这是费事不讨好,还不如直接sudo。但是这至少证明是设备节点的读写权限导致的这个问题。

b.      修改系统配置文件,让系统在创建设备节点的时候就允许普通用户有读写权限。但是这个时候潜在一个任何人都能访问节的的安全问题。

c.       从上面可以看到,将本人加入root用户组也可以得到读写的权限。(实用,推荐)


4.  adbd的启动。

      

现在在我们的手机里面只有选择ADB模式或者NET模式的时候mountd才会起 adbd 进程,当拔掉线的时候再杀掉adbd。如果在运行过程中adbd非正常的死掉了,init进程会重新启动adbd。

mountd会选择性的加载驱动,当加载 android adbdriver 以后才启动adbd,因为手机上的adbd起来以后要检测是否有驱动创建的android_adb节点,来判定是否执行usb_init()函数,如果没有就会进行local_init(),如果先启动的adb则不能检测到该节点,所以要这样设计。(下

有简单流程图)

 

Design:

a.       如果让adbd进程长期在系统驻留,不被mountd杀死也可以在加载驱动以后进入adb模式。让adb在作检测的时候不止检测有没有android_adb 节点,另外再进行本地IP有没有正确配置的检测,如果都没有则sleep 2000ms,然后在做检测。

b.      如过我们真的可以去掉NET模式。那么我们可以在先判断一下当前adbd是不是运行在虚拟机里面,如果是就进行NET的初始化,如果不是在虚拟机里面那么就进入ADB模式,这个时候还是要等待驱动的插入,当检测到有驱动节点创建的时候就进行初始化。(我已近在tiger上面进行了改动,测试结果证明是可行的。)

 

5. 安全问题

      

       在我们没有选择 NET 模式,mountd 没有加载配置文件的时候 手机的IP 地址并不是192.168.100.2,即使用WIFI也是没法和手机的 adbd 进行连通的。因为在我们现在的版本中ADB通信是把两个连通的IP写死了的,只有192.168.100.1和192.168.100.2能够进行连同。这就只牵扯到选择NET模式以后的的安全性问题,理论上这个时候WIFI是可以伪造IP 通过 adb只关心数据链路层来连接手机。mountd的design只是保证了ADB模式的正常进入,主要意图并不是来解决安全问题。

 

       Design:

a.       当我们连上线的时候当然是我们最先进入NET模式,黑客是后来进入的。可以让一部手机只让一台电脑连接,当建立连接以后,便不再接受其他的连接请求。是这样的手机上的adbd起来以后是一个等待PC连接的状态,当PC的数据过来以后才会进行连接,然后向管理的链表登记注册,这时候会对该PC 上的socket进行一个ID标识,手机的server就是根据这个来进行通讯的,我们可以设置这个ID标识的第一组,也就是我们连接的PC是合法值,其他为非法,不进行通讯。或者干脆就不对多出来的进行标识,这样就无法通讯。

 

6.      ADB debug 方式。

 

在PC端的log默认下是开启的,但是并不是所有的log都打开的。

在没有更改代码的前提下只记录ADB的启动和关闭 以及PID。

       sudo打开  /tmp/adb.log 可以看到

       我们可以通过更改代码来查看更多log,但是更简单的方式就是设置一个环境变量我们就可以查看更多的log。

       export ADB_TRACE=all或者等于ADB_TRACE= 1

       这个时候在运行adb命令就可以看到更多的log打在屏幕上,当然他们同时也打在了文件中。

       Phone的log 默认情况下是关闭的。

       如果打开的话,其记录在  /data/adb_<time>.txt 文件中。

 

7.      关于版本检测

 

大家都知道我们的系统中只能打开一个server,不管多少 Shell来运行adb都只是和同一个server来通迅,各shell通过连接本地lo的5037端口来和server通讯。所以当我们运行不同版本的时候都是杀的后台的server。

adb 进行版本检测是做的检测pc上的server的版本。只进行了版

              是否一致的检测。只要版本不一致,则会先杀死server然后才提示:

adbserver is out of date.  killing...

而不提示用户现在运行的版本是什么版本,是否真的低于想运行的版本。

             

              Design:

                     a.做进一步的检测。
                     b. 提示用户现在运行版本和将要运行版本的版本号。

 

8.      还是版本检测

 

adb help 和 adb version 这两条命令是不会进行版本检测的,甚至根

本都不关心server是否启动。只实现 help和 version的输出。

 

 

9.      merge adb 的新功能

 

donut并没有更改adb的整个框架,最明显是加了一个新的功能,更

改了一下log的记录方式。

以前的版本中是要输入 adb shellreboot才可以重启手机,现在新加一条命令--->adb reboot.这样就可以直接重启手机。

上面我没说了log的问题,现在donut把手机上的log稍微的改了一点,上面说的是记录在/data/log_<time>.txt中。这个time就是用time函数获得的。但是现在改成了这样。他首先在data下面建立了一个adb的文件夹,然后在其中写的log文件,现在的文件名格式改成了这样--->adb-%Y-%m-%d-%H-%M-%S.txt

Éclair里面有加了一些新的功能。

 

a..adb connect <host>:<port>                     

connectto a device via TCP/IP

b.adb disconnect <host>:<port>                        

disconnectfrom a TCP/IP device

c.adb usb

       restarts the adbd daemon listening on USB

c.       adb tcpip<port>                             

restartsthe adbd daemon listening on TCP on the specified port

 

 





(2-9本人也不太懂,资料不好找,所以就先放这了)

 

 

 

 

 

 

 

 

.

  • 8
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值