1 #include <stdint.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <fcntl.h>
6 #include <errno.h>
7 #include <string.h>
8 #include <sys/socket.h>
9 #include <termios.h>
10 #include <cutils/sockets.h>
11
12 /*
13 * the qemud daemon program is only used within Android as a bridge
14 * between the emulator program and the emulated system. it really works as
15 * a simple stream multiplexer that works as follows:
16 *
17 * - qemud is started by init following instructions in
18 * /system/etc/init.goldfish.rc (i.e. it is never started on real devices)
19 *
20 * - qemud communicates with the emulator program through a single serial
21 * port, whose name is passed through a kernel boot parameter
22 * (e.g. android.qemud=ttyS1)
23 *
24 * - qemud binds one unix local stream socket (/dev/socket/qemud, created
25 * by init through /system/etc/init.goldfish.rc).
26 *
27 *
28 * emulator <==serial==> qemud <---> /dev/socket/qemud <-+--> client1
29 * |
30 * +--> client2
31 *
32 * - the special channel index 0 is used by the emulator and qemud only.
33 * other channel numbers correspond to clients. More specifically,
34 * connection are created like this:
35 *
36 * * the client connects to /dev/socket/qemud
37 *
38 * * the client sends the service name through the socket, as
39 * <service-name>
40 *
41 * * qemud creates a "Client" object internally, assigns it an
42 * internal unique channel number > 0, then sends a connection
43 * initiation request to the emulator (i.e. through channel 0):
44 *
45 * connect:<id>:<name>
46 *
47 * where <name> is the service name, and <id> is a 2-hexchar
48 * number corresponding to the channel number.
49 *
50 * * in case of success, the emulator responds through channel 0
51 * with:
52 *
53 * ok:connect:<id>
54 *
55 * after this, all messages between the client and the emulator
56 * are passed in pass-through mode.
57 *
58 * * if the emulator refuses the service connection, it will
59 * send the following through channel 0:
60 *
61 * ko:connect:<id>:reason-for-failure
62 *
63 * * If the client closes the connection, qemud sends the following
64 * to the emulator:
65 *
66 * disconnect:<id>
67 *
68 * The same message is the opposite direction if the emulator
69 * chooses to close the connection.
70 *
71 * * any command sent through channel 0 to the emulator that is
72 * not properly recognized will be answered by:
73 *
74 * ko:unknown command
75 *
76 *
77 * Internally, the daemon maintains a "Client" object for each client
78 * connection (i.e. accepting socket connection).
79 */
80
81 /* name of the single control socket used by the daemon */
82 #define CONTROL_SOCKET_NAME "qemud"
83
84 #define DEBUG 1
85 #define T_ACTIVE 0 /* set to 1 to dump traffic */
86
87 #if DEBUG
88 # define LOG_TAG "qemud"
89 # include <cutils/log.h>
90 # define D(...) LOGD(__VA_ARGS__)
91 #else
92 # define D(...) ((void)0)
93 # define T(...) ((void)0)
94 #endif
95
96 #if T_ACTIVE
97 # define T(...) D(__VA_ARGS__)
98 #else
99 # define T(...) ((void)0)
100 #endif
101
102 /** UTILITIES
103 **/
104
105 static void
fatal(const char * fmt,...)106 fatal( const char* fmt, ... )
107 {
108 va_list args;
109 va_start(args, fmt);
110 fprintf(stderr, "PANIC: ");
111 vfprintf(stderr, fmt, args);
112 fprintf(stderr, "\n" );
113 va_end(args);
114 exit(1);
115 }
116
117 static void*
xalloc(size_t sz)118 xalloc( size_t sz )
119 {
120 void* p;
121
122 if (sz == 0)
123 return NULL;
124
125 p = malloc(sz);
126 if (p == NULL)
127 fatal( "not enough memory" );
128
129 return p;
130 }
131
132 #define xnew(p) (p) = xalloc(sizeof(*(p)))
133
134 static void*
xalloc0(size_t sz)135 xalloc0( size_t sz )
136 {
137 void* p = xalloc(sz);
138 memset( p, 0, sz );
139 return p;
140 }
141
142 #define xnew0(p) (p) = xalloc0(sizeof(*(p)))
143
144 #define xfree(p) (free((p)), (p) = NULL)
145
146 static void*
xrealloc(void * block,size_t size)147 xrealloc( void* block, size_t size )
148 {
149 void* p = realloc( block, size );
150
151 if (p == NULL && size > 0)
152 fatal( "not enough memory" );
153
154 return p;
155 }
156
157 #define xrenew(p,count) (p) = xrealloc((p),sizeof(*(p))*(count))
158
159 static int
hex2int(const uint8_t * data,int len)160 hex2int( const uint8_t* data, int len )
161 {
162 int result = 0;
163 while (len > 0) {
164 int c = *data++;
165 unsigned d;
166
167 result <<= 4;
168 do {
169 d = (unsigned)(c - '0');
170 if (d < 10)
171 break;
172
173 d = (unsigned)(c - 'a');
174 if (d < 6) {
175 d += 10;
176 break;
177 }
178
179 d = (unsigned)(c - 'A');
180 if (d < 6) {
181 d += 10;
182 break;
183 }
184
185 return -1;
186 }
187 while (0);
188
189 result |= d;
190 len -= 1;
191 }
192 return result;
193 }
194
195
196 static void
int2hex(int value,uint8_t * to,int width)197 int2hex( int value, uint8_t* to, int width )
198 {
199 int nn = 0;
200 static const char hexchars[16] = "0123456789abcdef";
201
202 for ( --width; width >= 0; width--, nn++ ) {
203 to[nn] = hexchars[(value >> (width*4)) & 15];
204 }
205 }
206
207 static int
fd_read(int fd,void * to,int len)208 fd_read(int fd, void* to, int len)
209 {
210 int ret;
211
212 do {
213 ret = read(fd, to, len);
214 } while (ret < 0 && errno == EINTR);
215
216 return ret;
217 }
218
219 static int
fd_write(int fd,const void * from,int len)220 fd_write(int fd, const void* from, int len)
221 {
222 int ret;
223
224 do {
225 ret = write(fd, from, len);
226 } while (ret < 0 && errno == EINTR);
227
228 return ret;
229 }
230
231 static void
fd_setnonblock(int fd)232 fd_setnonblock(int fd)
233 {
234 int ret, flags;
235
236 do {
237 flags = fcntl(fd, F_GETFD);
238 } while (flags < 0 && errno == EINTR);
239
240 if (flags < 0) {
241 fatal( "%s: could not get flags for fd %d: %s",
242 __FUNCTION__, fd, strerror(errno) );
243 }
244
245 do {
246 ret = fcntl(fd, F_SETFD, flags | O_NONBLOCK);
247 } while (ret < 0 && errno == EINTR);
248
249 if (ret < 0) {
250 fatal( "%s: could not set fd %d to non-blocking: %s",
251 __FUNCTION__, fd, strerror(errno) );
252 }
253 }
254
255
256 static int
fd_accept(int fd)257 fd_accept(int fd)
258 {
259 struct sockaddr from;
260 socklen_t fromlen = sizeof(from);
261 int ret;
262
263 do {
264 ret = accept(fd, &from, &fromlen);
265 } while (ret < 0 && errno == EINTR);
266
267 return ret;
268 }
269
270 /** FD EVENT LOOP
271 **/
272
273 /* A Looper object is used to monitor activity on one or more
274 * file descriptors (e.g sockets).
275 *
276 * - call looper_add() to register a function that will be
277 * called when events happen on the file descriptor.
278 *
279 * - call looper_enable() or looper_disable() to enable/disable
280 * the set of monitored events for a given file descriptor.
281 *
282 * - call looper_del() to unregister a file descriptor.
283 * this does *not* close the file descriptor.
284 *
285 * Note that you can only provide a single function to handle
286 * all events related to a given file descriptor.
287
288 * You can call looper_enable/_disable/_del within a function
289 * callback.
290 */
291
292 /* the current implementation uses Linux's epoll facility
293 * the event mask we use are simply combinations of EPOLLIN
294 * EPOLLOUT, EPOLLHUP and EPOLLERR
295 */
296 #include <sys/epoll.h>
297
298 #define MAX_CHANNELS 16
299 #define MAX_EVENTS (MAX_CHANNELS+1) /* each channel + the serial fd */
300
301 /* the event handler function type, 'user' is a user-specific
302 * opaque pointer passed to looper_add().
303 */
304 typedef void (*EventFunc)( void* user, int events );
305
306 /* bit flags for the LoopHook structure.
307 *
308 * HOOK_PENDING means that an event happened on the
309 * corresponding file descriptor.
310 *
311 * HOOK_CLOSING is used to delay-close monitored
312 * file descriptors.
313 */
314 enum {
315 HOOK_PENDING = (1 << 0),
316 HOOK_CLOSING = (1 << 1),
317 };
318
319 /* A LoopHook structure is used to monitor a given
320 * file descriptor and record its event handler.
321 */
322 typedef struct {
323 int fd;
324 int wanted; /* events we are monitoring */
325 int events; /* events that occured */
326 int state; /* see HOOK_XXX constants */
327 void* ev_user; /* user-provided handler parameter */
328 EventFunc ev_func; /* event handler callback */
329 } LoopHook;
330
331 /* Looper is the main object modeling a looper object
332 */
333 typedef struct {
334 int epoll_fd;
335 int num_fds;
336 int max_fds;
337 struct epoll_event* events;
338 LoopHook* hooks;
339 } Looper;
340
341 /* initialize a looper object */
342 static void
looper_init(Looper * l)343 looper_init( Looper* l )
344 {
345 l->epoll_fd = epoll_create(4);
346 l->num_fds = 0;
347 l->max_fds = 0;
348 l->events = NULL;
349 l->hooks = NULL;
350 }
351
352 /* finalize a looper object */
353 static void
looper_done(Looper * l)354 looper_done( Looper* l )
355 {
356 xfree(l->events);
357 xfree(l->hooks);
358 l->max_fds = 0;
359 l->num_fds = 0;
360
361 close(l->epoll_fd);
362 l->epoll_fd = -1;
363 }
364
365 /* return the LoopHook corresponding to a given
366 * monitored file descriptor, or NULL if not found
367 */
368 static LoopHook*
looper_find(Looper * l,int fd)369 looper_find( Looper* l, int fd )
370 {
371 LoopHook* hook = l->hooks;
372 LoopHook* end = hook + l->num_fds;
373
374 for ( ; hook < end; hook++ ) {
375 if (hook->fd == fd)
376 return hook;
377 }
378 return NULL;
379 }
380
381 /* grow the arrays in the looper object */
382 static void
looper_grow(Looper * l)383 looper_grow( Looper* l )
384 {
385 int old_max = l->max_fds;
386 int new_max = old_max + (old_max >> 1) + 4;
387 int n;
388
389 xrenew( l->events, new_max );
390 xrenew( l->hooks, new_max );
391 l->max_fds = new_max;
392
393 /* now change the handles to all events */
394 for (n = 0; n < l->num_fds; n++) {
395 struct epoll_event ev;
396 LoopHook* hook = l->hooks + n;
397
398 ev.events = hook->wanted;
399 ev.data.ptr = hook;
400 epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
401 }
402 }
403
404 /* register a file descriptor and its event handler.
405 * no event mask will be enabled
406 */
407 static void
looper_add(Looper * l,int fd,EventFunc func,void * user)408 looper_add( Looper* l, int fd, EventFunc func, void* user )
409 {
410 struct epoll_event ev;
411 LoopHook* hook;
412
413 if (l->num_fds >= l->max_fds)
414 looper_grow(l);
415
416 hook = l->hooks + l->num_fds;
417
418 hook->fd = fd;
419 hook->ev_user = user;
420 hook->ev_func = func;
421 hook->state = 0;
422 hook->wanted = 0;
423 hook->events = 0;
424
425 fd_setnonblock(fd);
426
427 ev.events = 0;
428 ev.data.ptr = hook;
429 epoll_ctl( l->epoll_fd, EPOLL_CTL_ADD, fd, &ev );
430
431 l->num_fds += 1;
432 }
433
434 /* unregister a file descriptor and its event handler
435 */
436 static void
looper_del(Looper * l,int fd)437 looper_del( Looper* l, int fd )
438 {
439 LoopHook* hook = looper_find( l, fd );
440
441 if (!hook) {
442 D( "%s: invalid fd: %d", __FUNCTION__, fd );
443 return;
444 }
445 /* don't remove the hook yet */
446 hook->state |= HOOK_CLOSING;
447
448 epoll_ctl( l->epoll_fd, EPOLL_CTL_DEL, fd, NULL );
449 }
450
451 /* enable monitoring of certain events for a file
452 * descriptor. This adds 'events' to the current
453 * event mask
454 */
455 static void
looper_enable(Looper * l,int fd,int events)456 looper_enable( Looper* l, int fd, int events )
457 {
458 LoopHook* hook = looper_find( l, fd );
459
460 if (!hook) {
461 D("%s: invalid fd: %d", __FUNCTION__, fd );
462 return;
463 }
464
465 if (events & ~hook->wanted) {
466 struct epoll_event ev;
467
468 hook->wanted |= events;
469 ev.events = hook->wanted;
470 ev.data.ptr = hook;
471
472 epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
473 }
474 }
475
476 /* disable monitoring of certain events for a file
477 * descriptor. This ignores events that are not
478 * currently enabled.
479 */
480 static void
looper_disable(Looper * l,int fd,int events)481 looper_disable( Looper* l, int fd, int events )
482 {
483 LoopHook* hook = looper_find( l, fd );
484
485 if (!hook) {
486 D("%s: invalid fd: %d", __FUNCTION__, fd );
487 return;
488 }
489
490 if (events & hook->wanted) {
491 struct epoll_event ev;
492
493 hook->wanted &= ~events;
494 ev.events = hook->wanted;
495 ev.data.ptr = hook;
496
497 epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
498 }
499 }
500
501 /* wait until an event occurs on one of the registered file
502 * descriptors. Only returns in case of error !!
503 */
504 static void
looper_loop(Looper * l)505 looper_loop( Looper* l )
506 {
507 for (;;) {
508 int n, count;
509
510 do {
511 count = epoll_wait( l->epoll_fd, l->events, l->num_fds, -1 );
512 } while (count < 0 && errno == EINTR);
513
514 if (count < 0) {
515 D("%s: error: %s", __FUNCTION__, strerror(errno) );
516 return;
517 }
518
519 if (count == 0) {
520 D("%s: huh ? epoll returned count=0", __FUNCTION__);
521 continue;
522 }
523
524 /* mark all pending hooks */
525 for (n = 0; n < count; n++) {
526 LoopHook* hook = l->events[n].data.ptr;
527 hook->state = HOOK_PENDING;
528 hook->events = l->events[n].events;
529 }
530
531 /* execute hook callbacks. this may change the 'hooks'
532 * and 'events' array, as well as l->num_fds, so be careful */
533 for (n = 0; n < l->num_fds; n++) {
534 LoopHook* hook = l->hooks + n;
535 if (hook->state & HOOK_PENDING) {
536 hook->state &= ~HOOK_PENDING;
537 hook->ev_func( hook->ev_user, hook->events );
538 }
539 }
540
541 /* now remove all the hooks that were closed by
542 * the callbacks */
543 for (n = 0; n < l->num_fds;) {
544 LoopHook* hook = l->hooks + n;
545
546 if (!(hook->state & HOOK_CLOSING)) {
547 n++;
548 continue;
549 }
550
551 hook[0] = l->hooks[l->num_fds-1];
552 l->num_fds -= 1;
553 }
554 }
555 }
556
557 #if T_ACTIVE
558 char*
quote(const void * data,int len)559 quote( const void* data, int len )
560 {
561 const char* p = data;
562 const char* end = p + len;
563 int count = 0;
564 int phase = 0;
565 static char* buff = NULL;
566
567 for (phase = 0; phase < 2; phase++) {
568 if (phase != 0) {
569 xfree(buff);
570 buff = xalloc(count+1);
571 }
572 count = 0;
573 for (p = data; p < end; p++) {
574 int c = *p;
575
576 if (c == '\\') {
577 if (phase != 0) {
578 buff[count] = buff[count+1] = '\\';
579 }
580 count += 2;
581 continue;
582 }
583
584 if (c >= 32 && c < 127) {
585 if (phase != 0)
586 buff[count] = c;
587 count += 1;
588 continue;
589 }
590
591
592 if (c == '\t') {
593 if (phase != 0) {
594 memcpy(buff+count, "<TAB>", 5);
595 }
596 count += 5;
597 continue;
598 }
599 if (c == '\n') {
600 if (phase != 0) {
601 memcpy(buff+count, "<LN>", 4);
602 }
603 count += 4;
604 continue;
605 }
606 if (c == '\r') {
607 if (phase != 0) {
608 memcpy(buff+count, "<CR>", 4);
609 }
610 count += 4;
611 continue;
612 }
613
614 if (phase != 0) {
615 buff[count+0] = '\\';
616 buff[count+1] = 'x';
617 buff[count+2] = "0123456789abcdef"[(c >> 4) & 15];
618 buff[count+3] = "0123456789abcdef"[ (c) & 15];
619 }
620 count += 4;
621 }
622 }
623 buff[count] = 0;
624 return buff;
625 }
626 #endif /* T_ACTIVE */
627
628 /** PACKETS
629 **
630 ** We need a way to buffer data before it can be sent to the
631 ** corresponding file descriptor. We use linked list of Packet
632 ** objects to do this.
633 **/
634
635 typedef struct Packet Packet;
636
637 #define MAX_PAYLOAD 4000
638
639 struct Packet {
640 Packet* next;
641 int len;
642 int channel;
643 uint8_t data[ MAX_PAYLOAD ];
644 };
645
646 /* we expect to alloc/free a lot of packets during
647 * operations so use a single linked list of free packets
648 * to keep things speedy and simple.
649 */
650 static Packet* _free_packets;
651
652 /* Allocate a packet */
653 static Packet*
packet_alloc(void)654 packet_alloc(void)
655 {
656 Packet* p = _free_packets;
657 if (p != NULL) {
658 _free_packets = p->next;
659 } else {
660 xnew(p);
661 }
662 p->next = NULL;
663 p->len = 0;
664 p->channel = -1;
665 return p;
666 }
667
668 /* Release a packet. This takes the address of a packet
669 * pointer that will be set to NULL on exit (avoids
670 * referencing dangling pointers in case of bugs)
671 */
672 static void
packet_free(Packet ** ppacket)673 packet_free( Packet* *ppacket )
674 {
675 Packet* p = *ppacket;
676 if (p) {
677 p->next = _free_packets;
678 _free_packets = p;
679 *ppacket = NULL;
680 }
681 }
682
683 /** PACKET RECEIVER
684 **
685 ** Simple abstraction for something that can receive a packet
686 ** from a FDHandler (see below) or something else.
687 **
688 ** Send a packet to it with 'receiver_post'
689 **
690 ** Call 'receiver_close' to indicate that the corresponding
691 ** packet source was closed.
692 **/
693
694 typedef void (*PostFunc) ( void* user, Packet* p );
695 typedef void (*CloseFunc)( void* user );
696
697 typedef struct {
698 PostFunc post;
699 CloseFunc close;
700 void* user;
701 } Receiver;
702
703 /* post a packet to a receiver. Note that this transfers
704 * ownership of the packet to the receiver.
705 */
706 static __inline__ void
receiver_post(Receiver * r,Packet * p)707 receiver_post( Receiver* r, Packet* p )
708 {
709 if (r->post)
710 r->post( r->user, p );
711 else
712 packet_free(&p);
713 }
714
715 /* tell a receiver the packet source was closed.
716 * this will also prevent further posting to the
717 * receiver.
718 */
719 static __inline__ void
receiver_close(Receiver * r)720 receiver_close( Receiver* r )
721 {
722 if (r->close) {
723 r->close( r->user );
724 r->close = NULL;
725 }
726 r->post = NULL;
727 }
728
729
730 /** FD HANDLERS
731 **
732 ** these are smart listeners that send incoming packets to a receiver
733 ** and can queue one or more outgoing packets and send them when
734 ** possible to the FD.
735 **
736 ** note that we support clean shutdown of file descriptors,
737 ** i.e. we try to send all outgoing packets before destroying
738 ** the FDHandler.
739 **/
740
741 typedef struct FDHandler FDHandler;
742 typedef struct FDHandlerList FDHandlerList;
743
744 struct FDHandler {
745 int fd;
746 FDHandlerList* list;
747 char closing;
748 Receiver receiver[1];
749
750 /* queue of outgoing packets */
751 int out_pos;
752 Packet* out_first;
753 Packet** out_ptail;
754
755 FDHandler* next;
756 FDHandler** pref;
757
758 };
759
760 struct FDHandlerList {
761 /* the looper that manages the fds */
762 Looper* looper;
763
764 /* list of active FDHandler objects */
765 FDHandler* active;
766
767 /* list of closing FDHandler objects.
768 * these are waiting to push their
769 * queued packets to the fd before
770 * freeing themselves.
771 */
772 FDHandler* closing;
773
774 };
775
776 /* remove a FDHandler from its current list */
777 static void
fdhandler_remove(FDHandler * f)778 fdhandler_remove( FDHandler* f )
779 {
780 f->pref[0] = f->next;
781 if (f->next)
782 f->next->pref = f->pref;
783 }
784
785 /* add a FDHandler to a given list */
786 static void
fdhandler_prepend(FDHandler * f,FDHandler ** list)787 fdhandler_prepend( FDHandler* f, FDHandler** list )
788 {
789 f->next = list[0];
790 f->pref = list;
791 list[0] = f;
792 if (f->next)
793 f->next->pref = &f->next;
794 }
795
796 /* initialize a FDHandler list */
797 static void
fdhandler_list_init(FDHandlerList * list,Looper * looper)798 fdhandler_list_init( FDHandlerList* list, Looper* looper )
799 {
800 list->looper = looper;
801 list->active = NULL;
802 list->closing = NULL;
803 }
804
805
806 /* close a FDHandler (and free it). Note that this will not
807 * perform a graceful shutdown, i.e. all packets in the
808 * outgoing queue will be immediately free.
809 *
810 * this *will* notify the receiver that the file descriptor
811 * was closed.
812 *
813 * you should call fdhandler_shutdown() if you want to
814 * notify the FDHandler that its packet source is closed.
815 */
816 static void
fdhandler_close(FDHandler * f)817 fdhandler_close( FDHandler* f )
818 {
819 /* notify receiver */
820 receiver_close(f->receiver);
821
822 /* remove the handler from its list */
823 fdhandler_remove(f);
824
825 /* get rid of outgoing packet queue */
826 if (f->out_first != NULL) {
827 Packet* p;
828 while ((p = f->out_first) != NULL) {
829 f->out_first = p->next;
830 packet_free(&p);
831 }
832 }
833
834 /* get rid of file descriptor */
835 if (f->fd >= 0) {
836 looper_del( f->list->looper, f->fd );
837 close(f->fd);
838 f->fd = -1;
839 }
840
841 f->list = NULL;
842 xfree(f);
843 }
844
845 /* Ask the FDHandler to cleanly shutdown the connection,
846 * i.e. send any pending outgoing packets then auto-free
847 * itself.
848 */
849 static void
fdhandler_shutdown(FDHandler * f)850 fdhandler_shutdown( FDHandler* f )
851 {
852 /* prevent later fdhandler_close() to
853 * call the receiver's close.
854 */
855 f->receiver->close = NULL;
856
857 if (f->out_first != NULL && !f->closing)
858 {
859 /* move the handler to the 'closing' list */
860 f->closing = 1;
861 fdhandler_remove(f);
862 fdhandler_prepend(f, &f->list->closing);
863 return;
864 }
865
866 fdhandler_close(f);
867 }
868
869 /* Enqueue a new packet that the FDHandler will
870 * send through its file descriptor.
871 */
872 static void
fdhandler_enqueue(FDHandler * f,Packet * p)873 fdhandler_enqueue( FDHandler* f, Packet* p )
874 {
875 Packet* first = f->out_first;
876
877 p->next = NULL;
878 f->out_ptail[0] = p;
879 f->out_ptail = &p->next;
880
881 if (first == NULL) {
882 f->out_pos = 0;
883 looper_enable( f->list->looper, f->fd, EPOLLOUT );
884 }
885 }
886
887
888 /* FDHandler file descriptor event callback for read/write ops */
889 static void
fdhandler_event(FDHandler * f,int events)890 fdhandler_event( FDHandler* f, int events )
891 {
892 int len;
893
894 /* in certain cases, it's possible to have both EPOLLIN and
895 * EPOLLHUP at the same time. This indicates that there is incoming
896 * data to read, but that the connection was nonetheless closed
897 * by the sender. Be sure to read the data before closing
898 * the receiver to avoid packet loss.
899 */
900
901 if (events & EPOLLIN) {
902 Packet* p = packet_alloc();
903 int len;
904
905 if ((len = fd_read(f->fd, p->data, MAX_PAYLOAD)) < 0) {
906 D("%s: can't recv: %s", __FUNCTION__, strerror(errno));
907 packet_free(&p);
908 } else if (len > 0) {
909 p->len = len;
910 p->channel = -101; /* special debug value, not used */
911 receiver_post( f->receiver, p );
912 }
913 }
914
915 if (events & (EPOLLHUP|EPOLLERR)) {
916 /* disconnection */
917 D("%s: disconnect on fd %d", __FUNCTION__, f->fd);
918 fdhandler_close(f);
919 return;
920 }
921
922 if (events & EPOLLOUT && f->out_first) {
923 Packet* p = f->out_first;
924 int avail, len;
925
926 avail = p->len - f->out_pos;
927 if ((len = fd_write(f->fd, p->data + f->out_pos, avail)) < 0) {
928 D("%s: can't send: %s", __FUNCTION__, strerror(errno));
929 } else {
930 f->out_pos += len;
931 if (f->out_pos >= p->len) {
932 f->out_pos = 0;
933 f->out_first = p->next;
934 packet_free(&p);
935 if (f->out_first == NULL) {
936 f->out_ptail = &f->out_first;
937 looper_disable( f->list->looper, f->fd, EPOLLOUT );
938 }
939 }
940 }
941 }
942 }
943
944
945 /* Create a new FDHandler that monitors read/writes */
946 static FDHandler*
fdhandler_new(int fd,FDHandlerList * list,Receiver * receiver)947 fdhandler_new( int fd,
948 FDHandlerList* list,
949 Receiver* receiver )
950 {
951 FDHandler* f = xalloc0(sizeof(*f));
952
953 f->fd = fd;
954 f->list = list;
955 f->receiver[0] = receiver[0];
956 f->out_first = NULL;
957 f->out_ptail = &f->out_first;
958 f->out_pos = 0;
959
960 fdhandler_prepend(f, &list->active);
961
962 looper_add( list->looper, fd, (EventFunc) fdhandler_event, f );
963 looper_enable( list->looper, fd, EPOLLIN );
964
965 return f;
966 }
967
968
969 /* event callback function to monitor accepts() on server sockets.
970 * the convention used here is that the receiver will receive a
971 * dummy packet with the new client socket in p->channel
972 */
973 static void
fdhandler_accept_event(FDHandler * f,int events)974 fdhandler_accept_event( FDHandler* f, int events )
975 {
976 if (events & EPOLLIN) {
977 /* this is an accept - send a dummy packet to the receiver */
978 Packet* p = packet_alloc();
979
980 D("%s: accepting on fd %d", __FUNCTION__, f->fd);
981 p->data[0] = 1;
982 p->len = 1;
983 p->channel = fd_accept(f->fd);
984 if (p->channel < 0) {
985 D("%s: accept failed ?: %s", __FUNCTION__, strerror(errno));
986 packet_free(&p);
987 return;
988 }
989 receiver_post( f->receiver, p );
990 }
991
992 if (events & (EPOLLHUP|EPOLLERR)) {
993 /* disconnecting !! */
994 D("%s: closing accept fd %d", __FUNCTION__, f->fd);
995 fdhandler_close(f);
996 return;
997 }
998 }
999
1000
1001 /* Create a new FDHandler used to monitor new connections on a
1002 * server socket. The receiver must expect the new connection
1003 * fd in the 'channel' field of a dummy packet.
1004 */
1005 static FDHandler*
fdhandler_new_accept(int fd,FDHandlerList * list,Receiver * receiver)1006 fdhandler_new_accept( int fd,
1007 FDHandlerList* list,
1008 Receiver* receiver )
1009 {
1010 FDHandler* f = xalloc0(sizeof(*f));
1011
1012 f->fd = fd;
1013 f->list = list;
1014 f->receiver[0] = receiver[0];
1015
1016 fdhandler_prepend(f, &list->active);
1017
1018 looper_add( list->looper, fd, (EventFunc) fdhandler_accept_event, f );
1019 looper_enable( list->looper, fd, EPOLLIN );
1020 listen( fd, 5 );
1021
1022 return f;
1023 }
1024
1025 /** SERIAL CONNECTION STATE
1026 **
1027 ** The following is used to handle the framing protocol
1028 ** used on the serial port connection.
1029 **/
1030
1031 /* each packet is made of a 6 byte header followed by a payload
1032 * the header looks like:
1033 *
1034 * offset size description
1035 * 0 2 a 2-byte hex string for the channel number
1036 * 4 4 a 4-char hex string for the size of the payload
1037 * 6 n the payload itself
1038 */
1039 #define HEADER_SIZE 6
1040 #define CHANNEL_OFFSET 0
1041 #define LENGTH_OFFSET 2
1042 #define CHANNEL_SIZE 2
1043 #define LENGTH_SIZE 4
1044
1045 #define CHANNEL_CONTROL 0
1046
1047 /* The Serial object receives data from the serial port,
1048 * extracts the payload size and channel index, then sends
1049 * the resulting messages as a packet to a generic receiver.
1050 *
1051 * You can also use serial_send to send a packet through
1052 * the serial port.
1053 */
1054 typedef struct Serial {
1055 FDHandler* fdhandler; /* used to monitor serial port fd */
1056 Receiver receiver[1]; /* send payload there */
1057 int in_len; /* current bytes in input packet */
1058 int in_datalen; /* payload size, or 0 when reading header */
1059 int in_channel; /* extracted channel number */
1060 Packet* in_packet; /* used to read incoming packets */
1061 } Serial;
1062
1063
1064 /* a callback called when the serial port's fd is closed */
1065 static void
serial_fd_close(Serial * s)1066 serial_fd_close( Serial* s )
1067 {
1068 fatal("unexpected serial port close !!");
1069 }
1070
1071 static void
serial_dump(Packet * p,const char * funcname)1072 serial_dump( Packet* p, const char* funcname )
1073 {
1074 T("%s: %03d bytes: '%s'",
1075 funcname, p->len, quote(p->data, p->len));
1076 }
1077
1078 /* a callback called when a packet arrives from the serial port's FDHandler.
1079 *
1080 * This will essentially parse the header, extract the channel number and
1081 * the payload size and store them in 'in_datalen' and 'in_channel'.
1082 *
1083 * After that, the payload is sent to the receiver once completed.
1084 */
1085 static void
serial_fd_receive(Serial * s,Packet * p)1086 serial_fd_receive( Serial* s, Packet* p )
1087 {
1088 int rpos = 0, rcount = p->len;
1089 Packet* inp = s->in_packet;
1090 int inpos = s->in_len;
1091
1092 serial_dump( p, __FUNCTION__ );
1093
1094 while (rpos < rcount)
1095 {
1096 int avail = rcount - rpos;
1097
1098 /* first, try to read the header */
1099 if (s->in_datalen == 0) {
1100 int wanted = HEADER_SIZE - inpos;
1101 if (avail > wanted)
1102 avail = wanted;
1103
1104 memcpy( inp->data + inpos, p->data + rpos, avail );
1105 inpos += avail;
1106 rpos += avail;
1107
1108 if (inpos == HEADER_SIZE) {
1109 s->in_datalen = hex2int( inp->data + LENGTH_OFFSET, LENGTH_SIZE );
1110 s->in_channel = hex2int( inp->data + CHANNEL_OFFSET, CHANNEL_SIZE );
1111
1112 if (s->in_datalen <= 0) {
1113 D("ignoring %s packet from serial port",
1114 s->in_datalen ? "empty" : "malformed");
1115 s->in_datalen = 0;
1116 }
1117
1118 //D("received %d bytes packet for channel %d", s->in_datalen, s->in_channel);
1119 inpos = 0;
1120 }
1121 }
1122 else /* then, populate the packet itself */
1123 {
1124 int wanted = s->in_datalen - inpos;
1125
1126 if (avail > wanted)
1127 avail = wanted;
1128
1129 memcpy( inp->data + inpos, p->data + rpos, avail );
1130 inpos += avail;
1131 rpos += avail;
1132
1133 if (inpos == s->in_datalen) {
1134 if (s->in_channel < 0) {
1135 D("ignoring %d bytes addressed to channel %d",
1136 inpos, s->in_channel);
1137 } else {
1138 inp->len = inpos;
1139 inp->channel = s->in_channel;
1140 receiver_post( s->receiver, inp );
1141 s->in_packet = inp = packet_alloc();
1142 }
1143 s->in_datalen = 0;
1144 inpos = 0;
1145 }
1146 }
1147 }
1148 s->in_len = inpos;
1149 packet_free(&p);
1150 }
1151
1152
1153 /* send a packet to the serial port.
1154 * this assumes that p->len and p->channel contain the payload's
1155 * size and channel and will add the appropriate header.
1156 */
1157 static void
serial_send(Serial * s,Packet * p)1158 serial_send( Serial* s, Packet* p )
1159 {
1160 Packet* h = packet_alloc();
1161
1162 //D("sending to serial %d bytes from channel %d: '%.*s'", p->len, p->channel, p->len, p->data);
1163
1164 /* insert a small header before this packet */
1165 h->len = HEADER_SIZE;
1166 int2hex( p->len, h->data + LENGTH_OFFSET, LENGTH_SIZE );
1167 int2hex( p->channel, h->data + CHANNEL_OFFSET, CHANNEL_SIZE );
1168
1169 serial_dump( h, __FUNCTION__ );
1170 serial_dump( p, __FUNCTION__ );
1171
1172 fdhandler_enqueue( s->fdhandler, h );
1173 fdhandler_enqueue( s->fdhandler, p );
1174 }
1175
1176
1177 /* initialize serial reader */
1178 static void
serial_init(Serial * s,int fd,FDHandlerList * list,Receiver * receiver)1179 serial_init( Serial* s,
1180 int fd,
1181 FDHandlerList* list,
1182 Receiver* receiver )
1183 {
1184 Receiver recv;
1185
1186 recv.user = s;
1187 recv.post = (PostFunc) serial_fd_receive;
1188 recv.close = (CloseFunc) serial_fd_close;
1189
1190 s->receiver[0] = receiver[0];
1191
1192 s->fdhandler = fdhandler_new( fd, list, &recv );
1193 s->in_len = 0;
1194 s->in_datalen = 0;
1195 s->in_channel = 0;
1196 s->in_packet = packet_alloc();
1197 }
1198
1199
1200 /** CLIENTS
1201 **/
1202
1203 typedef struct Client Client;
1204 typedef struct Multiplexer Multiplexer;
1205
1206 /* A Client object models a single qemud client socket
1207 * connection in the emulated system.
1208 *
1209 * the client first sends the name of the system service
1210 * it wants to contact (no framing), then waits for a 2
1211 * byte answer from qemud.
1212 *
1213 * the answer is either "OK" or "KO" to indicate
1214 * success or failure.
1215 *
1216 * In case of success, the client can send messages
1217 * to the service.
1218 *
1219 * In case of failure, it can disconnect or try sending
1220 * the name of another service.
1221 */
1222 struct Client {
1223 Client* next;
1224 Client** pref;
1225 int channel;
1226 char registered;
1227 FDHandler* fdhandler;
1228 Multiplexer* multiplexer;
1229 };
1230
1231 struct Multiplexer {
1232 Client* clients;
1233 int last_channel;
1234 Serial serial[1];
1235 Looper looper[1];
1236 FDHandlerList fdhandlers[1];
1237 };
1238
1239
1240 static int multiplexer_open_channel( Multiplexer* mult, Packet* p );
1241 static void multiplexer_close_channel( Multiplexer* mult, int channel );
1242 static void multiplexer_serial_send( Multiplexer* mult, int channel, Packet* p );
1243
1244 static void
client_dump(Client * c,Packet * p,const char * funcname)1245 client_dump( Client* c, Packet* p, const char* funcname )
1246 {
1247 T("%s: client %p (%d): %3d bytes: '%s'",
1248 funcname, c, c->fdhandler->fd,
1249 p->len, quote(p->data, p->len));
1250 }
1251
1252 /* destroy a client */
1253 static void
client_free(Client * c)1254 client_free( Client* c )
1255 {
1256 /* remove from list */
1257 c->pref[0] = c->next;
1258 if (c->next)
1259 c->next->pref = c->pref;
1260
1261 c->channel = -1;
1262 c->registered = 0;
1263
1264 /* gently ask the FDHandler to shutdown to
1265 * avoid losing queued outgoing packets */
1266 if (c->fdhandler != NULL) {
1267 fdhandler_shutdown(c->fdhandler);
1268 c->fdhandler = NULL;
1269 }
1270
1271 xfree(c);
1272 }
1273
1274
1275 /* a function called when a client socket receives data */
1276 static void
client_fd_receive(Client * c,Packet * p)1277 client_fd_receive( Client* c, Packet* p )
1278 {
1279 client_dump(c, p, __FUNCTION__);
1280
1281 if (c->registered) {
1282 /* the client is registered, just send the
1283 * data through the serial port
1284 */
1285 multiplexer_serial_send(c->multiplexer, c->channel, p);
1286 return;
1287 }
1288
1289 if (c->channel > 0) {
1290 /* the client is waiting registration results.
1291 * this should not happen because the client
1292 * should wait for our 'ok' or 'ko'.
1293 * close the connection.
1294 */
1295 D("%s: bad client sending data before end of registration",
1296 __FUNCTION__);
1297 BAD_CLIENT:
1298 packet_free(&p);
1299 client_free(c);
1300 return;
1301 }
1302
1303 /* the client hasn't registered a service yet,
1304 * so this must be the name of a service, call
1305 * the multiplexer to start registration for
1306 * it.
1307 */
1308 D("%s: attempting registration for service '%.*s'",
1309 __FUNCTION__, p->len, p->data);
1310 c->channel = multiplexer_open_channel(c->multiplexer, p);
1311 if (c->channel < 0) {
1312 D("%s: service name too long", __FUNCTION__);
1313 goto BAD_CLIENT;
1314 }
1315 D("%s: -> received channel id %d", __FUNCTION__, c->channel);
1316 packet_free(&p);
1317 }
1318
1319
1320 /* a function called when the client socket is closed. */
1321 static void
client_fd_close(Client * c)1322 client_fd_close( Client* c )
1323 {
1324 T("%s: client %p (%d)", __FUNCTION__, c, c->fdhandler->fd);
1325
1326 /* no need to shutdown the FDHandler */
1327 c->fdhandler = NULL;
1328
1329 /* tell the emulator we're out */
1330 if (c->channel > 0)
1331 multiplexer_close_channel(c->multiplexer, c->channel);
1332
1333 /* free the client */
1334 client_free(c);
1335 }
1336
1337 /* a function called when the multiplexer received a registration
1338 * response from the emulator for a given client.
1339 */
1340 static void
client_registration(Client * c,int registered)1341 client_registration( Client* c, int registered )
1342 {
1343 Packet* p = packet_alloc();
1344
1345 /* sends registration status to client */
1346 if (!registered) {
1347 D("%s: registration failed for client %d", __FUNCTION__, c->channel);
1348 memcpy( p->data, "KO", 2 );
1349 p->len = 2;
1350 } else {
1351 D("%s: registration succeeded for client %d", __FUNCTION__, c->channel);
1352 memcpy( p->data, "OK", 2 );
1353 p->len = 2;
1354 }
1355 client_dump(c, p, __FUNCTION__);
1356 fdhandler_enqueue(c->fdhandler, p);
1357
1358 /* now save registration state
1359 */
1360 c->registered = registered;
1361 if (!registered) {
1362 /* allow the client to try registering another service */
1363 c->channel = -1;
1364 }
1365 }
1366
1367 /* send data to a client */
1368 static void
client_send(Client * c,Packet * p)1369 client_send( Client* c, Packet* p )
1370 {
1371 client_dump(c, p, __FUNCTION__);
1372 fdhandler_enqueue(c->fdhandler, p);
1373 }
1374
1375
1376 /* Create new client socket handler */
1377 static Client*
client_new(Multiplexer * mult,int fd,FDHandlerList * pfdhandlers,Client ** pclients)1378 client_new( Multiplexer* mult,
1379 int fd,
1380 FDHandlerList* pfdhandlers,
1381 Client** pclients )
1382 {
1383 Client* c;
1384 Receiver recv;
1385
1386 xnew(c);
1387
1388 c->multiplexer = mult;
1389 c->next = NULL;
1390 c->pref = &c->next;
1391 c->channel = -1;
1392 c->registered = 0;
1393
1394 recv.user = c;
1395 recv.post = (PostFunc) client_fd_receive;
1396 recv.close = (CloseFunc) client_fd_close;
1397
1398 c->fdhandler = fdhandler_new( fd, pfdhandlers, &recv );
1399
1400 /* add to client list */
1401 c->next = *pclients;
1402 c->pref = pclients;
1403 *pclients = c;
1404 if (c->next)
1405 c->next->pref = &c->next;
1406
1407 return c;
1408 }
1409
1410 /** GLOBAL MULTIPLEXER
1411 **/
1412
1413 /* find a client by its channel */
1414 static Client*
multiplexer_find_client(Multiplexer * mult,int channel)1415 multiplexer_find_client( Multiplexer* mult, int channel )
1416 {
1417 Client* c = mult->clients;
1418
1419 for ( ; c != NULL; c = c->next ) {
1420 if (c->channel == channel)
1421 return c;
1422 }
1423 return NULL;
1424 }
1425
1426 /* handle control messages coming from the serial port
1427 * on CONTROL_CHANNEL.
1428 */
1429 static void
multiplexer_handle_control(Multiplexer * mult,Packet * p)1430 multiplexer_handle_control( Multiplexer* mult, Packet* p )
1431 {
1432 /* connection registration success */
1433 if (p->len == 13 && !memcmp(p->data, "ok:connect:", 11)) {
1434 int channel = hex2int(p->data+11, 2);
1435 Client* client = multiplexer_find_client(mult, channel);
1436
1437 /* note that 'client' can be NULL if the corresponding
1438 * socket was closed before the emulator response arrived.
1439 */
1440 if (client != NULL) {
1441 client_registration(client, 1);
1442 } else {
1443 D("%s: NULL client: '%.*s'", __FUNCTION__, p->len, p->data+11);
1444 }
1445 goto EXIT;
1446 }
1447
1448 /* connection registration failure */
1449 if (p->len == 13 && !memcmp(p->data, "ko:connect:",11)) {
1450 int channel = hex2int(p->data+11, 2);
1451 Client* client = multiplexer_find_client(mult, channel);
1452
1453 if (client != NULL)
1454 client_registration(client, 0);
1455
1456 goto EXIT;
1457 }
1458
1459 /* emulator-induced client disconnection */
1460 if (p->len == 13 && !memcmp(p->data, "disconnect:",11)) {
1461 int channel = hex2int(p->data+11, 2);
1462 Client* client = multiplexer_find_client(mult, channel);
1463
1464 if (client != NULL)
1465 client_free(client);
1466
1467 goto EXIT;
1468 }
1469
1470 /* A message that begins with "X00" is a probe sent by
1471 * the emulator used to detect which version of qemud it runs
1472 * against (in order to detect 1.0/1.1 system images. Just
1473 * silently ignore it there instead of printing an error
1474 * message.
1475 */
1476 if (p->len >= 3 && !memcmp(p->data,"X00",3)) {
1477 goto EXIT;
1478 }
1479
1480 D("%s: unknown control message (%d bytes): '%.*s'",
1481 __FUNCTION__, p->len, p->len, p->data);
1482
1483 EXIT:
1484 packet_free(&p);
1485 }
1486
1487 /* a function called when an incoming packet comes from the serial port */
1488 static void
multiplexer_serial_receive(Multiplexer * mult,Packet * p)1489 multiplexer_serial_receive( Multiplexer* mult, Packet* p )
1490 {
1491 Client* client;
1492
1493 T("%s: channel=%d '%.*s'", __FUNCTION__, p->channel, p->len, p->data);
1494
1495 if (p->channel == CHANNEL_CONTROL) {
1496 multiplexer_handle_control(mult, p);
1497 return;
1498 }
1499
1500 client = multiplexer_find_client(mult, p->channel);
1501 if (client != NULL) {
1502 client_send(client, p);
1503 return;
1504 }
1505
1506 D("%s: discarding packet for unknown channel %d", __FUNCTION__, p->channel);
1507 packet_free(&p);
1508 }
1509
1510 /* a function called when the serial reader closes */
1511 static void
multiplexer_serial_close(Multiplexer * mult)1512 multiplexer_serial_close( Multiplexer* mult )
1513 {
1514 fatal("unexpected close of serial reader");
1515 }
1516
1517 /* a function called to send a packet to the serial port */
1518 static void
multiplexer_serial_send(Multiplexer * mult,int channel,Packet * p)1519 multiplexer_serial_send( Multiplexer* mult, int channel, Packet* p )
1520 {
1521 p->channel = channel;
1522 serial_send( mult->serial, p );
1523 }
1524
1525
1526
1527 /* a function used by a client to allocate a new channel id and
1528 * ask the emulator to open it. 'service' must be a packet containing
1529 * the name of the service in its payload.
1530 *
1531 * returns -1 if the service name is too long.
1532 *
1533 * notice that client_registration() will be called later when
1534 * the answer arrives.
1535 */
1536 static int
multiplexer_open_channel(Multiplexer * mult,Packet * service)1537 multiplexer_open_channel( Multiplexer* mult, Packet* service )
1538 {
1539 Packet* p = packet_alloc();
1540 int len, channel;
1541
1542 /* find a free channel number, assume we don't have many
1543 * clients here. */
1544 {
1545 Client* c;
1546 TRY_AGAIN:
1547 channel = (++mult->last_channel) & 0xff;
1548
1549 for (c = mult->clients; c != NULL; c = c->next)
1550 if (c->channel == channel)
1551 goto TRY_AGAIN;
1552 }
1553
1554 len = snprintf((char*)p->data, sizeof p->data, "connect:%.*s:%02x", service->len, service->data, channel);
1555 if (len >= (int)sizeof(p->data)) {
1556 D("%s: weird, service name too long (%d > %d)", __FUNCTION__, len, sizeof(p->data));
1557 packet_free(&p);
1558 return -1;
1559 }
1560 p->channel = CHANNEL_CONTROL;
1561 p->len = len;
1562
1563 serial_send(mult->serial, p);
1564 return channel;
1565 }
1566
1567 /* used to tell the emulator a channel was closed by a client */
1568 static void
multiplexer_close_channel(Multiplexer * mult,int channel)1569 multiplexer_close_channel( Multiplexer* mult, int channel )
1570 {
1571 Packet* p = packet_alloc();
1572 int len = snprintf((char*)p->data, sizeof(p->data), "disconnect:%02x", channel);
1573
1574 if (len > (int)sizeof(p->data)) {
1575 /* should not happen */
1576 return;
1577 }
1578
1579 p->channel = CHANNEL_CONTROL;
1580 p->len = len;
1581
1582 serial_send(mult->serial, p);
1583 }
1584
1585 /* this function is used when a new connection happens on the control
1586 * socket.
1587 */
1588 static void
multiplexer_control_accept(Multiplexer * m,Packet * p)1589 multiplexer_control_accept( Multiplexer* m, Packet* p )
1590 {
1591 /* the file descriptor for the new socket connection is
1592 * in p->channel. See fdhandler_accept_event() */
1593 int fd = p->channel;
1594 Client* client = client_new( m, fd, m->fdhandlers, &m->clients );
1595
1596 D("created client %p listening on fd %d", client, fd);
1597
1598 /* free dummy packet */
1599 packet_free(&p);
1600 }
1601
1602 static void
multiplexer_control_close(Multiplexer * m)1603 multiplexer_control_close( Multiplexer* m )
1604 {
1605 fatal("unexpected multiplexer control close");
1606 }
1607
1608 static void
multiplexer_init(Multiplexer * m,const char * serial_dev)1609 multiplexer_init( Multiplexer* m, const char* serial_dev )
1610 {
1611 int fd, control_fd;
1612 Receiver recv;
1613
1614 /* initialize looper and fdhandlers list */
1615 looper_init( m->looper );
1616 fdhandler_list_init( m->fdhandlers, m->looper );
1617
1618 /* open the serial port */
1619 do {
1620 fd = open(serial_dev, O_RDWR);
1621 } while (fd < 0 && errno == EINTR);
1622
1623 if (fd < 0) {
1624 fatal( "%s: could not open '%s': %s", __FUNCTION__, serial_dev,
1625 strerror(errno) );
1626 }
1627 // disable echo on serial lines
1628 if ( !memcmp( serial_dev, "/dev/ttyS", 9 ) ) {
1629 struct termios ios;
1630 tcgetattr( fd, &ios );
1631 ios.c_lflag = 0; /* disable ECHO, ICANON, etc... */
1632 tcsetattr( fd, TCSANOW, &ios );
1633 }
1634
1635 /* initialize the serial reader/writer */
1636 recv.user = m;
1637 recv.post = (PostFunc) multiplexer_serial_receive;
1638 recv.close = (CloseFunc) multiplexer_serial_close;
1639
1640 serial_init( m->serial, fd, m->fdhandlers, &recv );
1641
1642 /* open the qemud control socket */
1643 recv.user = m;
1644 recv.post = (PostFunc) multiplexer_control_accept;
1645 recv.close = (CloseFunc) multiplexer_control_close;
1646
1647 fd = android_get_control_socket(CONTROL_SOCKET_NAME);
1648 if (fd < 0) {
1649 fatal("couldn't get fd for control socket '%s'", CONTROL_SOCKET_NAME);
1650 }
1651
1652 fdhandler_new_accept( fd, m->fdhandlers, &recv );
1653
1654 /* initialize clients list */
1655 m->clients = NULL;
1656 }
1657
1658 /** MAIN LOOP
1659 **/
1660
1661 static Multiplexer _multiplexer[1];
1662
main(void)1663 int main( void )
1664 {
1665 Multiplexer* m = _multiplexer;
1666
1667 /* extract the name of our serial device from the kernel
1668 * boot options that are stored in /proc/cmdline
1669 */
1670 #define KERNEL_OPTION "android.qemud="
1671
1672 {
1673 char buff[1024];
1674 int fd, len;
1675 char* p;
1676 char* q;
1677
1678 fd = open( "/proc/cmdline", O_RDONLY );
1679 if (fd < 0) {
1680 D("%s: can't open /proc/cmdline !!: %s", __FUNCTION__,
1681 strerror(errno));
1682 exit(1);
1683 }
1684
1685 len = fd_read( fd, buff, sizeof(buff)-1 );
1686 close(fd);
1687 if (len < 0) {
1688 D("%s: can't read /proc/cmdline: %s", __FUNCTION__,
1689 strerror(errno));
1690 exit(1);
1691 }
1692 buff[len] = 0;
1693
1694 p = strstr( buff, KERNEL_OPTION );
1695 if (p == NULL) {
1696 D("%s: can't find '%s' in /proc/cmdline",
1697 __FUNCTION__, KERNEL_OPTION );
1698 exit(1);
1699 }
1700
1701 p += sizeof(KERNEL_OPTION)-1; /* skip option */
1702 q = p;
1703 while ( *q && *q != ' ' && *q != '\t' )
1704 q += 1;
1705
1706 snprintf( buff, sizeof(buff), "/dev/%.*s", q-p, p );
1707
1708 multiplexer_init( m, buff );
1709 }
1710
1711 D( "entering main loop");
1712 looper_loop( m->looper );
1713 D( "unexpected termination !!" );
1714 return 0;
1715 }
1716