blob: 6415a47c8b221d1801c639e1154fded731adfc79 [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
95 where <service> is the service name, and <id> is a 4-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. Besides, the same multiplexing protocol was used to pass
185messages through multiple channels. However, several other differences
186exist, best illustrated by the following graphics:
187
188 emulator <==serial==> qemud <-+--> /dev/socket/qemud_gsm <--> GSM client
189 |
190 +--> /dev/socket/qemud_gps <--> GPS client
191 |
192 +--> /dev/socket/qemud_control <--> client(s)
193
194Now, for the details:
195
196 - instead of a single /dev/socket/qemud, init created several Unix domain
197 sockets, one per service:
198
199 /dev/socket/qemud_gsm
200 /dev/socket/qemud_gps
201 /dev/socket/qemud_control
202
203 note that there is no "sensors" socket in 1.0 and 1.1
204
205 - the daemon created a de-facto numbered channel for each one of these
206 services, even if no client did connect to it (only one client could
207 connect to a given service at a time).
208
209 - at startup, the emulator does query the channel numbers of all services
210 it implements, e.g. it would send *to* the daemon on channel 0:
211
212 connect:<service>
213
214 where <service> can be one of "gsm", "gps" or "control"
215
216 (Note that on the current implementation, the daemon is sending connection
217 messages to the emulator instead).
218
219 - the daemon would respond with either:
220
221 ok:connect:<service>:<hxid>
222
223 where <service> would be the service name, and <hxid> a 4-hexchar channel
224 number (NOTE: 4 chars, not 2). Or with:
225
226 ko:connect:bad name
227
228
229This old scheme was simpler to implement in both the daemon and the emulator
230but lacked a lot of flexibility:
231
232 - adding a new service required to modify /system/etc/init.goldfish.rc
233 as well as the daemon source file (which contained a hard-coded list
234 of sockets to listen to for client connections).
235
236 - only one client could be connected to a given service at a time,
237 except for the GPS special case which was a unidirectionnal broadcast
238 by convention.
239
240The current implementation moves any service-specific code to the emulator,
241only uses a single socket and allows concurrent clients for a all services.