protocol.txt 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. --- a replacement for aproto -------------------------------------------
  2. When it comes down to it, aproto's primary purpose is to forward
  3. various streams between the host computer and client device (in either
  4. direction).
  5. This replacement further simplifies the concept, reducing the protocol
  6. to an extremely straightforward model optimized to accomplish the
  7. forwarding of these streams and removing additional state or
  8. complexity.
  9. The host side becomes a simple comms bridge with no "UI", which will
  10. be used by either commandline or interactive tools to communicate with
  11. a device or emulator that is connected to the bridge.
  12. The protocol is designed to be straightforward and well-defined enough
  13. that if it needs to be reimplemented in another environment (Java
  14. perhaps), there should not problems ensuring perfect interoperability.
  15. The protocol discards the layering aproto has and should allow the
  16. implementation to be much more robust.
  17. --- protocol overview and basics ---------------------------------------
  18. The transport layer deals in "messages", which consist of a 24 byte
  19. header followed (optionally) by a payload. The header consists of 6
  20. 32 bit words which are sent across the wire in little endian format.
  21. struct message {
  22. unsigned command; /* command identifier constant */
  23. unsigned arg0; /* first argument */
  24. unsigned arg1; /* second argument */
  25. unsigned data_length; /* length of payload (0 is allowed) */
  26. unsigned data_crc32; /* crc32 of data payload */
  27. unsigned magic; /* command ^ 0xffffffff */
  28. };
  29. Receipt of an invalid message header, corrupt message payload, or an
  30. unrecognized command MUST result in the closing of the remote
  31. connection. The protocol depends on shared state and any break in the
  32. message stream will result in state getting out of sync.
  33. The following sections describe the six defined message types in
  34. detail. Their format is COMMAND(arg0, arg1, payload) where the payload
  35. is represented by a quoted string or an empty string if none should be
  36. sent.
  37. The identifiers "local-id" and "remote-id" are always relative to the
  38. *sender* of the message, so for a receiver, the meanings are effectively
  39. reversed.
  40. --- CONNECT(version, maxdata, "system-identity-string") ----------------
  41. The CONNECT message establishes the presence of a remote system.
  42. The version is used to ensure protocol compatibility and maxdata
  43. declares the maximum message body size that the remote system
  44. is willing to accept.
  45. Currently, version=0x01000000 and maxdata=4096
  46. Both sides send a CONNECT message when the connection between them is
  47. established. Until a CONNECT message is received no other messages may
  48. be sent. Any messages received before a CONNECT message MUST be ignored.
  49. If a CONNECT message is received with an unknown version or insufficiently
  50. large maxdata value, the connection with the other side must be closed.
  51. The system identity string should be "<systemtype>:<serialno>:<banner>"
  52. where systemtype is "bootloader", "device", or "host", serialno is some
  53. kind of unique ID (or empty), and banner is a human-readable version
  54. or identifier string. The banner is used to transmit useful properties.
  55. --- AUTH(type, 0, "data") ----------------------------------------------
  56. The AUTH message informs the recipient that authentication is required to
  57. connect to the sender. If type is TOKEN(1), data is a random token that
  58. the recipient can sign with a private key. The recipient replies with an
  59. AUTH packet where type is SIGNATURE(2) and data is the signature. If the
  60. signature verification succeeds, the sender replies with a CONNECT packet.
  61. If the signature verification fails, the sender replies with a new AUTH
  62. packet and a new random token, so that the recipient can retry signing
  63. with a different private key.
  64. Once the recipient has tried all its private keys, it can reply with an
  65. AUTH packet where type is RSAPUBLICKEY(3) and data is the public key. If
  66. possible, an on-screen confirmation may be displayed for the user to
  67. confirm they want to install the public key on the device.
  68. --- OPEN(local-id, 0, "destination") -----------------------------------
  69. The OPEN message informs the recipient that the sender has a stream
  70. identified by local-id that it wishes to connect to the named
  71. destination in the message payload. The local-id may not be zero.
  72. The OPEN message MUST result in either a READY message indicating that
  73. the connection has been established (and identifying the other end) or
  74. a CLOSE message, indicating failure. An OPEN message also implies
  75. a READY message sent at the same time.
  76. Common destination naming conventions include:
  77. * "tcp:<host>:<port>" - host may be omitted to indicate localhost
  78. * "udp:<host>:<port>" - host may be omitted to indicate localhost
  79. * "local-dgram:<identifier>"
  80. * "local-stream:<identifier>"
  81. * "shell" - local shell service
  82. * "upload" - service for pushing files across (like aproto's /sync)
  83. * "fs-bridge" - FUSE protocol filesystem bridge
  84. --- READY(local-id, remote-id, "") -------------------------------------
  85. The READY message informs the recipient that the sender's stream
  86. identified by local-id is ready for write messages and that it is
  87. connected to the recipient's stream identified by remote-id.
  88. Neither the local-id nor the remote-id may be zero.
  89. A READY message containing a remote-id which does not map to an open
  90. stream on the recipient's side is ignored. The stream may have been
  91. closed while this message was in-flight.
  92. The local-id is ignored on all but the first READY message (where it
  93. is used to establish the connection). Nonetheless, the local-id MUST
  94. not change on later READY messages sent to the same stream.
  95. --- WRITE(0, remote-id, "data") ----------------------------------------
  96. The WRITE message sends data to the recipient's stream identified by
  97. remote-id. The payload MUST be <= maxdata in length.
  98. A WRITE message containing a remote-id which does not map to an open
  99. stream on the recipient's side is ignored. The stream may have been
  100. closed while this message was in-flight.
  101. A WRITE message may not be sent until a READY message is received.
  102. Once a WRITE message is sent, an additional WRITE message may not be
  103. sent until another READY message has been received. Recipients of
  104. a WRITE message that is in violation of this requirement will CLOSE
  105. the connection.
  106. --- CLOSE(local-id, remote-id, "") -------------------------------------
  107. The CLOSE message informs recipient that the connection between the
  108. sender's stream (local-id) and the recipient's stream (remote-id) is
  109. broken. The remote-id MUST not be zero, but the local-id MAY be zero
  110. if this CLOSE indicates a failed OPEN.
  111. A CLOSE message containing a remote-id which does not map to an open
  112. stream on the recipient's side is ignored. The stream may have
  113. already been closed by the recipient while this message was in-flight.
  114. The recipient should not respond to a CLOSE message in any way. The
  115. recipient should cancel pending WRITEs or CLOSEs, but this is not a
  116. requirement, since they will be ignored.
  117. --- SYNC(online, sequence, "") -----------------------------------------
  118. The SYNC message is used by the io pump to make sure that stale
  119. outbound messages are discarded when the connection to the remote side
  120. is broken. It is only used internally to the bridge and never valid
  121. to send across the wire.
  122. * when the connection to the remote side goes offline, the io pump
  123. sends a SYNC(0, 0) and starts discarding all messages
  124. * when the connection to the remote side is established, the io pump
  125. sends a SYNC(1, token) and continues to discard messages
  126. * when the io pump receives a matching SYNC(1, token), it once again
  127. starts accepting messages to forward to the remote side
  128. --- message command constants ------------------------------------------
  129. #define A_SYNC 0x434e5953
  130. #define A_CNXN 0x4e584e43
  131. #define A_AUTH 0x48545541
  132. #define A_OPEN 0x4e45504f
  133. #define A_OKAY 0x59414b4f
  134. #define A_CLSE 0x45534c43
  135. #define A_WRTE 0x45545257
  136. --- implementation details ---------------------------------------------
  137. The core of the bridge program will use three threads. One thread
  138. will be a select/epoll loop to handle io between various inbound and
  139. outbound connections and the connection to the remote side.
  140. The remote side connection will be implemented as two threads (one for
  141. reading, one for writing) and a datagram socketpair to provide the
  142. channel between the main select/epoll thread and the remote connection
  143. threadpair. The reason for this is that for usb connections, the
  144. kernel interface on linux and osx does not allow you to do meaningful
  145. nonblocking IO.
  146. The endian swapping for the message headers will happen (as needed) in
  147. the remote connection threadpair and that the rest of the program will
  148. always treat message header values as native-endian.
  149. The bridge program will be able to have a number of mini-servers
  150. compiled in. They will be published under known names (examples
  151. "shell", "fs-bridge", etc) and upon receiving an OPEN() to such a
  152. service, the bridge program will create a stream socketpair and spawn
  153. a thread or subprocess to handle the io.
  154. --- simplified / embedded implementation -------------------------------
  155. For limited environments, like the bootloader, it is allowable to
  156. support a smaller, fixed number of channels using pre-assigned channel
  157. ID numbers such that only one stream may be connected to a bootloader
  158. endpoint at any given time. The protocol remains unchanged, but the
  159. "embedded" version of it is less dynamic.
  160. The bootloader will support two streams. A "bootloader:debug" stream,
  161. which may be opened to get debug messages from the bootloader and a
  162. "bootloader:control", stream which will support the set of basic
  163. bootloader commands.
  164. Example command stream dialogues:
  165. "flash_kernel,2515049,........\n" "okay\n"
  166. "flash_ramdisk,5038,........\n" "fail,flash write error\n"
  167. "bogus_command......" <CLOSE>
  168. --- future expansion ---------------------------------------------------
  169. I plan on providing either a message or a special control stream so that
  170. the client device could ask the host computer to setup inbound socket
  171. translations on the fly on behalf of the client device.
  172. The initial design does handshaking to provide flow control, with a
  173. message flow that looks like:
  174. >OPEN <READY >WRITE <READY >WRITE <READY >WRITE <CLOSE
  175. The far side may choose to issue the READY message as soon as it receives
  176. a WRITE or it may defer the READY until the write to the local stream
  177. succeeds. A future version may want to do some level of windowing where
  178. multiple WRITEs may be sent without requiring individual READY acks.
  179. ------------------------------------------------------------------------
  180. --- smartsockets -------------------------------------------------------
  181. Port 5037 is used for smart sockets which allow a client on the host
  182. side to request access to a service in the host adb daemon or in the
  183. remote (device) daemon. The service is requested by ascii name,
  184. preceeded by a 4 digit hex length. Upon successful connection an
  185. "OKAY" response is sent, otherwise a "FAIL" message is returned. Once
  186. connected the client is talking to that (remote or local) service.
  187. client: <hex4> <service-name>
  188. server: "OKAY"
  189. client: <hex4> <service-name>
  190. server: "FAIL" <hex4> <reason>