blob: 7841399e19f02ec28ac4e5869f665094791cef5e [file] [log] [blame]
David Turner47356942009-04-05 14:23:06 -07001 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
David Turner94088e22009-04-14 14:46:08 -070095 where <service> is the service name, and <id> is a 2-hexchar string
David Turner47356942009-04-05 14:23:06 -070096 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
David Turner94088e22009-04-14 14:46:08 -0700184to 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:
David Turner47356942009-04-05 14:23:06 -0700197
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.
Ot ten Thije871da2a2010-09-20 10:29:22 +0100252
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.