Tizen 2.1 base
[sdk/target/sdbd.git] / src / protocol.txt
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 (informational only).
76
77
78 --- OPEN(local-id, 0, "destination") -----------------------------------
79
80 The OPEN message informs the recipient that the sender has a stream
81 identified by local-id that it wishes to connect to the named
82 destination in the message payload.  The local-id may not be zero.
83
84 The OPEN message MUST result in either a READY message indicating that
85 the connection has been established (and identifying the other end) or
86 a CLOSE message, indicating failure.  An OPEN message also implies
87 a READY message sent at the same time.
88
89 Common destination naming conventions include:
90
91 * "tcp:<host>:<port>" - host may be omitted to indicate localhost
92 * "udp:<host>:<port>" - host may be omitted to indicate localhost
93 * "local-dgram:<identifier>"
94 * "local-stream:<identifier>"
95 * "shell" - local shell service
96 * "upload" - service for pushing files across (like aproto's /sync)
97 * "fs-bridge" - FUSE protocol filesystem bridge
98
99
100 --- READY(local-id, remote-id, "") -------------------------------------
101
102 The READY message informs the recipient that the sender's stream
103 identified by local-id is ready for write messages and that it is
104 connected to the recipient's stream identified by remote-id.
105
106 Neither the local-id nor the remote-id may be zero. 
107
108 A READY message containing a remote-id which does not map to an open
109 stream on the recipient's side is ignored.  The stream may have been
110 closed while this message was in-flight.
111
112 The local-id is ignored on all but the first READY message (where it
113 is used to establish the connection).  Nonetheless, the local-id MUST
114 not change on later READY messages sent to the same stream.
115
116
117
118 --- WRITE(0, remote-id, "data") ----------------------------------------
119
120 The WRITE message sends data to the recipient's stream identified by
121 remote-id.  The payload MUST be <= maxdata in length.
122
123 A WRITE message containing a remote-id which does not map to an open
124 stream on the recipient's side is ignored.  The stream may have been
125 closed while this message was in-flight.
126
127 A WRITE message may not be sent until a READY message is received.
128 Once a WRITE message is sent, an additional WRITE message may not be
129 sent until another READY message has been received.  Recipients of
130 a WRITE message that is in violation of this requirement will CLOSE
131 the connection.
132
133
134 --- CLOSE(local-id, remote-id, "") -------------------------------------
135
136 The CLOSE message informs recipient that the connection between the
137 sender's stream (local-id) and the recipient's stream (remote-id) is
138 broken.  The remote-id MUST not be zero, but the local-id MAY be zero
139 if this CLOSE indicates a failed OPEN.
140
141 A CLOSE 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
143 already been closed by the recipient while this message was in-flight.
144
145 The recipient should not respond to a CLOSE message in any way.  The
146 recipient should cancel pending WRITEs or CLOSEs, but this is not a
147 requirement, since they will be ignored.
148
149
150 --- SYNC(online, sequence, "") -----------------------------------------
151
152 The SYNC message is used by the io pump to make sure that stale
153 outbound messages are discarded when the connection to the remote side
154 is broken.  It is only used internally to the bridge and never valid
155 to send across the wire.  
156
157 * when the connection to the remote side goes offline, the io pump 
158   sends a SYNC(0, 0) and starts discarding all messages
159 * when the connection to the remote side is established, the io pump
160   sends a SYNC(1, token) and continues to discard messages
161 * when the io pump receives a matching SYNC(1, token), it once again
162   starts accepting messages to forward to the remote side
163
164
165 --- message command constants ------------------------------------------
166
167 #define A_SYNC 0x434e5953
168 #define A_CNXN 0x4e584e43
169 #define A_OPEN 0x4e45504f
170 #define A_OKAY 0x59414b4f
171 #define A_CLSE 0x45534c43
172 #define A_WRTE 0x45545257
173
174
175
176 --- implementation details ---------------------------------------------
177
178 The core of the bridge program will use three threads.  One thread
179 will be a select/epoll loop to handle io between various inbound and
180 outbound connections and the connection to the remote side.
181
182 The remote side connection will be implemented as two threads (one for
183 reading, one for writing) and a datagram socketpair to provide the
184 channel between the main select/epoll thread and the remote connection
185 threadpair.  The reason for this is that for usb connections, the
186 kernel interface on linux and osx does not allow you to do meaningful
187 nonblocking IO.
188
189 The endian swapping for the message headers will happen (as needed) in
190 the remote connection threadpair and that the rest of the program will
191 always treat message header values as native-endian.
192
193 The bridge program will be able to have a number of mini-servers
194 compiled in.  They will be published under known names (examples
195 "shell", "fs-bridge", etc) and upon receiving an OPEN() to such a
196 service, the bridge program will create a stream socketpair and spawn
197 a thread or subprocess to handle the io.
198
199
200 --- simplified / embedded implementation -------------------------------
201
202 For limited environments, like the bootloader, it is allowable to
203 support a smaller, fixed number of channels using pre-assigned channel
204 ID numbers such that only one stream may be connected to a bootloader
205 endpoint at any given time.  The protocol remains unchanged, but the
206 "embedded" version of it is less dynamic.
207
208 The bootloader will support two streams.  A "bootloader:debug" stream,
209 which may be opened to get debug messages from the bootloader and a 
210 "bootloader:control", stream which will support the set of basic 
211 bootloader commands.
212
213 Example command stream dialogues:  
214   "flash_kernel,2515049,........\n" "okay\n" 
215   "flash_ramdisk,5038,........\n" "fail,flash write error\n" 
216   "bogus_command......" <CLOSE>
217
218
219 --- future expansion ---------------------------------------------------
220
221 I plan on providing either a message or a special control stream so that
222 the client device could ask the host computer to setup inbound socket
223 translations on the fly on behalf of the client device.
224
225
226 The initial design does handshaking to provide flow control, with a
227 message flow that looks like:
228
229   >OPEN <READY >WRITE <READY >WRITE <READY >WRITE <CLOSE
230
231 The far side may choose to issue the READY message as soon as it receives
232 a WRITE or it may defer the READY until the write to the local stream
233 succeeds.  A future version may want to do some level of windowing where
234 multiple WRITEs may be sent without requiring individual READY acks.
235
236 ------------------------------------------------------------------------
237
238 --- smartsockets -------------------------------------------------------
239
240 Port 5037 is used for smart sockets which allow a client on the host
241 side to request access to a service in the host sdb daemon or in the
242 remote (device) daemon.  The service is requested by ascii name,
243 preceeded by a 4 digit hex length.  Upon successful connection an
244 "OKAY" response is sent, otherwise a "FAIL" message is returned.  Once
245 connected the client is talking to that (remote or local) service.
246
247 client: <hex4> <service-name>
248 server: "OKAY"
249
250 client: <hex4> <service-name>
251 server: "FAIL" <hex4> <reason>
252