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. 10 11 Its goal is to allow certain parts of the system to talk directly to the 12 emulator without requiring special kernel support; this simplifies a lot of 13 things 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 19 The emulator provides 'services' to various parts of the emulated system. 20 Each service is identified by a name and serves a specific purpose. For 21 example: 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 36 II. Implementation: 37 ------------------- 38 39 Since 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 173 III. Legacy 'qemud': 174 -------------------- 175 176 The system images provided by the 1.0 and 1.1 releases of the Android SDK 177 implement an older variant of the qemud daemon that uses a slightly 178 different protocol to communicate with the emulator. 179 180 This is documented here since this explains some subtleties in the 181 implementation code of android/hw-qemud.c 182 183 The old scheme also used a serial port to allow the daemon and the emulator 184 to 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 196 Several 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 204 Now, 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 239 This old scheme was simpler to implement in both the daemon and the emulator 240 but 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 250 The current implementation moves any service-specific code to the emulator, 251 only uses a single socket and allows concurrent clients for a all services. 252