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