Home | History | Annotate | Download | only in docs
      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