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.
     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