blob: ae6797e21b26df3a8c02d82b97cc5b231d65e519 [file] [log] [blame]
The Android Open Source Project52d4c302009-03-03 19:29:09 -08001#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 program is only used within the Android emulator 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 communicates with the emulator program through a single serial
18 * port, whose name is passed through a kernel boot parameter
19 * (e.g. android.qemud=ttyS1)
20 *
21 * - qemud setups one or more unix local stream sockets in the
22 * emulated system each one of these represent a different communication
23 * 'channel' between the emulator program and the emulated system.
24 *
25 * as an example, one channel is used for the emulated GSM modem
26 * (AT command channel), another channel is used for the emulated GPS,
27 * etc...
28 *
29 * - the protocol used on the serial connection is pretty simple:
30 *
31 * offset size description
32 * 0 4 4-char hex string giving the payload size
33 * 4 2 2-char hex string giving the destination or
34 * source channel
35 * 6 n the message payload
36 *
37 * for emulator->system messages, the 'channel' index indicates
38 * to which channel the payload must be sent
39 *
40 * for system->emulator messages, the 'channel' index indicates from
41 * which channel the payload comes from.
42 *
43 * - a special channel index (0) is used to communicate with the qemud
44 * program directly from the emulator. this is used for the following
45 * commands: (content of the payload):
46 *
47 * request: connect:<name>
48 * answer: ok:connect:<name>:XX // succesful name lookup
49 * answer: ko:connect:bad name // failed lookup
50 *
51 * the emulator queries the index of a given channel given
52 * its human-readable name. the answer contains a 2-char hex
53 * string for the channel index.
54 *
55 * not all emulated systems may need the same communication
56 * channels, so this function may fail.
57 *
58 * any invalid request will get an answer of:
59 *
60 * ko:unknown command
61 *
62 *
63 * here's a diagram of how things work:
64 *
65 *
66 * _________
67 * _____________ creates | |
68 * ________ | |==========>| Channel |--*--
69 * | |---->| Multiplexer | |_________|
70 * --*--| Serial | |_____________| || creates
71 * |________| | _____v___
72 * A +--------------->| |
73 * | | Client |--*--
74 * +---------------------------------|_________|
75 *
76 * which really means that:
77 *
78 * - the multiplexer creates one Channel object per control socket qemud
79 * handles (e.g. /dev/socket/qemud_gsm, /dev/socket/qemud_gps)
80 *
81 * - each Channel object has a numerical index that is >= 1, and waits
82 * for client connection. it will create a Client object when this
83 * happens
84 *
85 * - the Serial object receives packets from the serial port and sends them
86 * to the multiplexer
87 *
88 * - the multiplexer tries to find a channel the packet is addressed to,
89 * and will send the packet to all clients that correspond to it
90 *
91 * - when a Client receives data, it sends it directly to the Serial object
92 *
93 * - there are two kinds of Channel objects:
94 *
95 * CHANNEL_BROADCAST :: used for emulator -> clients broadcasts only
96 *
97 * CHANNEL_DUPLEX :: used for bidirectional communication with the
98 * emulator, with only *one* client allowed per
99 * duplex channel
100 */
101
102#define DEBUG 0
103
104#if DEBUG
105# define LOG_TAG "qemud"
106# include <cutils/log.h>
107# define D(...) LOGD(__VA_ARGS__)
108#else
109# define D(...) ((void)0)
110#endif
111
112/** UTILITIES
113 **/
114
115static void
116fatal( const char* fmt, ... )
117{
118 va_list args;
119 va_start(args, fmt);
120 fprintf(stderr, "PANIC: ");
121 vfprintf(stderr, fmt, args);
122 fprintf(stderr, "\n" );
123 va_end(args);
124 exit(1);
125}
126
127static void*
128xalloc( size_t sz )
129{
130 void* p;
131
132 if (sz == 0)
133 return NULL;
134
135 p = malloc(sz);
136 if (p == NULL)
137 fatal( "not enough memory" );
138
139 return p;
140}
141
142#define xnew(p) (p) = xalloc(sizeof(*(p)))
143
144static void*
145xalloc0( size_t sz )
146{
147 void* p = xalloc(sz);
148 memset( p, 0, sz );
149 return p;
150}
151
152#define xnew0(p) (p) = xalloc0(sizeof(*(p)))
153
154#define xfree(p) (free((p)), (p) = NULL)
155
156static void*
157xrealloc( void* block, size_t size )
158{
159 void* p = realloc( block, size );
160
161 if (p == NULL && size > 0)
162 fatal( "not enough memory" );
163
164 return p;
165}
166
167#define xrenew(p,count) (p) = xrealloc((p),sizeof(*(p))*(count))
168
169static int
170hex2int( const uint8_t* data, int len )
171{
172 int result = 0;
173 while (len > 0) {
174 int c = *data++;
175 unsigned d;
176
177 result <<= 4;
178 do {
179 d = (unsigned)(c - '0');
180 if (d < 10)
181 break;
182
183 d = (unsigned)(c - 'a');
184 if (d < 6) {
185 d += 10;
186 break;
187 }
188
189 d = (unsigned)(c - 'A');
190 if (d < 6) {
191 d += 10;
192 break;
193 }
194
195 return -1;
196 }
197 while (0);
198
199 result |= d;
200 len -= 1;
201 }
202 return result;
203}
204
205
206static void
207int2hex( int value, uint8_t* to, int width )
208{
209 int nn = 0;
210 static const char hexchars[16] = "0123456789abcdef";
211
212 for ( --width; width >= 0; width--, nn++ ) {
213 to[nn] = hexchars[(value >> (width*4)) & 15];
214 }
215}
216
217static int
218fd_read(int fd, void* to, int len)
219{
220 int ret;
221
222 do {
223 ret = read(fd, to, len);
224 } while (ret < 0 && errno == EINTR);
225
226 return ret;
227}
228
229static int
230fd_write(int fd, const void* from, int len)
231{
232 int ret;
233
234 do {
235 ret = write(fd, from, len);
236 } while (ret < 0 && errno == EINTR);
237
238 return ret;
239}
240
241static void
242fd_setnonblock(int fd)
243{
244 int ret, flags;
245
246 do {
247 flags = fcntl(fd, F_GETFD);
248 } while (flags < 0 && errno == EINTR);
249
250 if (flags < 0) {
251 fatal( "%s: could not get flags for fd %d: %s",
252 __FUNCTION__, fd, strerror(errno) );
253 }
254
255 do {
256 ret = fcntl(fd, F_SETFD, flags | O_NONBLOCK);
257 } while (ret < 0 && errno == EINTR);
258
259 if (ret < 0) {
260 fatal( "%s: could not set fd %d to non-blocking: %s",
261 __FUNCTION__, fd, strerror(errno) );
262 }
263}
264
265/** FD EVENT LOOP
266 **/
267
268#include <sys/epoll.h>
269
270#define MAX_CHANNELS 16
271#define MAX_EVENTS (MAX_CHANNELS+1) /* each channel + the serial fd */
272
273typedef void (*EventFunc)( void* user, int events );
274
275enum {
276 HOOK_PENDING = (1 << 0),
277 HOOK_CLOSING = (1 << 1),
278};
279
280typedef struct {
281 int fd;
282 int wanted;
283 int events;
284 int state;
285 void* ev_user;
286 EventFunc ev_func;
287} LoopHook;
288
289typedef struct {
290 int epoll_fd;
291 int num_fds;
292 int max_fds;
293 struct epoll_event* events;
294 LoopHook* hooks;
295} Looper;
296
297static void
298looper_init( Looper* l )
299{
300 l->epoll_fd = epoll_create(4);
301 l->num_fds = 0;
302 l->max_fds = 0;
303 l->events = NULL;
304 l->hooks = NULL;
305}
306
307static void
308looper_done( Looper* l )
309{
310 xfree(l->events);
311 xfree(l->hooks);
312 l->max_fds = 0;
313 l->num_fds = 0;
314
315 close(l->epoll_fd);
316 l->epoll_fd = -1;
317}
318
319static LoopHook*
320looper_find( Looper* l, int fd )
321{
322 LoopHook* hook = l->hooks;
323 LoopHook* end = hook + l->num_fds;
324
325 for ( ; hook < end; hook++ ) {
326 if (hook->fd == fd)
327 return hook;
328 }
329 return NULL;
330}
331
332static void
333looper_grow( Looper* l )
334{
335 int old_max = l->max_fds;
336 int new_max = old_max + (old_max >> 1) + 4;
337 int n;
338
339 xrenew( l->events, new_max );
340 xrenew( l->hooks, new_max );
341 l->max_fds = new_max;
342
343 /* now change the handles to all events */
344 for (n = 0; n < l->num_fds; n++) {
345 struct epoll_event ev;
346 LoopHook* hook = l->hooks + n;
347
348 ev.events = hook->wanted;
349 ev.data.ptr = hook;
350 epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
351 }
352}
353
354static void
355looper_add( Looper* l, int fd, EventFunc func, void* user )
356{
357 struct epoll_event ev;
358 LoopHook* hook;
359
360 if (l->num_fds >= l->max_fds)
361 looper_grow(l);
362
363 hook = l->hooks + l->num_fds;
364
365 hook->fd = fd;
366 hook->ev_user = user;
367 hook->ev_func = func;
368 hook->state = 0;
369 hook->wanted = 0;
370 hook->events = 0;
371
372 fd_setnonblock(fd);
373
374 ev.events = 0;
375 ev.data.ptr = hook;
376 epoll_ctl( l->epoll_fd, EPOLL_CTL_ADD, fd, &ev );
377
378 l->num_fds += 1;
379}
380
381static void
382looper_del( Looper* l, int fd )
383{
384 LoopHook* hook = looper_find( l, fd );
385
386 if (!hook) {
387 D( "%s: invalid fd: %d", __FUNCTION__, fd );
388 return;
389 }
390 /* don't remove the hook yet */
391 hook->state |= HOOK_CLOSING;
392
393 epoll_ctl( l->epoll_fd, EPOLL_CTL_DEL, fd, NULL );
394}
395
396static void
397looper_enable( Looper* l, int fd, int events )
398{
399 LoopHook* hook = looper_find( l, fd );
400
401 if (!hook) {
402 D("%s: invalid fd: %d", __FUNCTION__, fd );
403 return;
404 }
405
406 if (events & ~hook->wanted) {
407 struct epoll_event ev;
408
409 hook->wanted |= events;
410 ev.events = hook->wanted;
411 ev.data.ptr = hook;
412
413 epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
414 }
415}
416
417static void
418looper_disable( Looper* l, int fd, int events )
419{
420 LoopHook* hook = looper_find( l, fd );
421
422 if (!hook) {
423 D("%s: invalid fd: %d", __FUNCTION__, fd );
424 return;
425 }
426
427 if (events & hook->wanted) {
428 struct epoll_event ev;
429
430 hook->wanted &= ~events;
431 ev.events = hook->wanted;
432 ev.data.ptr = hook;
433
434 epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
435 }
436}
437
438static void
439looper_loop( Looper* l )
440{
441 for (;;) {
442 int n, count;
443
444 do {
445 count = epoll_wait( l->epoll_fd, l->events, l->num_fds, -1 );
446 } while (count < 0 && errno == EINTR);
447
448 if (count < 0) {
449 D("%s: error: %s", __FUNCTION__, strerror(errno) );
450 return;
451 }
452
453 /* mark all pending hooks */
454 for (n = 0; n < count; n++) {
455 LoopHook* hook = l->events[n].data.ptr;
456 hook->state = HOOK_PENDING;
457 hook->events = l->events[n].events;
458 }
459
460 /* execute hook callbacks. this may change the 'hooks'
461 * and 'events' array, as well as l->num_fds, so be careful */
462 for (n = 0; n < l->num_fds; n++) {
463 LoopHook* hook = l->hooks + n;
464 if (hook->state & HOOK_PENDING) {
465 hook->state &= ~HOOK_PENDING;
466 hook->ev_func( hook->ev_user, hook->events );
467 }
468 }
469
470 /* now remove all the hooks that were closed by
471 * the callbacks */
472 for (n = 0; n < l->num_fds;) {
473 LoopHook* hook = l->hooks + n;
474
475 if (!(hook->state & HOOK_CLOSING)) {
476 n++;
477 continue;
478 }
479
480 hook[0] = l->hooks[l->num_fds-1];
481 l->num_fds -= 1;
482 }
483 }
484}
485
486/** PACKETS
487 **/
488
489typedef struct Packet Packet;
490
491/* we want to ensure that Packet is no more than a single page */
492#define MAX_PAYLOAD (4096-16-6)
493
494struct Packet {
495 Packet* next;
496 int len;
497 int channel;
498 uint8_t data[ MAX_PAYLOAD ];
499};
500
501static Packet* _free_packets;
502
503static Packet*
504packet_alloc(void)
505{
506 Packet* p = _free_packets;
507 if (p != NULL) {
508 _free_packets = p->next;
509 } else {
510 xnew(p);
511 }
512 p->next = NULL;
513 p->len = 0;
514 p->channel = -1;
515 return p;
516}
517
518static void
519packet_free( Packet* *ppacket )
520{
521 Packet* p = *ppacket;
522 if (p) {
523 p->next = _free_packets;
524 _free_packets = p;
525 *ppacket = NULL;
526 }
527}
528
529static Packet*
530packet_dup( Packet* p )
531{
532 Packet* p2 = packet_alloc();
533
534 p2->len = p->len;
535 p2->channel = p->channel;
536 memcpy(p2->data, p->data, p->len);
537 return p2;
538}
539
540/** PACKET RECEIVER
541 **/
542
543typedef void (*PostFunc) ( void* user, Packet* p );
544typedef void (*CloseFunc)( void* user );
545
546typedef struct {
547 PostFunc post;
548 CloseFunc close;
549 void* user;
550} Receiver;
551
552static __inline__ void
553receiver_post( Receiver* r, Packet* p )
554{
555 r->post( r->user, p );
556}
557
558static __inline__ void
559receiver_close( Receiver* r )
560{
561 r->close( r->user );
562}
563
564
565/** FD HANDLERS
566 **
567 ** these are smart listeners that send incoming packets to a receiver
568 ** and can queue one or more outgoing packets and send them when possible
569 **/
570
571typedef struct FDHandler {
572 int fd;
573 Looper* looper;
574 Receiver receiver[1];
575 int out_pos;
576 Packet* out_first;
577 Packet** out_ptail;
578
579} FDHandler;
580
581
582static void
583fdhandler_done( FDHandler* f )
584{
585 /* get rid of unsent packets */
586 if (f->out_first) {
587 Packet* p;
588 while ((p = f->out_first) != NULL) {
589 f->out_first = p->next;
590 packet_free(&p);
591 }
592 }
593
594 /* get rid of file descriptor */
595 if (f->fd >= 0) {
596 looper_del( f->looper, f->fd );
597 close(f->fd);
598 f->fd = -1;
599 }
600 f->looper = NULL;
601}
602
603
604static void
605fdhandler_enqueue( FDHandler* f, Packet* p )
606{
607 Packet* first = f->out_first;
608
609 p->next = NULL;
610 f->out_ptail[0] = p;
611 f->out_ptail = &p->next;
612
613 if (first == NULL) {
614 f->out_pos = 0;
615 looper_enable( f->looper, f->fd, EPOLLOUT );
616 }
617}
618
619
620static void
621fdhandler_event( FDHandler* f, int events )
622{
623 int len;
624
625 if (events & EPOLLIN) {
626 Packet* p = packet_alloc();
627 int len;
628
629 if ((len = fd_read(f->fd, p->data, MAX_PAYLOAD)) < 0) {
630 D("%s: can't recv: %s", __FUNCTION__, strerror(errno));
631 packet_free(&p);
632 } else {
633 p->len = len;
634 p->channel = -101; /* special debug value */
635 receiver_post( f->receiver, p );
636 }
637 }
638
639 /* in certain cases, it's possible to have both EPOLLIN and
640 * EPOLLHUP at the same time. This indicates that there is incoming
641 * data to read, but that the connection was nonetheless closed
642 * by the sender. Be sure to read the data before closing
643 * the receiver to avoid packet loss.
644 */
645 if (events & (EPOLLHUP|EPOLLERR)) {
646 /* disconnection */
647 D("%s: disconnect on fd %d", __FUNCTION__, f->fd);
648 receiver_close( f->receiver );
649 return;
650 }
651
652 if (events & EPOLLOUT && f->out_first) {
653 Packet* p = f->out_first;
654 int avail, len;
655
656 avail = p->len - f->out_pos;
657 if ((len = fd_write(f->fd, p->data + f->out_pos, avail)) < 0) {
658 D("%s: can't send: %s", __FUNCTION__, strerror(errno));
659 } else {
660 f->out_pos += len;
661 if (f->out_pos >= p->len) {
662 f->out_pos = 0;
663 f->out_first = p->next;
664 packet_free(&p);
665 if (f->out_first == NULL) {
666 f->out_ptail = &f->out_first;
667 looper_disable( f->looper, f->fd, EPOLLOUT );
668 }
669 }
670 }
671 }
672}
673
674
675static void
676fdhandler_init( FDHandler* f,
677 int fd,
678 Looper* looper,
679 Receiver* receiver )
680{
681 f->fd = fd;
682 f->looper = looper;
683 f->receiver[0] = receiver[0];
684 f->out_first = NULL;
685 f->out_ptail = &f->out_first;
686 f->out_pos = 0;
687
688 looper_add( looper, fd, (EventFunc) fdhandler_event, f );
689 looper_enable( looper, fd, EPOLLIN );
690}
691
692
693static void
694fdhandler_accept_event( FDHandler* f, int events )
695{
696 if (events & EPOLLIN) {
697 /* this is an accept - send a dummy packet to the receiver */
698 Packet* p = packet_alloc();
699
700 D("%s: accepting on fd %d", __FUNCTION__, f->fd);
701 p->data[0] = 1;
702 p->len = 1;
703 receiver_post( f->receiver, p );
704 }
705
706 if (events & (EPOLLHUP|EPOLLERR)) {
707 /* disconnecting !! */
708 D("%s: closing fd %d", __FUNCTION__, f->fd);
709 receiver_close( f->receiver );
710 return;
711 }
712}
713
714
715static void
716fdhandler_init_accept( FDHandler* f,
717 int fd,
718 Looper* looper,
719 Receiver* receiver )
720{
721 f->fd = fd;
722 f->looper = looper;
723 f->receiver[0] = receiver[0];
724
725 looper_add( looper, fd, (EventFunc) fdhandler_accept_event, f );
726 looper_enable( looper, fd, EPOLLIN );
727}
728
729/** CLIENTS
730 **/
731
732typedef struct Client {
733 struct Client* next;
734 struct Client** pref;
735 int channel;
736 FDHandler fdhandler[1];
737 Receiver receiver[1];
738} Client;
739
740static Client* _free_clients;
741
742static void
743client_free( Client* c )
744{
745 c->pref[0] = c->next;
746 c->next = NULL;
747 c->pref = &c->next;
748
749 fdhandler_done( c->fdhandler );
750 free(c);
751}
752
753static void
754client_receive( Client* c, Packet* p )
755{
756 p->channel = c->channel;
757 receiver_post( c->receiver, p );
758}
759
760static void
761client_send( Client* c, Packet* p )
762{
763 fdhandler_enqueue( c->fdhandler, p );
764}
765
766static void
767client_close( Client* c )
768{
769 D("disconnecting client on fd %d", c->fdhandler->fd);
770 client_free(c);
771}
772
773static Client*
774client_new( int fd,
775 int channel,
776 Looper* looper,
777 Receiver* receiver )
778{
779 Client* c;
780 Receiver recv;
781
782 xnew(c);
783
784 c->next = NULL;
785 c->pref = &c->next;
786 c->channel = channel;
787 c->receiver[0] = receiver[0];
788
789 recv.user = c;
790 recv.post = (PostFunc) client_receive;
791 recv.close = (CloseFunc) client_close;
792
793 fdhandler_init( c->fdhandler, fd, looper, &recv );
794 return c;
795}
796
797static void
798client_link( Client* c, Client** plist )
799{
800 c->next = plist[0];
801 c->pref = plist;
802 plist[0] = c;
803}
804
805
806/** CHANNELS
807 **/
808
809typedef enum {
810 CHANNEL_BROADCAST = 0,
811 CHANNEL_DUPLEX,
812
813 CHANNEL_MAX /* do not remove */
814
815} ChannelType;
816
817#define CHANNEL_CONTROL 0
818
819typedef struct Channel {
820 struct Channel* next;
821 struct Channel** pref;
822 FDHandler fdhandler[1];
823 ChannelType ctype;
824 const char* name;
825 int index;
826 Receiver receiver[1];
827 Client* clients;
828} Channel;
829
830static void
831channel_free( Channel* c )
832{
833 while (c->clients)
834 client_free(c->clients);
835
836 c->pref[0] = c->next;
837 c->pref = &c->next;
838 c->next = NULL;
839
840 fdhandler_done( c->fdhandler );
841 free(c);
842}
843
844static void
845channel_close( Channel* c )
846{
847 D("closing channel '%s' on fd %d", c->name, c->fdhandler->fd);
848 channel_free(c);
849}
850
851
852static void
853channel_accept( Channel* c, Packet* p )
854{
855 int fd;
856 struct sockaddr from;
857 socklen_t fromlen = sizeof(from);
858
859 /* get rid of dummy packet (see fdhandler_event_accept) */
860 packet_free(&p);
861
862 do {
863 fd = accept( c->fdhandler->fd, &from, &fromlen );
864 } while (fd < 0 && errno == EINTR);
865
866 if (fd >= 0) {
867 Client* client;
868
869 /* DUPLEX channels can only have one client at a time */
870 if (c->ctype == CHANNEL_DUPLEX && c->clients != NULL) {
871 D("refusing client connection on duplex channel '%s'", c->name);
872 close(fd);
873 return;
874 }
875 client = client_new( fd, c->index, c->fdhandler->looper, c->receiver );
876 client_link( client, &c->clients );
877 D("new client for channel '%s' on fd %d", c->name, fd);
878 }
879 else
880 D("could not accept connection: %s", strerror(errno));
881}
882
883
884static Channel*
885channel_new( int fd,
886 ChannelType ctype,
887 const char* name,
888 int index,
889 Looper* looper,
890 Receiver* receiver )
891{
892 Channel* c;
893 Receiver recv;
894
895 xnew(c);
896
897 c->next = NULL;
898 c->pref = &c->next;
899 c->ctype = ctype;
900 c->name = name;
901 c->index = index;
902
903 /* saved for future clients */
904 c->receiver[0] = receiver[0];
905
906 recv.user = c;
907 recv.post = (PostFunc) channel_accept;
908 recv.close = (CloseFunc) channel_close;
909
910 fdhandler_init_accept( c->fdhandler, fd, looper, &recv );
911 listen( fd, 5 );
912
913 return c;
914}
915
916static void
917channel_link( Channel* c, Channel** plist )
918{
919 c->next = plist[0];
920 c->pref = plist;
921 plist[0] = c;
922}
923
924static void
925channel_send( Channel* c, Packet* p )
926{
927 Client* client = c->clients;
928 for ( ; client; client = client->next ) {
929 Packet* q = packet_dup(p);
930 client_send( client, q );
931 }
932 packet_free( &p );
933}
934
935
936/* each packet is made of a 6 byte header followed by a payload
937 * the header looks like:
938 *
939 * offset size description
940 * 0 4 a 4-char hex string for the size of the payload
941 * 4 2 a 2-byte hex string for the channel number
942 * 6 n the payload itself
943 */
944#define HEADER_SIZE 6
945#define LENGTH_OFFSET 0
946#define LENGTH_SIZE 4
947#define CHANNEL_OFFSET 4
948#define CHANNEL_SIZE 2
949
950#define CHANNEL_INDEX_NONE 0
951#define CHANNEL_INDEX_CONTROL 1
952
953#define TOSTRING(x) _TOSTRING(x)
954#define _TOSTRING(x) #x
955
956/** SERIAL HANDLER
957 **/
958
959typedef struct Serial {
960 FDHandler fdhandler[1];
961 Receiver receiver[1];
962 int in_len;
963 int in_datalen;
964 int in_channel;
965 Packet* in_packet;
966} Serial;
967
968static void
969serial_done( Serial* s )
970{
971 packet_free(&s->in_packet);
972 s->in_len = 0;
973 s->in_datalen = 0;
974 s->in_channel = 0;
975 fdhandler_done(s->fdhandler);
976}
977
978static void
979serial_close( Serial* s )
980{
981 fatal("unexpected serial port close !!");
982}
983
984/* receive packets from the serial port */
985static void
986serial_receive( Serial* s, Packet* p )
987{
988 int rpos = 0, rcount = p->len;
989 Packet* inp = s->in_packet;
990 int inpos = s->in_len;
991
992 //D("received from serial: %d bytes: '%.*s'", p->len, p->len, p->data);
993
994 while (rpos < rcount)
995 {
996 int avail = rcount - rpos;
997
998 /* first, try to read the header */
999 if (s->in_datalen == 0) {
1000 int wanted = HEADER_SIZE - inpos;
1001 if (avail > wanted)
1002 avail = wanted;
1003
1004 memcpy( inp->data + inpos, p->data + rpos, avail );
1005 inpos += avail;
1006 rpos += avail;
1007
1008 if (inpos == HEADER_SIZE) {
1009 s->in_datalen = hex2int( inp->data + LENGTH_OFFSET, LENGTH_SIZE );
1010 s->in_channel = hex2int( inp->data + CHANNEL_OFFSET, CHANNEL_SIZE );
1011
1012 if (s->in_datalen <= 0)
1013 D("ignoring empty packet from serial port");
1014
1015 //D("received %d bytes packet for channel %d", s->in_datalen, s->in_channel);
1016 inpos = 0;
1017 }
1018 }
1019 else /* then, populate the packet itself */
1020 {
1021 int wanted = s->in_datalen - inpos;
1022
1023 if (avail > wanted)
1024 avail = wanted;
1025
1026 memcpy( inp->data + inpos, p->data + rpos, avail );
1027 inpos += avail;
1028 rpos += avail;
1029
1030 if (inpos == s->in_datalen) {
1031 if (s->in_channel < 0) {
1032 D("ignoring %d bytes addressed to channel %d",
1033 inpos, s->in_channel);
1034 } else {
1035 inp->len = inpos;
1036 inp->channel = s->in_channel;
1037 receiver_post( s->receiver, inp );
1038 s->in_packet = inp = packet_alloc();
1039 }
1040 s->in_datalen = 0;
1041 inpos = 0;
1042 }
1043 }
1044 }
1045 s->in_len = inpos;
1046 packet_free(&p);
1047}
1048
1049
1050/* send a packet to the serial port */
1051static void
1052serial_send( Serial* s, Packet* p )
1053{
1054 Packet* h = packet_alloc();
1055
1056 //D("sending to serial %d bytes from channel %d: '%.*s'", p->len, p->channel, p->len, p->data);
1057
1058 /* insert a small header before this packet */
1059 h->len = HEADER_SIZE;
1060 int2hex( p->len, h->data + LENGTH_OFFSET, LENGTH_SIZE );
1061 int2hex( p->channel, h->data + CHANNEL_OFFSET, CHANNEL_SIZE );
1062
1063 fdhandler_enqueue( s->fdhandler, h );
1064 fdhandler_enqueue( s->fdhandler, p );
1065}
1066
1067
1068static void
1069serial_init( Serial* s,
1070 int fd,
1071 Looper* looper,
1072 Receiver* receiver )
1073{
1074 Receiver recv;
1075
1076 recv.user = s;
1077 recv.post = (PostFunc) serial_receive;
1078 recv.close = (CloseFunc) serial_close;
1079
1080 s->receiver[0] = receiver[0];
1081
1082 fdhandler_init( s->fdhandler, fd, looper, &recv );
1083 s->in_len = 0;
1084 s->in_datalen = 0;
1085 s->in_channel = 0;
1086 s->in_packet = packet_alloc();
1087}
1088
1089/** GLOBAL MULTIPLEXER
1090 **/
1091
1092typedef struct {
1093 Looper looper[1];
1094 Serial serial[1];
1095 Channel* channels;
1096 uint16_t channel_last;
1097} Multiplexer;
1098
1099/* receive a packet from the serial port, send it to the relevant client/channel */
1100static void multiplexer_receive_serial( Multiplexer* m, Packet* p );
1101
1102static void
1103multiplexer_init( Multiplexer* m, const char* serial_dev )
1104{
1105 int fd;
1106 Receiver recv;
1107
1108 looper_init( m->looper );
1109
1110 fd = open(serial_dev, O_RDWR);
1111 if (fd < 0) {
1112 fatal( "%s: could not open '%s': %s", __FUNCTION__, serial_dev,
1113 strerror(errno) );
1114 }
1115 // disable echo on serial lines
1116 if ( !memcmp( serial_dev, "/dev/ttyS", 9 ) ) {
1117 struct termios ios;
1118 tcgetattr( fd, &ios );
1119 ios.c_lflag = 0; /* disable ECHO, ICANON, etc... */
1120 tcsetattr( fd, TCSANOW, &ios );
1121 }
1122
1123 recv.user = m;
1124 recv.post = (PostFunc) multiplexer_receive_serial;
1125 recv.close = NULL;
1126
1127 serial_init( m->serial, fd, m->looper, &recv );
1128
1129 m->channels = NULL;
1130 m->channel_last = CHANNEL_CONTROL+1;
1131}
1132
1133static void
1134multiplexer_add_channel( Multiplexer* m, int fd, const char* name, ChannelType ctype )
1135{
1136 Channel* c;
1137 Receiver recv;
1138
1139 /* send channel client data directly to the serial port */
1140 recv.user = m->serial;
1141 recv.post = (PostFunc) serial_send;
1142 recv.close = (CloseFunc) client_close;
1143
1144 /* connect each channel directly to the serial port */
1145 c = channel_new( fd, ctype, name, m->channel_last, m->looper, &recv );
1146 channel_link( c, &m->channels );
1147
1148 m->channel_last += 1;
1149 if (m->channel_last <= CHANNEL_CONTROL)
1150 m->channel_last += 1;
1151}
1152
1153
1154static void
1155multiplexer_done( Multiplexer* m )
1156{
1157 while (m->channels)
1158 channel_close(m->channels);
1159
1160 serial_done( m->serial );
1161 looper_done( m->looper );
1162}
1163
1164
1165static void
1166multiplexer_send_answer( Multiplexer* m, Packet* p, const char* answer )
1167{
1168 p->len = strlen( answer );
1169 if (p->len >= MAX_PAYLOAD)
1170 p->len = MAX_PAYLOAD-1;
1171
1172 memcpy( (char*)p->data, answer, p->len );
1173 p->channel = CHANNEL_CONTROL;
1174
1175 serial_send( m->serial, p );
1176}
1177
1178
1179static void
1180multiplexer_handle_connect( Multiplexer* m, Packet* p, char* name )
1181{
1182 int n;
1183 Channel* c;
1184
1185 if (p->len >= MAX_PAYLOAD) {
1186 multiplexer_send_answer( m, p, "ko:connect:bad name" );
1187 return;
1188 }
1189 p->data[p->len] = 0;
1190
1191 for (c = m->channels; c != NULL; c = c->next)
1192 if ( !strcmp(c->name, name) )
1193 break;
1194
1195 if (c == NULL) {
1196 D("can't connect to unknown channel '%s'", name);
1197 multiplexer_send_answer( m, p, "ko:connect:bad name" );
1198 return;
1199 }
1200
1201 p->channel = CHANNEL_CONTROL;
1202 p->len = snprintf( (char*)p->data, MAX_PAYLOAD,
1203 "ok:connect:%s:%02x", c->name, c->index );
1204
1205 serial_send( m->serial, p );
1206}
1207
1208
1209static void
1210multiplexer_receive_serial( Multiplexer* m, Packet* p )
1211{
1212 Channel* c = m->channels;
1213
1214 /* check the destination channel index */
1215 if (p->channel != CHANNEL_CONTROL) {
1216 Channel* c;
1217
1218 for (c = m->channels; c; c = c->next ) {
1219 if (c->index == p->channel) {
1220 channel_send( c, p );
1221 break;
1222 }
1223 }
1224 if (c == NULL) {
1225 D("ignoring %d bytes packet for unknown channel index %d",
1226 p->len, p->channel );
1227 packet_free(&p);
1228 }
1229 }
1230 else /* packet addressed to the control channel */
1231 {
1232 D("received control message: '%.*s'", p->len, p->data);
1233 if (p->len > 8 && strncmp( (char*)p->data, "connect:", 8) == 0) {
1234 multiplexer_handle_connect( m, p, (char*)p->data + 8 );
1235 } else {
1236 /* unknown command */
1237 multiplexer_send_answer( m, p, "ko:unknown command" );
1238 }
1239 return;
1240 }
1241}
1242
1243
1244/** MAIN LOOP
1245 **/
1246
1247static Multiplexer _multiplexer[1];
1248
1249#define QEMUD_PREFIX "qemud_"
1250
1251static const struct { const char* name; ChannelType ctype; } default_channels[] = {
1252 { "gsm", CHANNEL_DUPLEX }, /* GSM AT command channel, used by commands/rild/rild.c */
1253 { "gps", CHANNEL_BROADCAST }, /* GPS NMEA commands, used by libs/hardware_legacy/qemu_gps.c */
1254 { "control", CHANNEL_DUPLEX }, /* Used for power/leds/vibrator/etc... */
1255 { NULL, 0 }
1256};
1257
1258int main( void )
1259{
1260 Multiplexer* m = _multiplexer;
1261
1262 /* extract the name of our serial device from the kernel
1263 * boot options that are stored in /proc/cmdline
1264 */
1265#define KERNEL_OPTION "android.qemud="
1266
1267 {
1268 char buff[1024];
1269 int fd, len;
1270 char* p;
1271 char* q;
1272
1273 fd = open( "/proc/cmdline", O_RDONLY );
1274 if (fd < 0) {
1275 D("%s: can't open /proc/cmdline !!: %s", __FUNCTION__,
1276 strerror(errno));
1277 exit(1);
1278 }
1279
1280 len = fd_read( fd, buff, sizeof(buff)-1 );
1281 close(fd);
1282 if (len < 0) {
1283 D("%s: can't read /proc/cmdline: %s", __FUNCTION__,
1284 strerror(errno));
1285 exit(1);
1286 }
1287 buff[len] = 0;
1288
1289 p = strstr( buff, KERNEL_OPTION );
1290 if (p == NULL) {
1291 D("%s: can't find '%s' in /proc/cmdline",
1292 __FUNCTION__, KERNEL_OPTION );
1293 exit(1);
1294 }
1295
1296 p += sizeof(KERNEL_OPTION)-1; /* skip option */
1297 q = p;
1298 while ( *q && *q != ' ' && *q != '\t' )
1299 q += 1;
1300
1301 snprintf( buff, sizeof(buff), "/dev/%.*s", q-p, p );
1302
1303 multiplexer_init( m, buff );
1304 }
1305
1306 D("multiplexer inited, creating default channels");
1307
1308 /* now setup all default channels */
1309 {
1310 int nn;
1311
1312 for (nn = 0; default_channels[nn].name != NULL; nn++) {
1313 char control_name[32];
1314 int fd;
1315 Channel* chan;
1316 const char* name = default_channels[nn].name;
1317 ChannelType ctype = default_channels[nn].ctype;
1318
1319 snprintf(control_name, sizeof(control_name), "%s%s",
1320 QEMUD_PREFIX, name);
1321
1322 if ((fd = android_get_control_socket(control_name)) < 0) {
1323 D("couldn't get fd for control socket '%s'", name);
1324 continue;
1325 }
1326 D( "got control socket '%s' on fd %d", control_name, fd);
1327 multiplexer_add_channel( m, fd, name, ctype );
1328 }
1329 }
1330
1331 D( "entering main loop");
1332 looper_loop( m->looper );
1333 D( "unexpected termination !!" );
1334 return 0;
1335}