• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2007-2008 The Android Open Source Project
2 **
3 ** This software is licensed under the terms of the GNU General Public
4 ** License version 2, as published by the Free Software Foundation, and
5 ** may be copied, distributed, and modified under those terms.
6 **
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 ** GNU General Public License for more details.
11 */
12 #include "android/hw-qemud.h"
13 #include "android/utils/debug.h"
14 #include "android/utils/misc.h"
15 #include "android/utils/system.h"
16 #include "android/utils/bufprint.h"
17 #include "android/looper.h"
18 #include "hw/hw.h"
19 #include "hw/goldfish_pipe.h"
20 #include "qemu-char.h"
21 #include "charpipe.h"
22 #include "cbuffer.h"
23 
24 #define  D(...)    VERBOSE_PRINT(qemud,__VA_ARGS__)
25 #define  D_ACTIVE  VERBOSE_CHECK(qemud)
26 
27 /* the T(...) macro is used to dump traffic */
28 #define  T_ACTIVE   0
29 
30 #if T_ACTIVE
31 #define  T(...)    VERBOSE_PRINT(qemud,__VA_ARGS__)
32 #else
33 #define  T(...)    ((void)0)
34 #endif
35 
36 /* max serial MTU. Don't change this without modifying
37  * development/emulator/qemud/qemud.c as well.
38  */
39 #define  MAX_SERIAL_PAYLOAD        4000
40 
41 /* max framed data payload. Must be < (1 << 16)
42  */
43 #define  MAX_FRAME_PAYLOAD  65535
44 
45 /* Version number of snapshots code. Increment whenever the data saved
46  * or the layout in which it is saved is changed.
47  */
48 #define QEMUD_SAVE_VERSION 2
49 
50 #define min(a, b) (((a) < (b)) ? (a) : (b))
51 
52 
53 /* define SUPPORT_LEGACY_QEMUD to 1 if you want to support
54  * talking to a legacy qemud daemon. See docs/ANDROID-QEMUD.TXT
55  * for details.
56  */
57 #ifdef TARGET_ARM
58 #define  SUPPORT_LEGACY_QEMUD  1
59 #endif
60 #ifdef TARGET_I386
61 #define  SUPPORT_LEGACY_QEMUD  0 /* no legacy support */
62 #endif
63 #if SUPPORT_LEGACY_QEMUD
64 #include "telephony/android_modem.h"
65 #include "telephony/modem_driver.h"
66 #endif
67 
68 /*
69  *  This implements support for the 'qemud' multiplexing communication
70  *  channel between clients running in the emulated system and 'services'
71  *  provided by the emulator.
72  *
73  *  For additional details, please read docs/ANDROID-QEMUD.TXT
74  *
75  */
76 
77 /*
78  * IMPLEMENTATION DETAILS:
79  *
80  * We use one charpipe to connect the emulated serial port to the 'QemudSerial'
81  * object. This object is used to receive data from the serial port, and
82  * unframe messages (i.e. extract payload length + channel id from header,
83  * then the payload itself), before sending them to a generic receiver.
84  *
85  * The QemudSerial object can also be used to send messages to the daemon
86  * through the serial port (see qemud_serial_send())
87  *
88  * The multiplexer is connected to one or more 'service' objects.
89  * are themselves connected through a charpipe to an emulated device or
90  * control sub-module in the emulator.
91  *
92  *  tty <==charpipe==> QemudSerial ---> QemudMultiplexer ----> QemudClient
93  *                          ^                                      |
94  *                          |                                      |
95  *                          +--------------------------------------+
96  *
97  */
98 
99 /** HANDLING INCOMING DATA FRAMES
100  **/
101 
102 /* A QemudSink is just a handly data structure that is used to
103  * read a fixed amount of bytes into a buffer
104  */
105 typedef struct QemudSink {
106     int       used;  /* number of bytes already used */
107     int       size;  /* total number of bytes in buff */
108     uint8_t*  buff;
109 } QemudSink;
110 
111 /* save the state of a QemudSink to a snapshot.
112  *
113  * The buffer pointer is not saved, since it usually points to buffer
114  * fields in other structs, which have save functions themselves. It
115  * is up to the caller to make sure the buffer is correctly saved and
116  * restored.
117  */
118 static void
qemud_sink_save(QEMUFile * f,QemudSink * s)119 qemud_sink_save(QEMUFile* f, QemudSink* s)
120 {
121     qemu_put_be32(f, s->used);
122     qemu_put_be32(f, s->size);
123 }
124 
125 /* load the state of a QemudSink from a snapshot.
126  */
127 static int
qemud_sink_load(QEMUFile * f,QemudSink * s)128 qemud_sink_load(QEMUFile* f, QemudSink* s)
129 {
130     s->used = qemu_get_be32(f);
131     s->size = qemu_get_be32(f);
132     return 0;
133 }
134 
135 
136 /* reset a QemudSink, i.e. provide a new destination buffer address
137  * and its size in bytes.
138  */
139 static void
qemud_sink_reset(QemudSink * ss,int size,uint8_t * buffer)140 qemud_sink_reset( QemudSink*  ss, int  size, uint8_t*  buffer )
141 {
142     ss->used = 0;
143     ss->size = size;
144     ss->buff = buffer;
145 }
146 
147 /* try to fill the sink by reading bytes from the source buffer
148  * '*pmsg' which contains '*plen' bytes
149  *
150  * this functions updates '*pmsg' and '*plen', and returns
151  * 1 if the sink's destination buffer is full, or 0 otherwise.
152  */
153 static int
qemud_sink_fill(QemudSink * ss,const uint8_t ** pmsg,int * plen)154 qemud_sink_fill( QemudSink*  ss, const uint8_t* *pmsg, int  *plen)
155 {
156     int  avail = ss->size - ss->used;
157 
158     if (avail <= 0)
159         return 1;
160 
161     if (avail > *plen)
162         avail = *plen;
163 
164     memcpy(ss->buff + ss->used, *pmsg, avail);
165     *pmsg += avail;
166     *plen -= avail;
167     ss->used += avail;
168 
169     return (ss->used == ss->size);
170 }
171 
172 /* returns the number of bytes needed to fill a sink's destination
173  * buffer.
174  */
175 static int
qemud_sink_needed(QemudSink * ss)176 qemud_sink_needed( QemudSink*  ss )
177 {
178     return ss->size - ss->used;
179 }
180 
181 /** HANDLING SERIAL PORT CONNECTION
182  **/
183 
184 /* The QemudSerial object receives data from the serial port charpipe.
185  * It parses the header to extract the channel id and payload length,
186  * then the message itself.
187  *
188  * Incoming messages are sent to a generic receiver identified by
189  * the 'recv_opaque' and 'recv_func' parameters to qemud_serial_init()
190  *
191  * It also provides qemud_serial_send() which can be used to send
192  * messages back through the serial port.
193  */
194 
195 #define  HEADER_SIZE    6
196 
197 #define  LENGTH_OFFSET  2
198 #define  LENGTH_SIZE    4
199 
200 #define  CHANNEL_OFFSET 0
201 #define  CHANNEL_SIZE   2
202 
203 #if SUPPORT_LEGACY_QEMUD
204 typedef enum {
205     QEMUD_VERSION_UNKNOWN,
206     QEMUD_VERSION_LEGACY,
207     QEMUD_VERSION_NORMAL
208 } QemudVersion;
209 
210 #  define  LEGACY_LENGTH_OFFSET   0
211 #  define  LEGACY_CHANNEL_OFFSET  4
212 #endif
213 
214 /* length of the framed header */
215 #define  FRAME_HEADER_SIZE  4
216 
217 #define  BUFFER_SIZE    MAX_SERIAL_PAYLOAD
218 
219 /* out of convenience, the incoming message is zero-terminated
220  * and can be modified by the receiver (e.g. for tokenization).
221  */
222 typedef void  (*QemudSerialReceive)( void*  opaque, int  channel, uint8_t*  msg, int  msglen);
223 
224 typedef struct QemudSerial {
225     CharDriverState*  cs;  /* serial charpipe endpoint */
226 
227     /* managing incoming packets from the serial port */
228     ABool         need_header;
229     int           overflow;
230     int           in_size;
231     int           in_channel;
232 #if SUPPORT_LEGACY_QEMUD
233     QemudVersion  version;
234 #endif
235     QemudSink     header[1];
236     QemudSink     payload[1];
237     uint8_t       data0[MAX_SERIAL_PAYLOAD+1];
238 
239     /* receiver */
240     QemudSerialReceive  recv_func;    /* receiver callback */
241     void*               recv_opaque;  /* receiver user-specific data */
242 } QemudSerial;
243 
244 
245 /* Save the state of a QemudSerial to a snapshot file.
246  */
247 static void
qemud_serial_save(QEMUFile * f,QemudSerial * s)248 qemud_serial_save(QEMUFile* f, QemudSerial* s)
249 {
250     /* cs, recv_func and recv_opaque are not saved, as these are assigned only
251      * during emulator init. A load within a session can re-use the values
252      * already assigned, a newly launched emulator has freshly assigned values.
253      */
254 
255     /* state of incoming packets from the serial port */
256     qemu_put_be32(f, s->need_header);
257     qemu_put_be32(f, s->overflow);
258     qemu_put_be32(f, s->in_size);
259     qemu_put_be32(f, s->in_channel);
260 #if SUPPORT_LEGACY_QEMUD
261     qemu_put_be32(f, s->version);
262 #endif
263     qemud_sink_save(f, s->header);
264     qemud_sink_save(f, s->payload);
265     qemu_put_be32(f, MAX_SERIAL_PAYLOAD+1);
266     qemu_put_buffer(f, s->data0, MAX_SERIAL_PAYLOAD+1);
267 }
268 
269 /* Load the state of a QemudSerial from a snapshot file.
270  */
271 static int
qemud_serial_load(QEMUFile * f,QemudSerial * s)272 qemud_serial_load(QEMUFile* f, QemudSerial* s)
273 {
274     /* state of incoming packets from the serial port */
275     s->need_header = qemu_get_be32(f);
276     s->overflow    = qemu_get_be32(f);
277     s->in_size     = qemu_get_be32(f);
278     s->in_channel  = qemu_get_be32(f);
279 #if SUPPORT_LEGACY_QEMUD
280     s->version = qemu_get_be32(f);
281 #endif
282     qemud_sink_load(f, s->header);
283     qemud_sink_load(f, s->payload);
284 
285     /* s->header and s->payload are only ever connected to s->data0 */
286     s->header->buff = s->payload->buff = s->data0;
287 
288     int len = qemu_get_be32(f);
289     if (len - 1 > MAX_SERIAL_PAYLOAD) {
290         D("%s: load failed: size of saved payload buffer (%d) exceeds "
291           "current maximum (%d)\n",
292           __FUNCTION__, len - 1, MAX_SERIAL_PAYLOAD);
293         return -EIO;
294     }
295     int ret;
296     if ((ret = qemu_get_buffer(f, s->data0, len)) != len) {
297         D("%s: failed to load serial buffer contents (tried reading %d bytes, got %d)\n",
298           __FUNCTION__, len, ret);
299         return -EIO;
300     }
301 
302     return 0;
303 }
304 
305 /* called by the charpipe to see how much bytes can be
306  * read from the serial port.
307  */
308 static int
qemud_serial_can_read(void * opaque)309 qemud_serial_can_read( void*  opaque )
310 {
311     QemudSerial*  s = opaque;
312 
313     if (s->overflow > 0) {
314         return s->overflow;
315     }
316 
317     /* if in_size is 0, we're reading the header */
318     if (s->need_header)
319         return qemud_sink_needed(s->header);
320 
321     /* otherwise, we're reading the payload */
322     return qemud_sink_needed(s->payload);
323 }
324 
325 /* called by the charpipe to read data from the serial
326  * port. 'len' cannot be more than the value returned
327  * by 'qemud_serial_can_read'.
328  */
329 static void
qemud_serial_read(void * opaque,const uint8_t * from,int len)330 qemud_serial_read( void*  opaque, const uint8_t*  from, int  len )
331 {
332     QemudSerial*  s = opaque;
333 
334     T("%s: received %3d bytes: '%s'", __FUNCTION__, len, quote_bytes((const void*)from, len));
335 
336     while (len > 0) {
337         int  avail;
338 
339         /* skip overflow bytes */
340         if (s->overflow > 0) {
341             avail = s->overflow;
342             if (avail > len)
343                 avail = len;
344 
345             from += avail;
346             len  -= avail;
347             continue;
348         }
349 
350         /* read header if needed */
351         if (s->need_header) {
352             if (!qemud_sink_fill(s->header, (const uint8_t**)&from, &len))
353                 break;
354 
355 #if SUPPORT_LEGACY_QEMUD
356             if (s->version == QEMUD_VERSION_UNKNOWN) {
357                 /* if we receive "001200" as the first header, then we
358                  * detected a legacy qemud daemon. See the comments
359                  * in qemud_serial_send_legacy_probe() for details.
360                  */
361                 if ( !memcmp(s->data0, "001200", 6) ) {
362                     D("%s: legacy qemud detected.", __FUNCTION__);
363                     s->version = QEMUD_VERSION_LEGACY;
364                     /* tell the modem to use legacy emulation mode */
365                     amodem_set_legacy(android_modem);
366                 } else {
367                     D("%s: normal qemud detected.", __FUNCTION__);
368                     s->version = QEMUD_VERSION_NORMAL;
369                 }
370             }
371 
372             if (s->version == QEMUD_VERSION_LEGACY) {
373                 s->in_size     = hex2int( s->data0 + LEGACY_LENGTH_OFFSET,  LENGTH_SIZE );
374                 s->in_channel  = hex2int( s->data0 + LEGACY_CHANNEL_OFFSET, CHANNEL_SIZE );
375             } else {
376                 s->in_size     = hex2int( s->data0 + LENGTH_OFFSET,  LENGTH_SIZE );
377                 s->in_channel  = hex2int( s->data0 + CHANNEL_OFFSET, CHANNEL_SIZE );
378             }
379 #else
380             /* extract payload length + channel id */
381             s->in_size     = hex2int( s->data0 + LENGTH_OFFSET,  LENGTH_SIZE );
382             s->in_channel  = hex2int( s->data0 + CHANNEL_OFFSET, CHANNEL_SIZE );
383 #endif
384             s->header->used = 0;
385 
386             if (s->in_size <= 0 || s->in_channel < 0) {
387                 D("%s: bad header: '%.*s'", __FUNCTION__, HEADER_SIZE, s->data0);
388                 continue;
389             }
390 
391             if (s->in_size > MAX_SERIAL_PAYLOAD) {
392                 D("%s: ignoring huge serial packet: length=%d channel=%1",
393                   __FUNCTION__, s->in_size, s->in_channel);
394                 s->overflow = s->in_size;
395                 continue;
396             }
397 
398             /* prepare 'in_data' for payload */
399             s->need_header = 0;
400             qemud_sink_reset(s->payload, s->in_size, s->data0);
401         }
402 
403         /* read payload bytes */
404         if (!qemud_sink_fill(s->payload, &from, &len))
405             break;
406 
407         /* zero-terminate payload, then send it to receiver */
408         s->payload->buff[s->payload->size] = 0;
409         D("%s: channel=%2d len=%3d '%s'", __FUNCTION__,
410           s->in_channel, s->payload->size,
411           quote_bytes((const void*)s->payload->buff, s->payload->size));
412 
413         s->recv_func( s->recv_opaque, s->in_channel, s->payload->buff, s->payload->size );
414 
415         /* prepare for new header */
416         s->need_header = 1;
417     }
418 }
419 
420 
421 #if SUPPORT_LEGACY_QEMUD
422 static void
qemud_serial_send_legacy_probe(QemudSerial * s)423 qemud_serial_send_legacy_probe( QemudSerial*  s )
424 {
425     /* we're going to send a specially crafted packet to the qemud
426      * daemon, this will help us determine whether we're talking
427      * to a legacy or a normal daemon.
428      *
429      * the trick is to known that a legacy daemon uses the following
430      * header:
431      *
432      *    <length><channel><payload>
433      *
434      * while the normal one uses:
435      *
436      *    <channel><length><payload>
437      *
438      * where <channel> is a 2-hexchar string, and <length> a 4-hexchar
439      * string.
440      *
441      * if we send a header of "000100", it is interpreted:
442      *
443      * - as the header of a 1-byte payload by the legacy daemon
444      * - as the header of a 256-byte payload by the normal one.
445      *
446      * we're going to send something that looks like:
447      *
448      *   "000100" + "X" +
449      *   "000b00" + "connect:gsm" +
450      *   "000b00" + "connect:gps" +
451      *   "000f00" + "connect:control" +
452      *   "00c210" + "0"*194
453      *
454      * the normal daemon will interpret this as a 256-byte payload
455      * for channel 0, with garbage content ("X000b00conn...") which
456      * will be silently ignored.
457      *
458      * on the other hand, the legacy daemon will see it as a
459      * series of packets:
460      *
461      *   one message "X" on channel 0, which will force the daemon
462      *   to send back "001200ko:unknown command" as its first answer.
463      *
464      *   three "connect:<xxx>" messages used to receive the channel
465      *   numbers of the three legacy services implemented by the daemon.
466      *
467      *   a garbage packet of 194 zeroes for channel 16, which will be
468      *   silently ignored.
469      */
470     uint8_t  tab[194];
471 
472     memset(tab, 0, sizeof(tab));
473     qemu_chr_write(s->cs, (uint8_t*)"000100X", 7);
474     qemu_chr_write(s->cs, (uint8_t*)"000b00connect:gsm", 17);
475     qemu_chr_write(s->cs, (uint8_t*)"000b00connect:gps", 17);
476     qemu_chr_write(s->cs, (uint8_t*)"000f00connect:control", 21);
477     qemu_chr_write(s->cs, (uint8_t*)"00c210", 6);
478     qemu_chr_write(s->cs, tab, sizeof(tab));
479 }
480 #endif /* SUPPORT_LEGACY_QEMUD */
481 
482 /* intialize a QemudSerial object with a charpipe endpoint
483  * and a receiver.
484  */
485 static void
qemud_serial_init(QemudSerial * s,CharDriverState * cs,QemudSerialReceive recv_func,void * recv_opaque)486 qemud_serial_init( QemudSerial*        s,
487                    CharDriverState*    cs,
488                    QemudSerialReceive  recv_func,
489                    void*               recv_opaque )
490 {
491     s->cs           = cs;
492     s->recv_func    = recv_func;
493     s->recv_opaque  = recv_opaque;
494     s->need_header  = 1;
495     s->overflow     = 0;
496 
497     qemud_sink_reset( s->header, HEADER_SIZE, s->data0 );
498     s->in_size      = 0;
499     s->in_channel   = -1;
500 
501 #if SUPPORT_LEGACY_QEMUD
502     s->version = QEMUD_VERSION_UNKNOWN;
503     qemud_serial_send_legacy_probe(s);
504 #endif
505 
506     qemu_chr_add_handlers( cs,
507                            qemud_serial_can_read,
508                            qemud_serial_read,
509                            NULL,
510                            s );
511 }
512 
513 /* send a message to the serial port. This will add the necessary
514  * header.
515  */
516 static void
qemud_serial_send(QemudSerial * s,int channel,ABool framing,const uint8_t * msg,int msglen)517 qemud_serial_send( QemudSerial*    s,
518                    int             channel,
519                    ABool           framing,
520                    const uint8_t*  msg,
521                    int             msglen )
522 {
523     uint8_t   header[HEADER_SIZE];
524     uint8_t   frame[FRAME_HEADER_SIZE];
525     int       avail, len = msglen;
526 
527     if (msglen <= 0 || channel < 0)
528         return;
529 
530     D("%s: channel=%2d len=%3d '%s'",
531       __FUNCTION__, channel, msglen,
532       quote_bytes((const void*)msg, msglen));
533 
534     if (framing) {
535         len += FRAME_HEADER_SIZE;
536     }
537 
538     /* packetize the payload for the serial MTU */
539     while (len > 0)
540     {
541         avail = len;
542         if (avail > MAX_SERIAL_PAYLOAD)
543             avail = MAX_SERIAL_PAYLOAD;
544 
545         /* write this packet's header */
546 #if SUPPORT_LEGACY_QEMUD
547         if (s->version == QEMUD_VERSION_LEGACY) {
548             int2hex(header + LEGACY_LENGTH_OFFSET,  LENGTH_SIZE,  avail);
549             int2hex(header + LEGACY_CHANNEL_OFFSET, CHANNEL_SIZE, channel);
550         } else {
551             int2hex(header + LENGTH_OFFSET,  LENGTH_SIZE,  avail);
552             int2hex(header + CHANNEL_OFFSET, CHANNEL_SIZE, channel);
553         }
554 #else
555         int2hex(header + LENGTH_OFFSET,  LENGTH_SIZE,  avail);
556         int2hex(header + CHANNEL_OFFSET, CHANNEL_SIZE, channel);
557 #endif
558         T("%s: '%.*s'", __FUNCTION__, HEADER_SIZE, header);
559         qemu_chr_write(s->cs, header, HEADER_SIZE);
560 
561         /* insert frame header when needed */
562         if (framing) {
563             int2hex(frame, FRAME_HEADER_SIZE, msglen);
564             T("%s: '%.*s'", __FUNCTION__, FRAME_HEADER_SIZE, frame);
565             qemu_chr_write(s->cs, frame, FRAME_HEADER_SIZE);
566             avail  -= FRAME_HEADER_SIZE;
567             len    -= FRAME_HEADER_SIZE;
568             framing = 0;
569         }
570 
571         /* write message content */
572         T("%s: '%.*s'", __FUNCTION__, avail, msg);
573         qemu_chr_write(s->cs, msg, avail);
574         msg += avail;
575         len -= avail;
576     }
577 }
578 
579 /** CLIENTS
580  **/
581 
582 /* Descriptor for a data buffer pending to be sent to a qemud pipe client.
583  *
584  * When a service decides to send data to the client, there could be cases when
585  * client is not ready to read them. In this case there is no GoldfishPipeBuffer
586  * available to write service's data to, So, we need to cache that data into the
587  * client descriptor, and "send" them over to the client in _qemudPipe_recvBuffers
588  * callback. Pending service data is stored in the client descriptor as a list
589  * of QemudPipeMessage instances.
590  */
591 typedef struct QemudPipeMessage QemudPipeMessage;
592 struct QemudPipeMessage {
593     /* Message to send. */
594     uint8_t*            message;
595     /* Message size. */
596     size_t              size;
597     /* Offset in the message buffer of the chunk, that has not been sent
598      * to the pipe yet. */
599     size_t              offset;
600     /* Links next message in the client. */
601     QemudPipeMessage*   next;
602 };
603 
604 
605 /* A QemudClient models a single client as seen by the emulator.
606  * Each client has its own channel id (for the serial qemud), or pipe descriptor
607  * (for the pipe based qemud), and belongs to a given QemudService (see below).
608  *
609  * There is a global list of serial clients used to multiplex incoming
610  * messages from the channel id (see qemud_multiplexer_serial_recv()). Pipe
611  * clients don't need multiplexing, because they are communicated via qemud pipes
612  * that are unique for each client.
613  *
614  */
615 
616 /* Defines type of the client: pipe, or serial.
617  */
618 typedef enum QemudProtocol {
619     /* Client is communicating via pipe. */
620     QEMUD_PROTOCOL_PIPE,
621     /* Client is communicating via serial port. */
622     QEMUD_PROTOCOL_SERIAL
623 } QemudProtocol;
624 
625 /* Descriptor for a QEMUD pipe connection.
626  *
627  * Every time a client connects to the QEMUD via pipe, an instance of this
628  * structure is created to represent a connection used by new pipe client.
629  */
630 typedef struct QemudPipe {
631     /* Pipe descriptor. */
632     void*           hwpipe;
633     /* Looper used for I/O */
634     void*           looper;
635     /* Service for this pipe. */
636     QemudService*   service;
637     /* Client for this pipe. */
638     QemudClient*    client;
639 } QemudPipe;
640 
641 struct QemudClient {
642     /* Defines protocol, used by the client. */
643     QemudProtocol     protocol;
644 
645     /* Fields that are common for all protocols. */
646     char*             param;
647     void*             clie_opaque;
648     QemudClientRecv   clie_recv;
649     QemudClientClose  clie_close;
650     QemudClientSave   clie_save;
651     QemudClientLoad   clie_load;
652     QemudService*     service;
653     QemudClient*      next_serv; /* next in same service */
654     QemudClient*      next;
655     QemudClient**     pref;
656 
657     /* framing support */
658     int               framing;
659     ABool             need_header;
660     ABool             closing;
661     QemudSink         header[1];
662     uint8_t           header0[FRAME_HEADER_SIZE];
663     QemudSink         payload[1];
664 
665     /* Fields that are protocol-specific. */
666     union {
667         /* Serial-specific fields. */
668         struct {
669             int                 channel;
670             QemudSerial*        serial;
671         } Serial;
672         /* Pipe-specific fields. */
673         struct {
674             QemudPipe*          qemud_pipe;
675             QemudPipeMessage*   messages;
676         } Pipe;
677     } ProtocolSelector;
678 };
679 
680 static ABool
_is_pipe_client(QemudClient * client)681 _is_pipe_client(QemudClient* client)
682 {
683     return (client-> protocol == QEMUD_PROTOCOL_PIPE) ? true : false;
684 }
685 
686 static void  qemud_service_remove_client( QemudService*  service,
687                                           QemudClient*   client );
688 
689 /* remove a QemudClient from global list */
690 static void
qemud_client_remove(QemudClient * c)691 qemud_client_remove( QemudClient*  c )
692 {
693     c->pref[0] = c->next;
694     if (c->next)
695         c->next->pref = c->pref;
696 
697     c->next = NULL;
698     c->pref = &c->next;
699 }
700 
701 /* add a QemudClient to global list */
702 static void
qemud_client_prepend(QemudClient * c,QemudClient ** plist)703 qemud_client_prepend( QemudClient*  c, QemudClient** plist )
704 {
705     c->next = *plist;
706     c->pref = plist;
707     *plist  = c;
708     if (c->next)
709         c->next->pref = &c->next;
710 }
711 
712 /* receive a new message from a client, and dispatch it to
713  * the real service implementation.
714  */
715 static void
qemud_client_recv(void * opaque,uint8_t * msg,int msglen)716 qemud_client_recv( void*  opaque, uint8_t*  msg, int  msglen )
717 {
718     QemudClient*  c = opaque;
719 
720     /* no framing, things are simple */
721     if (!c->framing) {
722         if (c->clie_recv)
723             c->clie_recv( c->clie_opaque, msg, msglen, c );
724         return;
725     }
726 
727     /* framing */
728 
729 #if 1
730     /* special case, in 99% of cases, everything is in
731      * the incoming message, and we can do all we need
732      * directly without dynamic allocation.
733      */
734     if (msglen > FRAME_HEADER_SIZE   &&
735         c->need_header == 1          &&
736         qemud_sink_needed(c->header) == 0)
737     {
738         int  len = hex2int( msg, FRAME_HEADER_SIZE );
739 
740         if (len >= 0 && msglen == len + FRAME_HEADER_SIZE) {
741             if (c->clie_recv)
742                 c->clie_recv( c->clie_opaque,
743                               msg+FRAME_HEADER_SIZE,
744                               msglen-FRAME_HEADER_SIZE, c );
745             return;
746         }
747     }
748 #endif
749 
750     while (msglen > 0) {
751         uint8_t *data;
752 
753         /* read the header */
754         if (c->need_header) {
755             int       frame_size;
756             uint8_t*  data;
757 
758             if (!qemud_sink_fill(c->header, (const uint8_t**)&msg, &msglen))
759                 break;
760 
761             frame_size = hex2int(c->header0, 4);
762             if (frame_size == 0) {
763                 D("%s: ignoring empty frame", __FUNCTION__);
764                 continue;
765             }
766             if (frame_size < 0) {
767                 D("%s: ignoring corrupted frame header '.*s'",
768                   __FUNCTION__, FRAME_HEADER_SIZE, c->header0 );
769                 continue;
770             }
771 
772             AARRAY_NEW(data, frame_size+1);  /* +1 for terminating zero */
773             qemud_sink_reset(c->payload, frame_size, data);
774             c->need_header = 0;
775             c->header->used = 0;
776         }
777 
778         /* read the payload */
779         if (!qemud_sink_fill(c->payload, (const uint8_t**)&msg, &msglen))
780             break;
781 
782         c->payload->buff[c->payload->size] = 0;
783         c->need_header = 1;
784         data = c->payload->buff;
785 
786         /* Technically, calling 'clie_recv' can destroy client object 'c'
787          * if it decides to close the connection, so ensure we don't
788          * use/dereference it after the call. */
789         if (c->clie_recv)
790             c->clie_recv( c->clie_opaque, c->payload->buff, c->payload->size, c );
791 
792         AFREE(data);
793     }
794 }
795 
796 /* Sends data to a pipe-based client.
797  */
798 static void
799 _qemud_pipe_send(QemudClient*  client, const uint8_t*  msg, int  msglen);
800 
801 /* Frees memory allocated for the qemud client.
802  */
803 static void
_qemud_client_free(QemudClient * c)804 _qemud_client_free(QemudClient* c)
805 {
806     if ( c != NULL) {
807         if (_is_pipe_client(c)) {
808             /* Free outstanding messages. */
809             QemudPipeMessage** msg_list = &c->ProtocolSelector.Pipe.messages;
810             while (*msg_list != NULL) {
811                 QemudPipeMessage* to_free = *msg_list;
812                 *msg_list = to_free->next;
813                 free(to_free);
814             }
815         }
816         if (c->param != NULL) {
817             free(c->param);
818         }
819         AFREE(c);
820     }
821 }
822 
823 /* disconnect a client. this automatically frees the QemudClient.
824  * note that this also removes the client from the global list
825  * and from its service's list, if any.
826  */
827 static void
qemud_client_disconnect(void * opaque)828 qemud_client_disconnect( void*  opaque )
829 {
830     QemudClient*  c = opaque;
831 
832     if (c->closing) {  /* recursive call, exit immediately */
833         return;
834     }
835     c->closing = 1;
836 
837     /* remove from current list */
838     qemud_client_remove(c);
839 
840     /* send a disconnect command to the daemon */
841     if (_is_pipe_client(c)) {
842         char  tmp[128], *p=tmp, *end=p+sizeof(tmp);
843         p = bufprint(tmp, end, "disconnect:00");
844         _qemud_pipe_send(c, (uint8_t*)tmp, p-tmp);
845         /* We must NULL the client reference in the QemuPipe for this connection,
846          * so if a sudden receive request comes after client has been closed, we
847          * don't blow up. */
848         c->ProtocolSelector.Pipe.qemud_pipe->client = NULL;
849     } else if (c->ProtocolSelector.Serial.channel > 0) {
850         char  tmp[128], *p=tmp, *end=p+sizeof(tmp);
851         p = bufprint(tmp, end, "disconnect:%02x",
852                      c->ProtocolSelector.Serial.channel);
853         qemud_serial_send(c->ProtocolSelector.Serial.serial, 0, 0, (uint8_t*)tmp, p-tmp);
854     }
855 
856     /* call the client close callback */
857     if (c->clie_close) {
858         c->clie_close(c->clie_opaque);
859         c->clie_close = NULL;
860     }
861     c->clie_recv = NULL;
862 
863     /* remove from service list, if any */
864     if (c->service) {
865         qemud_service_remove_client(c->service, c);
866         c->service = NULL;
867     }
868 
869     _qemud_client_free(c);
870 }
871 
872 /* allocate a new QemudClient object
873  * NOTE: channel_id valie is used as a selector between serial and pipe clients.
874  * Since channel_id < 0 is an invalid value for a serial client, it would
875  * indicate that creating client is a pipe client. */
876 static QemudClient*
qemud_client_alloc(int channel_id,const char * client_param,void * clie_opaque,QemudClientRecv clie_recv,QemudClientClose clie_close,QemudClientSave clie_save,QemudClientLoad clie_load,QemudSerial * serial,QemudClient ** pclients)877 qemud_client_alloc( int               channel_id,
878                     const char*       client_param,
879                     void*             clie_opaque,
880                     QemudClientRecv   clie_recv,
881                     QemudClientClose  clie_close,
882                     QemudClientSave   clie_save,
883                     QemudClientLoad   clie_load,
884                     QemudSerial*      serial,
885                     QemudClient**     pclients )
886 {
887     QemudClient*  c;
888 
889     ANEW0(c);
890 
891     if (channel_id < 0) {
892         /* Allocating a pipe client. */
893         c->protocol = QEMUD_PROTOCOL_PIPE;
894         c->ProtocolSelector.Pipe.messages   = NULL;
895         c->ProtocolSelector.Pipe.qemud_pipe = NULL;
896     } else {
897         /* Allocating a serial client. */
898         c->protocol = QEMUD_PROTOCOL_SERIAL;
899         c->ProtocolSelector.Serial.serial   = serial;
900         c->ProtocolSelector.Serial.channel  = channel_id;
901     }
902     c->param       = client_param ? ASTRDUP(client_param) : NULL;
903     c->clie_opaque = clie_opaque;
904     c->clie_recv   = clie_recv;
905     c->clie_close  = clie_close;
906     c->clie_save   = clie_save;
907     c->clie_load   = clie_load;
908     c->service     = NULL;
909     c->next_serv   = NULL;
910     c->next        = NULL;
911     c->framing     = 0;
912     c->need_header = 1;
913     qemud_sink_reset(c->header, FRAME_HEADER_SIZE, c->header0);
914 
915     qemud_client_prepend(c, pclients);
916 
917     return c;
918 }
919 
920 /* forward */
921 static void  qemud_service_save_name( QEMUFile* f, QemudService* s );
922 static char* qemud_service_load_name( QEMUFile* f );
923 static QemudService* qemud_service_find(  QemudService*  service_list,
924                                           const char*    service_name );
925 static QemudClient*  qemud_service_connect_client(  QemudService  *sv,
926                                                     int           channel_id,
927                                                     const char* client_param);
928 
929 /* Saves the client state needed to re-establish connections on load.
930  */
931 static void
qemud_client_save(QEMUFile * f,QemudClient * c)932 qemud_client_save(QEMUFile* f, QemudClient* c)
933 {
934     /* save generic information */
935     qemud_service_save_name(f, c->service);
936     qemu_put_be32(f, c->protocol);
937     if (!_is_pipe_client(c)) {
938         qemu_put_be32(f, c->ProtocolSelector.Serial.channel);
939     }
940 
941     /* save client-specific state */
942     if (c->clie_save)
943         c->clie_save(f, c, c->clie_opaque);
944 
945     /* save framing configuration */
946     qemu_put_be32(f, c->framing);
947     if (c->framing) {
948         qemu_put_be32(f, c->need_header);
949         /* header sink always connected to c->header0, no need to save */
950         qemu_put_be32(f, FRAME_HEADER_SIZE);
951         qemu_put_buffer(f, c->header0, FRAME_HEADER_SIZE);
952         /* payload sink */
953         qemud_sink_save(f, c->payload);
954         qemu_put_buffer(f, c->payload->buff, c->payload->size);
955     }
956 }
957 
958 /* Loads client state from file, then starts a new client connected to the
959  * corresponding service.
960  */
961 static int
qemud_client_load(QEMUFile * f,QemudService * current_services,int version)962 qemud_client_load(QEMUFile* f, QemudService* current_services, int version )
963 {
964     char *service_name = qemud_service_load_name(f);
965     if (service_name == NULL)
966         return -EIO;
967 
968     /* get current service instance */
969     QemudService *sv = qemud_service_find(current_services, service_name);
970     if (sv == NULL) {
971         D("%s: load failed: unknown service \"%s\"\n",
972           __FUNCTION__, service_name);
973         return -EIO;
974     }
975 
976     int channel = -1;
977 
978     if (version >= 2) {
979         /* get protocol. */
980         QemudProtocol protocol = qemu_get_be32(f);
981         /* get channel id */
982         if (protocol == QEMUD_PROTOCOL_SERIAL) {
983             channel = qemu_get_be32(f);
984         }
985     } else {
986         channel = qemu_get_be32(f);
987     }
988 
989     if (channel == 0) {
990         D("%s: illegal snapshot: client for control channel must no be saved\n",
991           __FUNCTION__);
992         return -EIO;
993     }
994 
995     /* re-connect client */
996     QemudClient* c = qemud_service_connect_client(sv, channel, NULL);
997     if(c == NULL)
998         return -EIO;
999 
1000     /* load client-specific state */
1001     int ret;
1002     if (c->clie_load)
1003         if ((ret = c->clie_load(f, c, c->clie_opaque)))
1004             return ret;  /* load failure */
1005 
1006     /* load framing configuration */
1007     c->framing = qemu_get_be32(f);
1008     if (c->framing) {
1009 
1010         /* header buffer */
1011         c->need_header = qemu_get_be32(f);
1012         int header_size = qemu_get_be32(f);
1013         if (header_size > FRAME_HEADER_SIZE) {
1014             D("%s: load failed: payload buffer requires %d bytes, %d available\n",
1015               __FUNCTION__, header_size, FRAME_HEADER_SIZE);
1016             return -EIO;
1017         }
1018         int ret;
1019         if ((ret = qemu_get_buffer(f, c->header0, header_size)) != header_size) {
1020             D("%s: frame header buffer load failed: expected %d bytes, got %d\n",
1021               __FUNCTION__, header_size, ret);
1022             return -EIO;
1023         }
1024 
1025         /* payload sink */
1026         if ((ret = qemud_sink_load(f, c->payload)))
1027             return ret;
1028 
1029         /* replace payload buffer by saved data */
1030         if (c->payload->buff) {
1031             AFREE(c->payload->buff);
1032         }
1033         AARRAY_NEW(c->payload->buff, c->payload->size+1);  /* +1 for terminating zero */
1034         if ((ret = qemu_get_buffer(f, c->payload->buff, c->payload->size)) != c->payload->size) {
1035             D("%s: frame payload buffer load failed: expected %d bytes, got %d\n",
1036               __FUNCTION__, c->payload->size, ret);
1037             AFREE(c->payload->buff);
1038             return -EIO;
1039         }
1040     }
1041 
1042     return 0;
1043 }
1044 
1045 
1046 /** SERVICES
1047  **/
1048 
1049 /* A QemudService models a _named_ service facility implemented
1050  * by the emulator, that clients in the emulated system can connect
1051  * to.
1052  *
1053  * Each service can have a limit on the number of clients they
1054  * accept (this number if unlimited if 'max_clients' is 0).
1055  *
1056  * Each service maintains a list of active QemudClients and
1057  * can also be used to create new QemudClient objects through
1058  * its 'serv_opaque' and 'serv_connect' fields.
1059  */
1060 struct QemudService {
1061     const char*          name;
1062     int                  max_clients;
1063     int                  num_clients;
1064     QemudClient*         clients;
1065     QemudServiceConnect  serv_connect;
1066     QemudServiceSave     serv_save;
1067     QemudServiceLoad     serv_load;
1068     void*                serv_opaque;
1069     QemudService*        next;
1070 };
1071 
1072 /* Create a new QemudService object */
1073 static QemudService*
qemud_service_new(const char * name,int max_clients,void * serv_opaque,QemudServiceConnect serv_connect,QemudServiceSave serv_save,QemudServiceLoad serv_load,QemudService ** pservices)1074 qemud_service_new( const char*          name,
1075                    int                  max_clients,
1076                    void*                serv_opaque,
1077                    QemudServiceConnect  serv_connect,
1078                    QemudServiceSave     serv_save,
1079                    QemudServiceLoad     serv_load,
1080                    QemudService**       pservices )
1081 {
1082     QemudService*  s;
1083 
1084     ANEW0(s);
1085     s->name        = ASTRDUP(name);
1086     s->max_clients = max_clients;
1087     s->num_clients = 0;
1088     s->clients     = NULL;
1089 
1090     s->serv_opaque  = serv_opaque;
1091     s->serv_connect = serv_connect;
1092     s->serv_save = serv_save;
1093     s->serv_load = serv_load;
1094 
1095     s->next    = *pservices;
1096     *pservices = s;
1097 
1098     return s;
1099 }
1100 
1101 /* used internally to populate a QemudService object with a
1102  * new QemudClient */
1103 static void
qemud_service_add_client(QemudService * s,QemudClient * c)1104 qemud_service_add_client( QemudService*  s, QemudClient*  c )
1105 {
1106     c->service      = s;
1107     c->next_serv    = s->clients;
1108     s->clients      = c;
1109     s->num_clients += 1;
1110 }
1111 
1112 /* used internally to remove a QemudClient from a QemudService */
1113 static void
qemud_service_remove_client(QemudService * s,QemudClient * c)1114 qemud_service_remove_client( QemudService*  s, QemudClient*  c )
1115 {
1116     QemudClient**  pnode = &s->clients;
1117     QemudClient*   node;
1118 
1119     /* remove from clients linked-list */
1120     for (;;) {
1121         node = *pnode;
1122         if (node == NULL) {
1123             D("%s: could not find client for service '%s'",
1124               __FUNCTION__, s->name);
1125             return;
1126         }
1127         if (node == c)
1128             break;
1129         pnode = &node->next_serv;
1130     }
1131 
1132     *pnode          = node->next_serv;
1133     s->num_clients -= 1;
1134 }
1135 
1136 /* ask the service to create a new QemudClient. Note that we
1137  * assume that this calls qemud_client_new() which will add
1138  * the client to the service's list automatically.
1139  *
1140  * returns the client or NULL if an error occurred
1141  */
1142 static QemudClient*
qemud_service_connect_client(QemudService * sv,int channel_id,const char * client_param)1143 qemud_service_connect_client(QemudService *sv,
1144                              int channel_id,
1145                              const char* client_param)
1146 {
1147     QemudClient* client =
1148         sv->serv_connect( sv->serv_opaque, sv, channel_id, client_param );
1149     if (client == NULL) {
1150         D("%s: registration failed for '%s' service",
1151           __FUNCTION__, sv->name);
1152         return NULL;
1153     }
1154     D("%s: registered client channel %d for '%s' service",
1155       __FUNCTION__, channel_id, sv->name);
1156     return client;
1157 }
1158 
1159 /* find a registered service by name.
1160  */
1161 static QemudService*
qemud_service_find(QemudService * service_list,const char * service_name)1162 qemud_service_find( QemudService*  service_list, const char*  service_name)
1163 {
1164     QemudService*  sv = NULL;
1165     for (sv = service_list; sv != NULL; sv = sv->next) {
1166         if (!strcmp(sv->name, service_name)) {
1167             break;
1168         }
1169     }
1170     return sv;
1171 }
1172 
1173 /* Save the name of the given service.
1174  */
1175 static void
qemud_service_save_name(QEMUFile * f,QemudService * s)1176 qemud_service_save_name(QEMUFile* f, QemudService* s)
1177 {
1178     int len = strlen(s->name) + 1;  // include '\0' terminator
1179     qemu_put_be32(f, len);
1180     qemu_put_buffer(f, (const uint8_t *) s->name, len);
1181 }
1182 
1183 /* Load the name of a service. Returns a pointer to the loaded name, or NULL
1184  * on failure.
1185  */
1186 static char*
qemud_service_load_name(QEMUFile * f)1187 qemud_service_load_name( QEMUFile*  f )
1188 {
1189     int ret;
1190     int name_len = qemu_get_be32(f);
1191     char *service_name = android_alloc(name_len);
1192     if ((ret = qemu_get_buffer(f, (uint8_t*)service_name, name_len) != name_len)) {
1193         D("%s: service name load failed: expected %d bytes, got %d\n",
1194           __FUNCTION__, name_len, ret);
1195         AFREE(service_name);
1196         return NULL;
1197     }
1198     if (service_name[name_len - 1] != '\0') {
1199         char last = service_name[name_len - 1];
1200         service_name[name_len - 1] = '\0';  /* make buffer contents printable */
1201         D("%s: service name load failed: expecting NULL-terminated string, but "
1202           "last char is '%c' (buffer contents: '%s%c')\n",
1203           __FUNCTION__, name_len, last, service_name, last);
1204         AFREE(service_name);
1205         return NULL;
1206     }
1207 
1208     return service_name;
1209 }
1210 
1211 /* Saves state of a service.
1212  */
1213 static void
qemud_service_save(QEMUFile * f,QemudService * s)1214 qemud_service_save(QEMUFile* f, QemudService* s)
1215 {
1216     qemud_service_save_name(f, s);
1217     qemu_put_be32(f, s->max_clients);
1218     qemu_put_be32(f, s->num_clients);
1219 
1220     if (s->serv_save)
1221         s->serv_save(f, s, s->serv_opaque);
1222 }
1223 
1224 /* Loads service state from file, then updates the currently running instance
1225  * of that service to mirror the loaded state. If the service is not running,
1226  * the load process is aborted.
1227  *
1228  * Parameter 'current_services' should be the list of active services.
1229  */
1230 static int
qemud_service_load(QEMUFile * f,QemudService * current_services)1231 qemud_service_load(  QEMUFile*  f, QemudService*  current_services  )
1232 {
1233     char* service_name = qemud_service_load_name(f);
1234     if (service_name == NULL)
1235         return -EIO;
1236 
1237     /* get current service instance */
1238     QemudService *sv = qemud_service_find(current_services, service_name);
1239     if (sv == NULL) {
1240         D("%s: loading failed: service \"%s\" not available\n",
1241           __FUNCTION__, service_name);
1242         return -EIO;
1243     }
1244 
1245     /* reconfigure service as required */
1246     sv->max_clients = qemu_get_be32(f);
1247     sv->num_clients = qemu_get_be32(f);
1248 
1249     /* load service specific data */
1250     int ret;
1251     if (sv->serv_load)
1252         if ((ret = sv->serv_load(f, sv, sv->serv_opaque)))
1253             return ret;  /* load failure */
1254 
1255     return 0;
1256 }
1257 
1258 
1259 /** MULTIPLEXER
1260  **/
1261 
1262 /* A QemudMultiplexer object maintains the global state of the
1263  * qemud service facility. It holds a QemudSerial object to
1264  * maintain the state of the serial port connection.
1265  *
1266  * The QemudMultiplexer receives all incoming messages from
1267  * the serial port, and dispatches them to the appropriate
1268  * QemudClient.
1269  *
1270  * It also has a global list of clients, and a global list of
1271  * services.
1272  *
1273  * Finally, the QemudMultiplexer has a special QemudClient used
1274  * to handle channel 0, i.e. the control channel used to handle
1275  * connections and disconnections of clients.
1276  */
1277 typedef struct QemudMultiplexer  QemudMultiplexer;
1278 
1279 struct QemudMultiplexer {
1280     QemudSerial    serial[1];
1281     QemudClient*   clients;
1282     QemudService*  services;
1283 };
1284 
1285 /* this is the serial_recv callback that is called
1286  * whenever an incoming message arrives through the serial port
1287  */
1288 static void
qemud_multiplexer_serial_recv(void * opaque,int channel,uint8_t * msg,int msglen)1289 qemud_multiplexer_serial_recv( void*     opaque,
1290                                int       channel,
1291                                uint8_t*  msg,
1292                                int       msglen )
1293 {
1294     QemudMultiplexer*  m = opaque;
1295     QemudClient*       c = m->clients;
1296 
1297     /* dispatch to an existing client if possible
1298      * note that channel 0 is handled by a special
1299      * QemudClient that is setup in qemud_multiplexer_init()
1300      */
1301     for ( ; c != NULL; c = c->next ) {
1302         if (!_is_pipe_client(c) && c->ProtocolSelector.Serial.channel == channel) {
1303             qemud_client_recv(c, msg, msglen);
1304             return;
1305         }
1306     }
1307 
1308     D("%s: ignoring %d bytes for unknown channel %d",
1309       __FUNCTION__, msglen, channel);
1310 }
1311 
1312 /* handle a new connection attempt. This returns 0 on
1313  * success, -1 if the service name is unknown, or -2
1314  * if the service's maximum number of clients has been
1315  * reached.
1316  */
1317 static int
qemud_multiplexer_connect(QemudMultiplexer * m,const char * service_name,int channel_id)1318 qemud_multiplexer_connect( QemudMultiplexer*  m,
1319                            const char*        service_name,
1320                            int                channel_id )
1321 {
1322     /* find the corresponding registered service by name */
1323     QemudService*  sv = qemud_service_find(m->services, service_name);
1324     if (sv == NULL) {
1325         D("%s: no registered '%s' service", __FUNCTION__, service_name);
1326         return -1;
1327     }
1328 
1329     /* check service's client count */
1330     if (sv->max_clients > 0 && sv->num_clients >= sv->max_clients) {
1331         D("%s: registration failed for '%s' service: too many clients (%d)",
1332           __FUNCTION__, service_name, sv->num_clients);
1333         return -2;
1334     }
1335 
1336     /* connect a new client to the service on the given channel */
1337     if (qemud_service_connect_client(sv, channel_id, NULL) == NULL)
1338         return -1;
1339 
1340     return 0;
1341 }
1342 
1343 /* disconnect a given client from its channel id */
1344 static void
qemud_multiplexer_disconnect(QemudMultiplexer * m,int channel)1345 qemud_multiplexer_disconnect( QemudMultiplexer*  m,
1346                               int                channel )
1347 {
1348     QemudClient*  c;
1349 
1350     /* find the client by its channel id, then disconnect it */
1351     for (c = m->clients; c; c = c->next) {
1352         if (!_is_pipe_client(c) && c->ProtocolSelector.Serial.channel == channel) {
1353             D("%s: disconnecting client %d",
1354               __FUNCTION__, channel);
1355             /* note thatt this removes the client from
1356              * m->clients automatically.
1357              */
1358             c->ProtocolSelector.Serial.channel = -1; /* no need to send disconnect:<id> */
1359             qemud_client_disconnect(c);
1360             return;
1361         }
1362     }
1363     D("%s: disconnecting unknown channel %d",
1364       __FUNCTION__, channel);
1365 }
1366 
1367 /* disconnects all channels, except for the control channel, without informing
1368  * the daemon in the guest that disconnection has occurred.
1369  *
1370  * Used to silently kill clients when restoring emulator state snapshots.
1371  */
1372 static void
qemud_multiplexer_disconnect_noncontrol(QemudMultiplexer * m)1373 qemud_multiplexer_disconnect_noncontrol( QemudMultiplexer*  m )
1374 {
1375     QemudClient* c;
1376     QemudClient* next = m->clients;
1377 
1378     while (next) {
1379         c = next;
1380         next = c->next;  /* disconnect frees c, remember next in advance */
1381 
1382         if (!_is_pipe_client(c) && c->ProtocolSelector.Serial.channel > 0) {
1383             /* skip control channel */
1384             D("%s: disconnecting client %d",
1385               __FUNCTION__, c->ProtocolSelector.Serial.channel);
1386             D("%s: disconnecting client %d\n",
1387               __FUNCTION__, c->ProtocolSelector.Serial.channel);
1388             c->ProtocolSelector.Serial.channel = -1; /* do not send disconnect:<id> */
1389             qemud_client_disconnect(c);
1390         }
1391     }
1392 }
1393 
1394 /* handle control messages. This is used as the receive
1395  * callback for the special QemudClient setup to manage
1396  * channel 0.
1397  *
1398  * note that the message is zero-terminated for convenience
1399  * (i.e. msg[msglen] is a valid memory read that returns '\0')
1400  */
1401 static void
qemud_multiplexer_control_recv(void * opaque,uint8_t * msg,int msglen,QemudClient * client)1402 qemud_multiplexer_control_recv( void*         opaque,
1403                                 uint8_t*      msg,
1404                                 int           msglen,
1405                                 QemudClient*  client )
1406 {
1407     QemudMultiplexer*  mult   = opaque;
1408     uint8_t*           msgend = msg + msglen;
1409     char               tmp[64], *p=tmp, *end=p+sizeof(tmp);
1410 
1411     /* handle connection attempts.
1412      * the client message must be "connect:<service-name>:<id>"
1413      * where <id> is a 2-char hexadecimal string, which must be > 0
1414      */
1415     if (msglen > 8 && !memcmp(msg, "connect:", 8))
1416     {
1417         const char*    service_name = (const char*)msg + 8;
1418         int            channel, ret;
1419         char*          q;
1420 
1421         q = strchr(service_name, ':');
1422         if (q == NULL || q+3 != (char*)msgend) {
1423             D("%s: malformed connect message: '%.*s' (offset=%d)",
1424               __FUNCTION__, msglen, (const char*)msg, q ? q-(char*)msg : -1);
1425             return;
1426         }
1427         *q++ = 0;  /* zero-terminate service name */
1428         channel = hex2int((uint8_t*)q, 2);
1429         if (channel <= 0) {
1430             D("%s: malformed channel id '%.*s",
1431               __FUNCTION__, 2, q);
1432             return;
1433         }
1434 
1435         ret = qemud_multiplexer_connect(mult, service_name, channel);
1436         /* the answer can be one of:
1437          *    ok:connect:<id>
1438          *    ko:connect:<id>:<reason-for-failure>
1439          */
1440         if (ret < 0) {
1441             if (ret == -1) {
1442                 /* could not connect */
1443                 p = bufprint(tmp, end, "ko:connect:%02x:unknown service", channel);
1444             } else {
1445                 p = bufprint(tmp, end, "ko:connect:%02x:service busy", channel);
1446             }
1447         }
1448         else {
1449             p = bufprint(tmp, end, "ok:connect:%02x", channel);
1450         }
1451         qemud_serial_send(mult->serial, 0, 0, (uint8_t*)tmp, p-tmp);
1452         return;
1453     }
1454 
1455     /* handle client disconnections,
1456      * this message arrives when the client has closed the connection.
1457      * format: "disconnect:<id>" where <id> is a 2-hex channel id > 0
1458      */
1459     if (msglen == 13 && !memcmp(msg, "disconnect:", 11)) {
1460         int  channel_id = hex2int(msg+11, 2);
1461         if (channel_id <= 0) {
1462             D("%s: malformed disconnect channel id: '%.*s'",
1463               __FUNCTION__, 2, msg+11);
1464             return;
1465         }
1466         qemud_multiplexer_disconnect(mult, channel_id);
1467         return;
1468     }
1469 
1470 #if SUPPORT_LEGACY_QEMUD
1471     /* an ok:connect:<service>:<id> message can be received if we're
1472      * talking to a legacy qemud daemon, i.e. one running in a 1.0 or
1473      * 1.1 system image.
1474      *
1475      * we should treat is as a normal "connect:" attempt, except that
1476      * we must not send back any acknowledgment.
1477      */
1478     if (msglen > 11 && !memcmp(msg, "ok:connect:", 11)) {
1479         const char*  service_name = (const char*)msg + 11;
1480         char*        q            = strchr(service_name, ':');
1481         int          channel;
1482 
1483         if (q == NULL || q+3 != (char*)msgend) {
1484             D("%s: malformed legacy connect message: '%.*s' (offset=%d)",
1485               __FUNCTION__, msglen, (const char*)msg, q ? q-(char*)msg : -1);
1486             return;
1487         }
1488         *q++ = 0;  /* zero-terminate service name */
1489         channel = hex2int((uint8_t*)q, 2);
1490         if (channel <= 0) {
1491             D("%s: malformed legacy channel id '%.*s",
1492               __FUNCTION__, 2, q);
1493             return;
1494         }
1495 
1496         switch (mult->serial->version) {
1497         case QEMUD_VERSION_UNKNOWN:
1498             mult->serial->version = QEMUD_VERSION_LEGACY;
1499             D("%s: legacy qemud daemon detected.", __FUNCTION__);
1500             break;
1501 
1502         case QEMUD_VERSION_LEGACY:
1503             /* nothing unusual */
1504             break;
1505 
1506         default:
1507             D("%s: weird, ignoring legacy qemud control message: '%.*s'",
1508               __FUNCTION__, msglen, msg);
1509             return;
1510         }
1511 
1512         /* "hw-control" was called "control" in 1.0/1.1 */
1513         if (!strcmp(service_name,"control"))
1514             service_name = "hw-control";
1515 
1516         qemud_multiplexer_connect(mult, service_name, channel);
1517         return;
1518     }
1519 
1520     /* anything else, don't answer for legacy */
1521     if (mult->serial->version == QEMUD_VERSION_LEGACY)
1522         return;
1523 #endif /* SUPPORT_LEGACY_QEMUD */
1524 
1525     /* anything else is a problem */
1526     p = bufprint(tmp, end, "ko:unknown command");
1527     qemud_serial_send(mult->serial, 0, 0, (uint8_t*)tmp, p-tmp);
1528 }
1529 
1530 /* initialize the global QemudMultiplexer.
1531  */
1532 static void
qemud_multiplexer_init(QemudMultiplexer * mult,CharDriverState * serial_cs)1533 qemud_multiplexer_init( QemudMultiplexer*  mult,
1534                         CharDriverState*   serial_cs )
1535 {
1536     QemudClient*  control;
1537 
1538     /* initialize serial handler */
1539     qemud_serial_init( mult->serial,
1540                        serial_cs,
1541                        qemud_multiplexer_serial_recv,
1542                        mult );
1543 
1544     /* setup listener for channel 0 */
1545     control = qemud_client_alloc( 0,
1546                                   NULL,
1547                                   mult,
1548                                   qemud_multiplexer_control_recv,
1549                                   NULL, NULL, NULL,
1550                                   mult->serial,
1551                                   &mult->clients );
1552 }
1553 
1554 /* the global multiplexer state */
1555 static QemudMultiplexer  _multiplexer[1];
1556 
1557 /** HIGH-LEVEL API
1558  **/
1559 
1560 /* this function must be used in the serv_connect callback
1561  * of a given QemudService object (see qemud_service_register()
1562  * below). It is used to register a new QemudClient to acknowledge
1563  * a new client connection.
1564  *
1565  * 'clie_opaque', 'clie_recv' and 'clie_close' are used to
1566  * send incoming client messages to the corresponding service
1567  * implementation, or notify the service that a client has
1568  * disconnected.
1569  */
1570 QemudClient*
qemud_client_new(QemudService * service,int channelId,const char * client_param,void * clie_opaque,QemudClientRecv clie_recv,QemudClientClose clie_close,QemudClientSave clie_save,QemudClientLoad clie_load)1571 qemud_client_new( QemudService*     service,
1572                   int               channelId,
1573                   const char*       client_param,
1574                   void*             clie_opaque,
1575                   QemudClientRecv   clie_recv,
1576                   QemudClientClose  clie_close,
1577                   QemudClientSave   clie_save,
1578                   QemudClientLoad   clie_load )
1579 {
1580     QemudMultiplexer*  m = _multiplexer;
1581     QemudClient*       c = qemud_client_alloc( channelId,
1582                                                client_param,
1583                                                clie_opaque,
1584                                                clie_recv,
1585                                                clie_close,
1586                                                clie_save,
1587                                                clie_load,
1588                                                m->serial,
1589                                                &m->clients );
1590 
1591     qemud_service_add_client(service, c);
1592     return c;
1593 }
1594 
1595 /* Caches a service message into the client's descriptor.
1596  *
1597  * See comments on QemudPipeMessage structure for more info.
1598  */
1599 static void
_qemud_pipe_cache_buffer(QemudClient * client,const uint8_t * msg,int msglen)1600 _qemud_pipe_cache_buffer(QemudClient* client, const uint8_t*  msg, int  msglen)
1601 {
1602     QemudPipeMessage* buf;
1603     QemudPipeMessage** ins_at = &client->ProtocolSelector.Pipe.messages;
1604 
1605     /* Allocate descriptor big enough to contain message as well. */
1606     buf = (QemudPipeMessage*)malloc(msglen + sizeof(QemudPipeMessage));
1607     if (buf != NULL) {
1608         /* Message starts right after the descriptor. */
1609         buf->message = (uint8_t*)buf + sizeof(QemudPipeMessage);
1610         buf->size = msglen;
1611         memcpy(buf->message, msg, msglen);
1612         buf->offset = 0;
1613         buf->next = NULL;
1614         while (*ins_at != NULL) {
1615             ins_at = &(*ins_at)->next;
1616         }
1617         *ins_at = buf;
1618         /* Notify the pipe that there is data to read. */
1619         goldfish_pipe_wake(client->ProtocolSelector.Pipe.qemud_pipe->hwpipe,
1620                            PIPE_WAKE_READ);
1621     }
1622 }
1623 
1624 /* Sends service message to the client.
1625  */
1626 static void
_qemud_pipe_send(QemudClient * client,const uint8_t * msg,int msglen)1627 _qemud_pipe_send(QemudClient*  client, const uint8_t*  msg, int  msglen)
1628 {
1629     uint8_t   frame[FRAME_HEADER_SIZE];
1630     int       avail, len = msglen;
1631     int framing = client->framing;
1632 
1633     if (msglen <= 0)
1634         return;
1635 
1636     D("%s: len=%3d '%s'",
1637       __FUNCTION__, msglen, quote_bytes((const void*)msg, msglen));
1638 
1639     if (framing) {
1640         len += FRAME_HEADER_SIZE;
1641     }
1642 
1643     /* packetize the payload for the serial MTU */
1644     while (len > 0)
1645     {
1646         avail = len;
1647         if (avail > MAX_SERIAL_PAYLOAD)
1648             avail = MAX_SERIAL_PAYLOAD;
1649 
1650         /* insert frame header when needed */
1651         if (framing) {
1652             int2hex(frame, FRAME_HEADER_SIZE, msglen);
1653             T("%s: '%.*s'", __FUNCTION__, FRAME_HEADER_SIZE, frame);
1654             _qemud_pipe_cache_buffer(client, frame, FRAME_HEADER_SIZE);
1655             avail  -= FRAME_HEADER_SIZE;
1656             len    -= FRAME_HEADER_SIZE;
1657             framing = 0;
1658         }
1659 
1660         /* write message content */
1661         T("%s: '%.*s'", __FUNCTION__, avail, msg);
1662         _qemud_pipe_cache_buffer(client, msg, avail);
1663         msg += avail;
1664         len -= avail;
1665     }
1666 }
1667 
1668 /* this can be used by a service implementation to send an answer
1669  * or message to a specific client.
1670  */
1671 void
qemud_client_send(QemudClient * client,const uint8_t * msg,int msglen)1672 qemud_client_send ( QemudClient*  client, const uint8_t*  msg, int  msglen )
1673 {
1674     if (_is_pipe_client(client)) {
1675         _qemud_pipe_send(client, msg, msglen);
1676     } else {
1677         qemud_serial_send(client->ProtocolSelector.Serial.serial,
1678                           client->ProtocolSelector.Serial.channel,
1679                           client->framing != 0, msg, msglen);
1680     }
1681 }
1682 
1683 /* enable framing for this client. When TRUE, this will
1684  * use internally a simple 4-hexchar header before each
1685  * message exchanged through the serial port.
1686  */
1687 void
qemud_client_set_framing(QemudClient * client,int framing)1688 qemud_client_set_framing( QemudClient*  client, int  framing )
1689 {
1690     /* release dynamic buffer if we're disabling framing */
1691     if (client->framing) {
1692         if (!client->need_header) {
1693             AFREE(client->payload->buff);
1694             client->need_header = 1;
1695         }
1696     }
1697     client->framing = !!framing;
1698 }
1699 
1700 /* this can be used by a service implementation to close a
1701  * specific client connection.
1702  */
1703 void
qemud_client_close(QemudClient * client)1704 qemud_client_close( QemudClient*  client )
1705 {
1706     qemud_client_disconnect(client);
1707 }
1708 
1709 
1710 /** SNAPSHOT SUPPORT
1711  **/
1712 
1713 /* Saves the number of clients.
1714  */
1715 static void
qemud_client_save_count(QEMUFile * f,QemudClient * c)1716 qemud_client_save_count(QEMUFile* f, QemudClient* c)
1717 {
1718     unsigned int client_count = 0;
1719     for( ; c; c = c->next)   // walk over linked list
1720         // skip control channel, which is not saved
1721         if (_is_pipe_client(c) || c->ProtocolSelector.Serial.channel > 0)
1722             client_count++;
1723 
1724     qemu_put_be32(f, client_count);
1725 }
1726 
1727 /* Saves the number of services currently available.
1728  */
1729 static void
qemud_service_save_count(QEMUFile * f,QemudService * s)1730 qemud_service_save_count(QEMUFile* f, QemudService* s)
1731 {
1732     unsigned int service_count = 0;
1733     for( ; s; s = s->next )  // walk over linked list
1734         service_count++;
1735 
1736     qemu_put_be32(f, service_count);
1737 }
1738 
1739 /* Save QemuD state to snapshot.
1740  *
1741  * The control channel has no state of its own, other than the local variables
1742  * in qemud_multiplexer_control_recv. We can therefore safely skip saving it,
1743  * which spares us dealing with the exception of a client not connected to a
1744  * service.
1745  */
1746 static void
qemud_save(QEMUFile * f,void * opaque)1747 qemud_save(QEMUFile* f, void* opaque)
1748 {
1749     QemudMultiplexer *m = opaque;
1750 
1751     qemud_serial_save(f, m->serial);
1752 
1753     /* save service states */
1754     qemud_service_save_count(f, m->services);
1755     QemudService *s;
1756     for (s = m->services; s; s = s->next)
1757         qemud_service_save(f, s);
1758 
1759     /* save client channels */
1760     qemud_client_save_count(f, m->clients);
1761     QemudClient *c;
1762     for (c = m->clients; c; c = c->next) {
1763         /* skip control channel client */
1764         if (_is_pipe_client(c) || c->ProtocolSelector.Serial.channel > 0) {
1765             qemud_client_save(f, c);
1766         }
1767     }
1768 
1769 }
1770 
1771 
1772 /* Checks whether the same services are available at this point as when the
1773  * snapshot was made.
1774  */
1775 static int
qemud_load_services(QEMUFile * f,QemudService * current_services)1776 qemud_load_services( QEMUFile*  f, QemudService*  current_services )
1777 {
1778     int i, ret;
1779     int service_count = qemu_get_be32(f);
1780     for (i = 0; i < service_count; i++) {
1781         if ((ret = qemud_service_load(f, current_services)))
1782             return ret;
1783     }
1784 
1785     return 0;
1786 }
1787 
1788 /* Removes all active non-control clients, then creates new ones with state
1789  * taken from the snapshot.
1790  *
1791  * We do not send "disconnect" commands, over the channel. If we did, we might
1792  * stop clients in the restored guest, resulting in an incorrect restore.
1793  *
1794  * Instead, we silently replace the clients that were running before the
1795  * restore with new clients, whose state we copy from the snapshot. Since
1796  * everything is multiplexed over one link, only the multiplexer notices the
1797  * changes, there is no communication with the guest.
1798  */
1799 static int
qemud_load_clients(QEMUFile * f,QemudMultiplexer * m,int version)1800 qemud_load_clients(QEMUFile* f, QemudMultiplexer* m, int version )
1801 {
1802     /* Remove all clients, except on the control channel.*/
1803     qemud_multiplexer_disconnect_noncontrol(m);
1804 
1805     /* Load clients from snapshot */
1806     int client_count = qemu_get_be32(f);
1807     int i, ret;
1808     for (i = 0; i < client_count; i++) {
1809         if ((ret = qemud_client_load(f, m->services, version))) {
1810             return ret;
1811         }
1812     }
1813 
1814     return 0;
1815 }
1816 
1817 /* Load QemuD state from file.
1818  */
1819 static int
qemud_load(QEMUFile * f,void * opaque,int version)1820 qemud_load(QEMUFile *f, void* opaque, int version)
1821 {
1822     QemudMultiplexer *m = opaque;
1823 
1824     int ret;
1825 
1826     if ((ret = qemud_serial_load(f, m->serial)))
1827         return ret;
1828     if ((ret = qemud_load_services(f, m->services)))
1829         return ret;
1830     if ((ret = qemud_load_clients(f, m, version)))
1831         return ret;
1832 
1833     return 0;
1834 }
1835 
1836 /*------------------------------------------------------------------------------
1837  *
1838  * QEMUD PIPE service callbacks
1839  *
1840  * ----------------------------------------------------------------------------*/
1841 
1842 /* This is a callback that gets invoked when guest is connecting to the service.
1843  *
1844  * Here we will create a new client as well as pipe descriptor representing new
1845  * connection.
1846  */
1847 static void*
_qemudPipe_init(void * hwpipe,void * _looper,const char * args)1848 _qemudPipe_init(void* hwpipe, void* _looper, const char* args)
1849 {
1850     QemudMultiplexer *m = _multiplexer;
1851     QemudService* sv = m->services;
1852     QemudClient* client;
1853     QemudPipe* pipe = NULL;
1854     char service_name[512];
1855     const char* client_args;
1856     size_t srv_name_len;
1857 
1858     /* 'args' passed in this callback represents name of the service the guest is
1859      * connecting to. It can't be NULL. */
1860     if (args == NULL) {
1861         D("%s: Missing address!", __FUNCTION__);
1862         return NULL;
1863     }
1864 
1865     /* 'args' contain service name, and optional parameters for the client that
1866      * is about to be created in this call. The parameters are separated from the
1867      * service name wit ':'. Separate service name from the client param. */
1868     client_args = strchr(args, ':');
1869     if (client_args != NULL) {
1870         srv_name_len = min(client_args - args, sizeof(service_name) - 1);
1871         client_args++;  // Past the ':'
1872         if (*client_args == '\0') {
1873             /* No actual parameters. */
1874             client_args = NULL;
1875         }
1876     } else {
1877         srv_name_len = min(strlen(args), sizeof(service_name) - 1);
1878     }
1879     memcpy(service_name, args, srv_name_len);
1880     service_name[srv_name_len] = '\0';
1881 
1882     /* Lookup registered service by its name. */
1883     while (sv != NULL && strcmp(sv->name, service_name)) {
1884         sv = sv->next;
1885     }
1886     if (sv == NULL) {
1887         D("%s: Service '%s' has not been registered!", __FUNCTION__, service_name);
1888         return NULL;
1889     }
1890 
1891     /* Create a client for this connection. -1 as a channel ID signals that this
1892      * is a pipe client. */
1893     client = qemud_service_connect_client(sv, -1, client_args);
1894     if (client != NULL) {
1895         ANEW0(pipe);
1896         pipe->hwpipe = hwpipe;
1897         pipe->looper = _looper;
1898         pipe->service = sv;
1899         pipe->client = client;
1900         client->ProtocolSelector.Pipe.qemud_pipe = pipe;
1901     }
1902 
1903     return pipe;
1904 }
1905 
1906 /* Called when the guest wants to close the channel.
1907 */
1908 static void
_qemudPipe_closeFromGuest(void * opaque)1909 _qemudPipe_closeFromGuest( void* opaque )
1910 {
1911     QemudPipe* pipe = opaque;
1912     QemudClient*  client = pipe->client;
1913     D("%s", __FUNCTION__);
1914     if (client != NULL) {
1915         qemud_client_disconnect(client);
1916     } else {
1917         D("%s: Unexpected NULL client", __FUNCTION__);
1918     }
1919 }
1920 
1921 /* Called when the guest has sent some data to the client.
1922  */
1923 static int
_qemudPipe_sendBuffers(void * opaque,const GoldfishPipeBuffer * buffers,int numBuffers)1924 _qemudPipe_sendBuffers(void* opaque,
1925                        const GoldfishPipeBuffer* buffers,
1926                        int numBuffers)
1927 {
1928     QemudPipe* pipe = opaque;
1929     QemudClient*  client = pipe->client;
1930     size_t transferred = 0;
1931 
1932     if (client == NULL) {
1933         D("%s: Unexpected NULL client", __FUNCTION__);
1934         return -1;
1935     }
1936 
1937     if (numBuffers == 1) {
1938         /* Simple case: all data are in one buffer. */
1939         D("%s: %s", __FUNCTION__, quote_bytes((char*)buffers->data, buffers->size));
1940         qemud_client_recv(client, buffers->data, buffers->size);
1941         transferred = buffers->size;
1942     } else {
1943         /* If there are multiple buffers involved, collect all data in one buffer
1944          * before calling the high level client. */
1945         uint8_t* msg, *wrk;
1946         int n;
1947         for (n = 0; n < numBuffers; n++) {
1948             transferred += buffers[n].size;
1949         }
1950         msg = malloc(transferred);
1951         wrk = msg;
1952         for (n = 0; n < numBuffers; n++) {
1953             memcpy(wrk, buffers[n].data, buffers[n].size);
1954             wrk += buffers[n].size;
1955         }
1956         D("%s: %s", __FUNCTION__, quote_bytes((char*)msg, transferred));
1957         qemud_client_recv(client, msg, transferred);
1958         free(msg);
1959     }
1960 
1961     return transferred;
1962 }
1963 
1964 /* Called when the guest is reading data from the client.
1965  */
1966 static int
_qemudPipe_recvBuffers(void * opaque,GoldfishPipeBuffer * buffers,int numBuffers)1967 _qemudPipe_recvBuffers(void* opaque, GoldfishPipeBuffer* buffers, int numBuffers)
1968 {
1969     QemudPipe* pipe = opaque;
1970     QemudClient*  client = pipe->client;
1971     QemudPipeMessage** msg_list;
1972     GoldfishPipeBuffer* buff = buffers;
1973     GoldfishPipeBuffer* endbuff = buffers + numBuffers;
1974     size_t sent_bytes = 0;
1975     size_t off_in_buff = 0;
1976 
1977     if (client == NULL) {
1978         D("%s: Unexpected NULL client", __FUNCTION__);
1979         return -1;
1980     }
1981 
1982     msg_list = &client->ProtocolSelector.Pipe.messages;
1983     if (*msg_list == NULL) {
1984         /* No data to send. Let it block until we wake it up with
1985          * PIPE_WAKE_READ when service sends data to the client. */
1986         return PIPE_ERROR_AGAIN;
1987     }
1988 
1989     /* Fill in goldfish buffers while they are still available, and there are
1990      * messages in the client's message list. */
1991     while (buff != endbuff && *msg_list != NULL) {
1992         QemudPipeMessage* msg = *msg_list;
1993         /* Message data fiting the current pipe's buffer. */
1994         size_t to_copy = min(msg->size - msg->offset, buff->size - off_in_buff);
1995         memcpy(buff->data + off_in_buff, msg->message + msg->offset, to_copy);
1996         /* Update offsets. */
1997         off_in_buff += to_copy;
1998         msg->offset += to_copy;
1999         sent_bytes += to_copy;
2000         if (msg->size == msg->offset) {
2001             /* We're done with the current message. Go to the next one. */
2002             *msg_list = msg->next;
2003             free(msg);
2004         }
2005         if (off_in_buff == buff->size) {
2006             /* Current pipe buffer is full. Continue with the next one. */
2007             buff++;
2008             off_in_buff = 0;
2009         }
2010     }
2011 
2012     D("%s: -> %u (of %u)", __FUNCTION__, sent_bytes, buffers->size);
2013 
2014     return sent_bytes;
2015 }
2016 
2017 static unsigned
_qemudPipe_poll(void * opaque)2018 _qemudPipe_poll(void* opaque)
2019 {
2020     QemudPipe* pipe = opaque;
2021     QemudClient*  client = pipe->client;
2022     unsigned ret = 0;
2023 
2024     if (client != NULL) {
2025         ret |= PIPE_POLL_OUT;
2026         if (client->ProtocolSelector.Pipe.messages != NULL) {
2027             ret |= PIPE_POLL_IN;
2028         }
2029     } else {
2030         D("%s: Unexpected NULL client", __FUNCTION__);
2031     }
2032 
2033     return ret;
2034 }
2035 
2036 static void
_qemudPipe_wakeOn(void * opaque,int flags)2037 _qemudPipe_wakeOn(void* opaque, int flags)
2038 {
2039     D("%s: -> %X", __FUNCTION__, flags);
2040 }
2041 
2042 /* QEMUD pipe functions.
2043  */
2044 static const GoldfishPipeFuncs _qemudPipe_funcs = {
2045     _qemudPipe_init,
2046     _qemudPipe_closeFromGuest,
2047     _qemudPipe_sendBuffers,
2048     _qemudPipe_recvBuffers,
2049     _qemudPipe_poll,
2050     _qemudPipe_wakeOn,
2051 };
2052 
2053 /* Initializes QEMUD pipe interface.
2054  */
2055 static void
_android_qemud_pipe_init(void)2056 _android_qemud_pipe_init(void)
2057 {
2058     static ABool _qemud_pipe_initialized = false;
2059 
2060     if (!_qemud_pipe_initialized) {
2061         goldfish_pipe_add_type( "qemud", looper_newCore(), &_qemudPipe_funcs );
2062         _qemud_pipe_initialized = true;
2063     }
2064 }
2065 
2066 /* this is the end of the serial charpipe that must be passed
2067  * to the emulated tty implementation. The other end of the
2068  * charpipe must be passed to qemud_multiplexer_init().
2069  */
2070 static CharDriverState*  android_qemud_cs;
2071 
2072 /* Initializes QEMUD serial interface.
2073  */
2074 static void
_android_qemud_serial_init(void)2075 _android_qemud_serial_init(void)
2076 {
2077     CharDriverState*    cs;
2078 
2079     if (android_qemud_cs != NULL)
2080         return;
2081 
2082     if (qemu_chr_open_charpipe( &android_qemud_cs, &cs ) < 0) {
2083         derror( "%s: can't create charpipe to serial port",
2084                 __FUNCTION__ );
2085         exit(1);
2086     }
2087 
2088     qemud_multiplexer_init(_multiplexer, cs);
2089 
2090     register_savevm( "qemud", 0, QEMUD_SAVE_VERSION,
2091                       qemud_save, qemud_load, _multiplexer);
2092 }
2093 
2094 extern void
android_qemud_init(void)2095 android_qemud_init( void )
2096 {
2097     D("%s", __FUNCTION__);
2098     /* We don't know in advance whether the guest system supports qemud pipes,
2099      * so we will initialize both qemud machineries, the legacy (over serial
2100      * port), and the new one (over qemu pipe). Then we let the guest to connect
2101      * via one, or the other. */
2102     _android_qemud_serial_init();
2103     _android_qemud_pipe_init();
2104 }
2105 
2106 /* return the serial charpipe endpoint that must be used
2107  * by the emulated tty implementation.
2108  */
android_qemud_get_cs(void)2109 CharDriverState*  android_qemud_get_cs( void )
2110 {
2111     if (android_qemud_cs == NULL)
2112         android_qemud_init();
2113 
2114     return android_qemud_cs;
2115 }
2116 
2117 /* this function is used to register a new named qemud-based
2118  * service. You must provide 'serv_opaque' and 'serv_connect'
2119  * which will be called whenever a new client tries to connect
2120  * to the services.
2121  *
2122  * 'serv_connect' shall return NULL if the connection is refused,
2123  * or a handle to a new QemudClient otherwise. The latter can be
2124  * created through qemud_client_new() defined above.
2125  *
2126  * 'max_clients' is the maximum number of clients accepted by
2127  * the service concurrently. If this value is 0, then any number
2128  * of clients can connect.
2129  */
2130 QemudService*
qemud_service_register(const char * service_name,int max_clients,void * serv_opaque,QemudServiceConnect serv_connect,QemudServiceSave serv_save,QemudServiceLoad serv_load)2131 qemud_service_register( const char*          service_name,
2132                         int                  max_clients,
2133                         void*                serv_opaque,
2134                         QemudServiceConnect  serv_connect,
2135                         QemudServiceSave     serv_save,
2136                         QemudServiceLoad     serv_load )
2137 {
2138     QemudService*      sv;
2139     QemudMultiplexer*  m  = _multiplexer;
2140 
2141     android_qemud_init();
2142 
2143     sv = qemud_service_new(service_name,
2144                            max_clients,
2145                            serv_opaque,
2146                            serv_connect,
2147                            serv_save,
2148                            serv_load,
2149                            &m->services);
2150     D("Registered QEMUD service %s", service_name);
2151     return sv;
2152 }
2153 
2154 /* broadcast a given message to all clients of a given QemudService
2155  */
2156 extern void
qemud_service_broadcast(QemudService * sv,const uint8_t * msg,int msglen)2157 qemud_service_broadcast( QemudService*  sv,
2158                          const uint8_t*  msg,
2159                          int             msglen )
2160 {
2161     QemudClient*  c;
2162 
2163     for (c = sv->clients; c; c = c->next_serv)
2164         qemud_client_send(c, msg, msglen);
2165 }
2166 
2167 
2168 
2169 /*
2170  * The following code is used for backwards compatibility reasons.
2171  * It allows you to implement a given qemud-based service through
2172  * a charpipe.
2173  *
2174  * In other words, this implements a QemudService and corresponding
2175  * QemudClient that connects a qemud client running in the emulated
2176  * system, to a CharDriverState object implemented through a charpipe.
2177  *
2178  *   QemudCharClient <===charpipe====> (char driver user)
2179  *
2180  * For example, this is used to implement the "gsm" service when the
2181  * modem emulation is provided through an external serial device.
2182  *
2183  * A QemudCharService can have only one client by definition.
2184  * There is no QemudCharClient object because we can store a single
2185  * CharDriverState handle in the 'opaque' field for simplicity.
2186  */
2187 
2188 typedef struct {
2189     QemudService*     service;
2190     CharDriverState*  cs;
2191 } QemudCharService;
2192 
2193 /* called whenever a new message arrives from a qemud client.
2194  * this simply sends the message through the charpipe to the user.
2195  */
2196 static void
_qemud_char_client_recv(void * opaque,uint8_t * msg,int msglen,QemudClient * client)2197 _qemud_char_client_recv( void*  opaque, uint8_t*  msg, int  msglen,
2198                          QemudClient*  client )
2199 {
2200     CharDriverState*  cs = opaque;
2201     qemu_chr_write(cs, msg, msglen);
2202 }
2203 
2204 /* we don't expect clients of char. services to exit. Just
2205  * print an error to signal an unexpected situation. We should
2206  * be able to recover from these though, so don't panic.
2207  */
2208 static void
_qemud_char_client_close(void * opaque)2209 _qemud_char_client_close( void*  opaque )
2210 
2211 {
2212     QemudClient* client = opaque;
2213 
2214     /* At this point modem driver still uses char pipe to communicate with
2215      * hw-qemud, while communication with the guest is done over qemu pipe.
2216      * So, when guest disconnects from the qemu pipe, and emulator-side client
2217      * goes through the disconnection process, this routine is called, since it
2218      * has been set to called during service registration. Unless modem driver
2219      * is changed to drop char pipe communication, this routine will be called
2220      * due to guest disconnection. As long as the client was a qemu pipe - based
2221      * client, it's fine, since we don't really need to do anything in this case.
2222      */
2223     if (!_is_pipe_client(client)) {
2224         derror("unexpected qemud char. channel close");
2225     }
2226 }
2227 
2228 
2229 /* called by the charpipe to know how much data can be read from
2230  * the user. Since we send everything directly to the serial port
2231  * we can return an arbitrary number.
2232  */
2233 static int
_qemud_char_service_can_read(void * opaque)2234 _qemud_char_service_can_read( void*  opaque )
2235 {
2236     return 8192;  /* whatever */
2237 }
2238 
2239 /* called to read data from the charpipe and send it to the client.
2240  * used qemud_service_broadcast() even if there is a single client
2241  * because we don't need a QemudCharClient object this way.
2242  */
2243 static void
_qemud_char_service_read(void * opaque,const uint8_t * from,int len)2244 _qemud_char_service_read( void*  opaque, const uint8_t*  from, int  len )
2245 {
2246     QemudService*  sv = opaque;
2247     qemud_service_broadcast( sv, from, len );
2248 }
2249 
2250 /* called when a qemud client tries to connect to a char. service.
2251  * we simply create a new client and open the charpipe to receive
2252  * data from it.
2253  */
2254 static QemudClient*
_qemud_char_service_connect(void * opaque,QemudService * sv,int channel,const char * client_param)2255 _qemud_char_service_connect(void*          opaque,
2256                             QemudService*  sv,
2257                             int            channel,
2258                             const char*    client_param )
2259 {
2260     CharDriverState*   cs = opaque;
2261     QemudClient*       c  = qemud_client_new( sv, channel, client_param,
2262                                               cs,
2263                                               _qemud_char_client_recv,
2264                                               _qemud_char_client_close,
2265                                               NULL, NULL );
2266 
2267     /* now we can open the gates :-) */
2268     qemu_chr_add_handlers( cs,
2269                            _qemud_char_service_can_read,
2270                            _qemud_char_service_read,
2271                            NULL,
2272                            sv );
2273 
2274     return c;
2275 }
2276 
2277 /* returns a charpipe endpoint that can be used by an emulated
2278  * device or external serial port to implement a char. service
2279  */
2280 int
android_qemud_get_channel(const char * name,CharDriverState ** pcs)2281 android_qemud_get_channel( const char*  name, CharDriverState* *pcs )
2282 {
2283     CharDriverState*   cs;
2284 
2285     if (qemu_chr_open_charpipe(&cs, pcs) < 0) {
2286         derror("can't open charpipe for '%s' qemud service", name);
2287         exit(2);
2288     }
2289     qemud_service_register(name, 1, cs, _qemud_char_service_connect, NULL, NULL);
2290     return 0;
2291 }
2292 
2293 /* set the character driver state for a given qemud communication channel. this
2294  * is used to attach the channel to an external char driver device directly.
2295  * returns 0 on success, -1 on error
2296  */
2297 int
android_qemud_set_channel(const char * name,CharDriverState * peer_cs)2298 android_qemud_set_channel( const char*  name, CharDriverState*  peer_cs )
2299 {
2300     CharDriverState*  char_buffer = qemu_chr_open_buffer(peer_cs);
2301 
2302     if (char_buffer == NULL)
2303         return -1;
2304 
2305     qemud_service_register(name, 1, char_buffer, _qemud_char_service_connect,
2306                            NULL, NULL);
2307     return 0;
2308 }
2309