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