分类: LINUX
2011-06-10 19:41:41
比如push 一个文件, adb push '/xxx//xxxxx.xxx' mode 100644
从device 端分析下通讯过程中包的传输过程:
A_XXXX message 总是24byte长,结构如下:
=>A_XXXX :表示从host 发过来
A_XXXX=> : 表示device 发出去
----------------------------------------------------------------------------
=>A_OPEN 24byte
DATA 6byte ==>(sync:\0)
(handle A_OPEN packet 的最后s->ready(s),来通
知device ,
自己可以接收,后续都是主动发A_OKAY来实现)
----------------------------------------------------------------------------
A_OKAY=> 24byte
(transport层发send_packet)
-----------------------------------------------------------------------------
=>A_WRTE
DATA 8byte ==>+size
struct {
unsigned id; ==>'STAT'
unsigned namelen;==>后续路径名长度'/xxx/' 5byte
} req;
------------------------------------------------------------------------------
A_OKAY=> 24byte
(transport层发send_packet)
----------------------------------------------------------------------------
(service 层writex发xxx目录的stat)
A_WRTE=>
DATA 16byte
struct {
('STAT')<== unsigned id;
unsigned mode;
unsigned size;
unsigned time;
} stat;
----------------------------------------------------------------------------
A_OKAY=> 24byte
(可以看出host ,devie 收到A_WRTE 后必须回A_OKAY)
----------------------------------------------------------------------------
(开始发文件)
=>A_WRTE 24byte
DATA 8byte
struct {
unsigned id; ==>'SEND' id
unsigned namelen; ==>file name size +mode size( 16+8=22byte)
} req;
------------------------------------------------------------------------------
A_OKAY=> 24byte
(transport层发send_packet)
------------------------------------------------------------------------------
(进入handle_send_file)
=>A_WRTE 24byte
DATA 4096byte (包括下面22byte+data struct + left data)
22byte namelen ==> file name+mode(include path)
struct { ==> syncmsg
unsigned id; ==>'DATA' id
unsigned size; ==>data size 65536byte
} data;
left data ==>4096-22-8 byte
------------------------------------------------------------------------------
A_OKAY=> 24byte
(transport层发send_packet)
-------------------------------------------------------------------------------
(下面开始是 纯data )
=>A_WRTE 24byte
DATA 4096byte
file data ==>4096
------------------------------------------------------------------------------
A_OKAY=> 24byte
(transport层发send_packet)
--------------------------------------------------------------------------------
..... (host重复发=>A_WRTE 纯data) (device 重复A_OKAY=>)
--------------------------------------------------------------------------------
(到msg过来时满了64k 注意最大64K 需要重新发DATA syncmsg)
=>A_WRTE 24byte
DATA 4096byte (同时一个消息最大4K data)
22byte data ==> file data
struct {
unsigned id; ==>'DATA' id
unsigned size; ==>data size 65536byte
} data;
left data ==>4096-22-8 byte
---------------------------------------------------------------------------------
.... (一直到文件内容发完)
---------------------------------------------------------------------------------
(收到DONE id msg ,跳出handle_send_file循环)
=>A_WRTE 24byte
DATA 8byte
struct {
unsigned id; ==>'DONE' id
unsigned size; ==>timestamp 4byte
} data;
---------------------------------------------------------------------------------
devie 发ID_OKAY (注意不是A_OKAY)
A_WRTE=> 24byte
DATA 8byte
struct {
unsigned id;==>'ID_OKAY'
unsigned msglen; ==>0
} status;
---------------------------------------------------------------------------------
=>A_OKAY 24byte 后面无DATA
---------------------------------------------------------------------------------
=>A_WRTE 24byte
DATA 8byte
struct {
unsigned id; ==>'QUIT' id
unsigned namelen; ==>0
} req;
----------------------------------------------------------------------------------
A_OKAY=> 24byte
(transport层发send_packet)
----------------------------------------------------------------------------------
=>A_CLSE 24byte
通讯发生在socket 层和transport 层 :
socket 是在service 层面的通讯
transport是在设备端口层面的通讯
第1层socket pair 用于 设备注册,注册过程在thread中,device kick 来触发
第2层socket pair 用于 设备通讯,主要是包的通讯,6大消息包的handle:
CONNECT(version, maxdata, "system-identity-string")
OPEN(local-id, 0, "destination")
READY(local-id, remote-id, "")
WRITE(0, remote-id, "data")
CLOSE(local-id, remote-id, "")
SYNC(online, sequence, "")
第3层socket pair 用于 service 通讯,是实际功能的通讯 ,不包含包头,打包过程在第2层socketpair 完成
local_socket_event_func 是由A_WRTE收到后enqueue 时驱动write,并且由收到A_OKAY 消息驱动read