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