Chinaunix首页 | 论坛 | 博客
  • 博客访问: 396045
  • 博文数量: 53
  • 博客积分: 1910
  • 博客等级: 中尉
  • 技术积分: 1130
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-10 14:56
文章分类

全部博文(53)

文章存档

2013年(1)

2012年(17)

2011年(33)

2010年(2)

分类: LINUX

2011-06-17 12:48:55

adb push 文件时host端(server+client)通讯的流程,分析如下:

绿色表示Cleint端

兰色表示Server端                                                                            

红色表示Device端
------------------------------------------------------------------------------
(1) (server)   
     ( socket_loopback_server(tcp:5037 loopback server 监听client连接)
------------------------------------------------------------------------------
(2)                                         (目前为client)
                             ( int fd = _adb_connect(service); )
                          执行socket_loopback_client 去连接server
------------------------------------------------------------------------------
 (3) (server)  
     如果有client 连接交由ss_listener_event_func 处理
    adb_socket_accept 接受连接后进行如下处理:
    * 设置socket buff 大小
    * 用create_local_socket 创建asocket 对象
          并初始化enqueue,ready,close  函数指针local_socket_xxx
          设置asocket 的id, 设置asocket 的fd 为accpeted socket fd
                                                                    (使用该fd 与client 通讯)
    * 设置epoll 等待该accepted socket fd   上FDE READ,WRITE事件
           处理函数为local_socket_event_func
           (注意这时并为设置等待FDE EVENT !!!)
    * 用connect_to_smartsocket 创建一个smart asocket
          ( 注意是smart 不是remote!)
          asocket id 为0  (这是个细节)
          并设置enqueue ,ready ,close 函数为smart_socket_xxx
          设置local ,smart asocket 互为对方peer
          调用下local socket ready,这样local_socket_event_func
             就可以等待到client 发数据过来的fde read event了
------------------------------------------------------------------------------
(4)                          (client)
                             (_adb_connect("sync:"))=>
                             * switch_socket_transport 发送:
                               'xxxx'(msglen)+ 'host:transport-any'
                             * 然后readx 读socket_loopback_client
                                返回的fd  来等待server 应答
------------------------------------------------------------------------------                                                                         
(5) (server)  
      local_socket_event_func 的 fde read  分支读到client 发来的
      'xxxx'(msglen)+ 'host:transport-any'  ,调用
      smart_socket_enqueue (不是remot socket 入队)
        *  收完msg len 指定长度的msg
        * 开始handle_host_request(service='transport-any'
                                  , ttype=kTransportAny
                                  , serial=nll
                                  , s->peer->fd  local socekt 's fd
                                  , s smart asocket 
                    通过acquire_one_transport(CS_ANY, type=kTransportAny,serial,error_string);
                    去从transport_list 上获得一个transport
                       transport_list  是在 usb_init  =>device_poll_thread  中发现usb device
                       插入,或者local_init 通过client_socket_thread 通过ip+port 连上device 后
                       通过register_xxx_transport ,xxx指 usb 或socket,注册时link 到list上的
                       所以注意如果想用tcp 连接时  getenv("ADBHOST") ,要设置ip 地址
                       不过现在仍然假定使用usb transport 并且device 已经插入成功
                       获得一个atransport  成功后,给client 发OKAY
                       并把smart asocket 的atransport 设置为获得的atransport 
         *  handle_host_request 返回时判断service 中用'transport' 字样就
            return 0; 退出enqueue    
-------------------------------------------------------------------------------------
(6)                    (client)
                       等到server 发来的okay ,开始通过
                       loopback client socket fd 发
                       'xxxx'(len)+ 'sync:'
-------------------------------------------------------------------------------------
(7) (server)  
local_socket_event_func 中如果enqueue 返回>0 才会
delete FDE_READ,前面(5)楼enqueue 退出为return 0,
所以条件不满足, 仍然可以触发
又到了local_socket_event_func 的 fde read  分支!!!
收到'xxxx'(msglen)+ 'sync:'  调用
smart_socket_enqueue 入队
          由于msg 中没有任何host 字样就直接去设置
          local asocket 的ready ,改为local_socket_ready_notify,
                  主要为回应client OKAY 做个过度,所有又设回
                  local_socket_ready (notify 做了下二传手的作用)

          close 设为local_socket_close_notify 重设为local_socket_close_notify
                  和上面一样主要是回应 client  "closed",然后设回

          s->peer->peer = 0;  将local asocket 的peer端由smart socket 改为0      
             (local asocket 与smart socket 现在断开了)

          connect_to_remote(smart ascoket,'sync:'); 去向目前还挂在
          smart asocket 上的usb transport 发6大message 之一个的
          A_OPEN 去open sync service

          (注意smart asocket 获得见5楼倒数第3行,虽然和loc sock断开了,不过还有利用价值)
-------------------------------------------------------------------------------------
(8)
(device)
device 收到open sycn 后打开sync service
然后给host 端发A_OKAY
(具体见ADB push 文件通讯包的device端分析 )
-------------------------------------------------------------------------------------
(9)
(server)
server 端 收到A_OKAY 后handle_packet  处理A_OKAY
(具体ADB push 文件通讯包的device端分析)
因为前面local asocket 与smart ascoket 断开时设置
* s->peer->peer = 0 ;  (peer的peer 一定不要昏,见前面(7)楼解释)
* 所以create_remote_socket(device asocket id, usb atransport->transport register时获得)
                 * 设置 新创建的remote asocket 的enqueue,ready,close ,disconnet 等func pt
* 将刚才和smart asocket 断开的local asocket 连到remote asocket
      (就是这句s->peer->peer = s;)

*  调ready   (那个ready ???  ;)  )
    local_socket_ready_notify ,这个ready 2传下到
    local_socket_ready(close)  ,然后给client 回个OKAY , 
    然后再s->ready(s); (那个ready???)
    local_sokcet_ready ,设置fde_read, (这句很关键!!!)
    
    回头看下client ,它发完sync  还挂着adb_status 等OKAY,
    现在轮到client 了
-------------------------------------------------------------------------------------   
(10)                              (目前为client)  
                                    adb connet sync:成功返回loopback
                                    client socket fd 后开始发文件了
                                    sync_send(fd=> loop back client sfd
                                          *  发ID_SEND + filename +file mode 's len
                                          *  write_data_file
                                                 发ID_DATA + size + file data (最大64K)
                                          (这里和下面是交叉执行)
      
-------------------------------------------------------------------------------------
(11)
(server)
(9)楼提到的关键句s->ready(s) 起作用了
加上client 的write ,激发了
local_socket_event_func 去处理分支FDE_READ
     * 读loopbake server socket  fd 获得client 发来的数据
     * s->peer->enqueue =>现在enqueue 是remote 了, 不是smart
        这就是前面local, smart 断开时做的
        (见上面处理A_OKAY 时create_remote_socket 做的)
        enqueue => remote_socket_enqueue  
                          向device 发A_WRTE (通过usb transport
                          send_packet出去)
local_socket_event_func => FDE_READ => adb_read(fd, x, avail)
的avail 是4096,所以实际usb 上一次write max 4096
-------------------------------------------------------------------------------------
(12)
(device)
由于ADB push 文件通讯包的device 端分析中已经
讲过device 端,所以省略
但是每次device 处理A_write 后都回A_OKAY
-------------------------------------------------------------------------------------
(server)
又回到server 端处理A_OKAY,和上面(9)楼一样处理
一直又处理到(12)楼
直到文件内容发完
-------------------------------------------------------------------------------------
(13)                              (目前为client)    
                                    发ID_DONE + mtime
                                    然后等server 回OKAY
-------------------------------------------------------------------------------------                                   
(目前为server)
这部分和(11)楼处理过程一样,因为省略分析devcie 端
但也是由s->ready  + client 写sfd 激发local_socket_event_func 开始的
最后server 通过local_socket_ready_notify 回应 client OKAY
-------------------------------------------------------------------------------------
(14)                             (client)    

                                   收到OKAY  
                                   sync_quit =>
                                   发ID_QUIT
-------------------------------------------------------------------------------------
(15)
(server)
已经基本没client 的事情了
server local_socket_event_func 上最后一 次 去处理分支FDE_READ
 r = adb_read(fd, x, avail);  r 返回0
 is_eof成立
执行 s->close(s); =>local_socket_close_notify
 直接贴代码

  1. static void local_socket_close_notify(asocket *s)
  2. {
  3.     s->ready = local_socket_ready;
  4.     s->close = local_socket_close;
  5.     sendfailmsg(s->fd, "closed");
  6.     s->close(s); ===> local_socket_ready 发A_CLSE
  7. }


 -------------------------------------------------------------------------------------
(16)
如device 端分析中最后收到A_CLSE
结束


其他

           
server 端对非host 命令的转发类似与一个单刀双掷开关


                      fd(loopback sfd) <---------------->  (client)
                             |                                                                     
                            fde (local_socket_event_func)
                         (2) |(1)
  (device handle)             \                     (server handle) 
 (remote enqueue)  <------>    <----------------->(smart enqueue
)
 开始连着client ,接收到非host 命令,发A_OPEN 打开device service 后
 开关连到(2)一头,以后enqueue 就是remote 了,就发给了device

  两路 :一路client 经过(1) 到server handle

       另一路client 经过(2)到device handle

                                                   
                       
  

 

阅读(5035) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~