ANDROID-QEMUD.TXT revision 871da2aa80687142bec00ef7c1112253c76c32bb
1                    THE ANDROID "QEMUD" MULTIPLEXING DAEMON
2
3I. Overview:
4------------
5
6The Android system image includes a small daemon program named "qemud"
7which is started at boot time. Its purpose is to provide a multiplexing
8communication channel between the emulated system and the emulator program
9itself.
10
11Its goal is to allow certain parts of the system to talk directly to the
12emulator without requiring special kernel support; this simplifies a lot of
13things since it does *not* require:
14
15- writing/configuring a specific kernel driver
16- writing the corresponding hardware emulation code in hw/goldfish_xxxx.c
17- dealing with device allocation and permission issues in the emulated system
18
19The emulator provides 'services' to various parts of the emulated system.
20Each service is identified by a name and serves a specific purpose. For
21example:
22
23   "gsm"       Used to communicate with the emulated GSM modem with
24               AT commands.
25
26   "gps"       Used to receive NMEA sentences broadcasted from the
27               emulated GPS device.
28
29   "sensors"   Used to list the number of emulated sensors, as well as
30               enable/disable reception of specific sensor events.
31
32   "control"   Used to control misc. simple emulated hardware devices
33               (e.g. vibrator, leds, LCD backlight, etc...)
34
35
36II. Implementation:
37-------------------
38
39Since the "cupcake" platform, this works as follows:
40
41- A 'qemud client' is any part of the emulated system that wants to talk
42  to the emulator. It does so by:
43
44  - connecting to the /dev/socket/qemud Unix domain socket
45  - sending the service name through the socket
46  - receives two bytes of data, which will be "OK" in case of
47    success, or "KO" in case of failure.
48
49  After an OK, the same connection can be used to talk directly to the
50  corresponding service.
51
52
53- The /dev/socket/qemud Unix socket is created by init and owned by the
54  'qemud' daemon started at boot by /system/etc/init.goldfish.rc
55
56  The daemon also opens an emulated serial port (e.g. /dev/ttyS1) and
57  will pass all messages between clients and emulator services. Thus,
58  everything looks like the following:
59
60
61     emulator <==serial==> qemud <---> /dev/socket/qemud <-+--> client1
62                                                           |
63                                                           +--> client2
64
65  A very simple multiplexing protocol is used on the serial connection:
66
67           offset    size    description
68
69               0       2     2-char hex string giving the destination or
70                             source channel
71
72               2       4     4-char hex string giving the payload size
73
74               6       n     the message payload
75
76  Where each client gets a 'channel' number allocated by the daemon
77  at connection time.
78
79  Note that packets larger than 65535 bytes cannot be sent directly
80  through the qemud channel. This is intentional; for large data
81  communication, the client and service should use a fragmentation
82  convention that deals with this.
83
84  Zero-sized packets are silently discard by qemud and the emulator and
85  should normally not appear on the serial port.
86
87  Channel 0 is reserved for control messages between the daemon and the
88  emulator. These are the following:
89
90    - When a client connects to /dev/socket/qemud and sends a service
91      name to the daemon, the later sends to the emulator:
92
93        connect:<service>:<id>
94
95      where <service> is the service name, and <id> is a 2-hexchar string
96      giving the allocated channel index for the client.
97
98
99    - The emulator can respond in case of success with:
100
101        ok:connect:<id>
102
103      or, in case of failure, with:
104
105        ok:connect:<id>:<reason>
106
107      where <reason> is a liberal string giving the reason for failure.
108      It is never sent to clients (which will only receive a "KO") and
109      is used strictly for debugging purposes.
110
111    - After a succesful connect, all messages between the client and
112      the corresponding emulator service will be passed through the
113      corresponding numbered channel.
114
115      But if the client disconnects from the socket, the daemon will
116      send through channel 0 this message to the emulator:
117
118        disconnect:<id>
119
120    - If an emulator service decides, for some reason, to disconnect
121      a client, the emulator will send to the daemon (on channel 0):
122
123        disconnect:<id>
124
125      The daemon deals with this gracefully (e.g. it will wait that the
126      client has read all buffered data in the daemon before closing the
127      socket, to avoid packet loss).
128
129    - Any other command sent from the daemon to the emulator will result
130      in the following answer:
131
132        ko:bad command
133
134- Which exact serial port to open is determined by the emulator at startup
135  and is passed to the system as a kernel parameter, e.g.:
136
137        android.qemud=ttyS1
138
139
140- The code to support services and their clients in the emulator is located
141  in android/hw-qemud.c. This code is heavily commented.
142
143  The daemon's source is in $ROOT/development/emulator/qemud/qemud.c
144
145  The header in $ROOT/hardware/libhardware/include/hardware/qemud.h
146  can be used by clients to ease connecting and talking to QEMUD-based
147  services.
148
149  This is used by $ROOT/developement/emulator/sensors/sensors_qemu.c which
150  implements emulator-specific sensor support in the system by talking to
151  the "sensors" service provided by the emulator (if available).
152
153  Code in $ROOT/hardware/libhardware_legacy also uses QEMUD-based services.
154
155
156- Certain services also implement a simple framing protocol when exchanging
157  messages with their clients. The framing happens *after* serial port
158  multiplexing and looks like:
159
160           offset    size    description
161
162               0       4     4-char hex string giving the payload size
163
164               4       n     the message payload
165
166  This is needed because the framing protocol used on the serial port is
167  not preserved when talking to clients through /dev/socket/qemud.
168
169  Certain services do not need it at all (GSM, GPS) so it is optional and
170  must be used depending on which service you talk to by clients.
171
172
173III. Legacy 'qemud':
174--------------------
175
176The system images provided by the 1.0 and 1.1 releases of the Android SDK
177implement an older variant of the qemud daemon that uses a slightly
178different protocol to communicate with the emulator.
179
180This is documented here since this explains some subtleties in the
181implementation code of android/hw-qemud.c
182
183The old scheme also used a serial port to allow the daemon and the emulator
184to communicate. However, the multiplexing protocol swaps the position of
185'channel' and 'length' in the header:
186
187           offset    size    description
188
189               0       4     4-char hex string giving the payload size
190
191               4       2     2-char hex string giving the destination or
192                             source channel
193
194               6       n     the message payload
195
196Several other differences, best illustrated by the following graphics:
197
198    emulator <==serial==> qemud <-+--> /dev/socket/qemud_gsm <--> GSM client
199                                  |
200                                  +--> /dev/socket/qemud_gps <--> GPS client
201                                  |
202                                  +--> /dev/socket/qemud_control <--> client(s)
203
204Now, for the details:
205
206 - instead of a single /dev/socket/qemud, init created several Unix domain
207   sockets, one per service:
208
209        /dev/socket/qemud_gsm
210        /dev/socket/qemud_gps
211        /dev/socket/qemud_control
212
213   note that there is no "sensors" socket in 1.0 and 1.1
214
215 - the daemon created a de-facto numbered channel for each one of these
216   services, even if no client did connect to it (only one client could
217   connect to a given service at a time).
218
219 - at startup, the emulator does query the channel numbers of all services
220   it implements, e.g. it would send *to* the daemon on channel 0:
221
222        connect:<service>
223
224   where <service> can be one of "gsm", "gps" or "control"
225
226   (Note that on the current implementation, the daemon is sending connection
227   messages to the emulator instead).
228
229 - the daemon would respond with either:
230
231        ok:connect:<service>:<hxid>
232
233   where <service> would be the service name, and <hxid> a 4-hexchar channel
234   number (NOTE: 4 chars, not 2). Or with:
235
236        ko:connect:bad name
237
238
239This old scheme was simpler to implement in both the daemon and the emulator
240but lacked a lot of flexibility:
241
242  - adding a new service required to modify /system/etc/init.goldfish.rc
243    as well as the daemon source file (which contained a hard-coded list
244    of sockets to listen to for client connections).
245
246  - only one client could be connected to a given service at a time,
247    except for the GPS special case which was a unidirectionnal broadcast
248    by convention.
249
250The current implementation moves any service-specific code to the emulator,
251only uses a single socket and allows concurrent clients for a all services.
252
253
254IV. State snapshots:
255--------------------
256
257Support for snapshots relies on the symmetric qemud_*_save and qemud_*_load 
258functions which save the state of the various Qemud* structs defined in
259android/hw-qemud.c. The high-level process is as follows.
260
261When a snapshot is made, the names and configurations of all services are
262saved. Services can register a custom callback, which is invoked at this point
263to allow saving of service-specific state. Next, clients are saved following
264the same pattern. We save the channel id and the name of service they are
265registered to, then invoke a client-specific callback.
266
267When a snapshot is restored, the first step is to check whether all services
268that were present when the snapshot was made are available. There is currently
269no functionality to start start missing services, so loading fails if a service
270is not present. If all services are present, callbacks are used to restore
271service-specific state.
272
273Next, all active clients are shut down. Information from the snapshot is used
274to start new clients for the services and channels as they were when the
275snapshot was made. This completes the restore process.
276