#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <termios.h>
#include <cutils/sockets.h>

/*
 *  the qemud daemon program is only used within Android as a bridge
 *  between the emulator program and the emulated system. it really works as
 *  a simple stream multiplexer that works as follows:
 *
 *    - qemud is started by init following instructions in
 *      /system/etc/init.goldfish.rc (i.e. it is never started on real devices)
 *
 *    - qemud communicates with the emulator program through a single serial
 *      port, whose name is passed through a kernel boot parameter
 *      (e.g. android.qemud=ttyS1)
 *
 *    - qemud binds one unix local stream socket (/dev/socket/qemud, created
 *      by init through /system/etc/init.goldfish.rc).
 *
 *
 *      emulator <==serial==> qemud <---> /dev/socket/qemud <-+--> client1
 *                                                            |
 *                                                            +--> client2
 *
 *   - the special channel index 0 is used by the emulator and qemud only.
 *     other channel numbers correspond to clients. More specifically,
 *     connection are created like this:
 *
 *     * the client connects to /dev/socket/qemud
 *
 *     * the client sends the service name through the socket, as
 *            <service-name>
 *
 *     * qemud creates a "Client" object internally, assigns it an
 *       internal unique channel number > 0, then sends a connection
 *       initiation request to the emulator (i.e. through channel 0):
 *
 *           connect:<id>:<name>
 *
 *       where <name> is the service name, and <id> is a 2-hexchar
 *       number corresponding to the channel number.
 *
 *     * in case of success, the emulator responds through channel 0
 *       with:
 *
 *           ok:connect:<id>
 *
 *       after this, all messages between the client and the emulator
 *       are passed in pass-through mode.
 *
 *     * if the emulator refuses the service connection, it will
 *       send the following through channel 0:
 *
 *           ko:connect:<id>:reason-for-failure
 *
 *     * If the client closes the connection, qemud sends the following
 *       to the emulator:
 *
 *           disconnect:<id>
 *
 *       The same message is the opposite direction if the emulator
 *       chooses to close the connection.
 *
 *     * any command sent through channel 0 to the emulator that is
 *       not properly recognized will be answered by:
 *
 *           ko:unknown command
 *
 *
 *  Internally, the daemon maintains a "Client" object for each client
 *  connection (i.e. accepting socket connection).
 */

/* name of the single control socket used by the daemon */
#define CONTROL_SOCKET_NAME  "qemud"

#define  DEBUG     0
#define  T_ACTIVE  0  /* set to 1 to dump traffic */

#if DEBUG
#  define LOG_TAG  "qemud"
#  include <cutils/log.h>
#  define  D(...)   ALOGD(__VA_ARGS__)
#else
#  define  D(...)  ((void)0)
#  define  T(...)  ((void)0)
#endif

#if T_ACTIVE
#  define  T(...)   D(__VA_ARGS__)
#else
#  define  T(...)   ((void)0)
#endif

/** UTILITIES
 **/

static void
fatal( const char*  fmt, ... )
{
    va_list  args;
    va_start(args, fmt);
    fprintf(stderr, "PANIC: ");
    vfprintf(stderr, fmt, args);
    fprintf(stderr, "\n" );
    va_end(args);
    exit(1);
}

static void*
xalloc( size_t   sz )
{
    void*  p;

    if (sz == 0)
        return NULL;

    p = malloc(sz);
    if (p == NULL)
        fatal( "not enough memory" );

    return p;
}

#define  xnew(p)   (p) = xalloc(sizeof(*(p)))

static void*
xalloc0( size_t  sz )
{
    void*  p = xalloc(sz);
    memset( p, 0, sz );
    return p;
}

#define  xnew0(p)   (p) = xalloc0(sizeof(*(p)))

#define  xfree(p)    (free((p)), (p) = NULL)

static void*
xrealloc( void*  block, size_t  size )
{
    void*  p = realloc( block, size );

    if (p == NULL && size > 0)
        fatal( "not enough memory" );

    return p;
}

#define  xrenew(p,count)  (p) = xrealloc((p),sizeof(*(p))*(count))

static int
hex2int( const uint8_t*  data, int  len )
{
    int  result = 0;
    while (len > 0) {
        int       c = *data++;
        unsigned  d;

        result <<= 4;
        do {
            d = (unsigned)(c - '0');
            if (d < 10)
                break;

            d = (unsigned)(c - 'a');
            if (d < 6) {
                d += 10;
                break;
            }

            d = (unsigned)(c - 'A');
            if (d < 6) {
                d += 10;
                break;
            }

            return -1;
        }
        while (0);

        result |= d;
        len    -= 1;
    }
    return  result;
}


static void
int2hex( int  value, uint8_t*  to, int  width )
{
    int  nn = 0;
    static const char hexchars[16] = "0123456789abcdef";

    for ( --width; width >= 0; width--, nn++ ) {
        to[nn] = hexchars[(value >> (width*4)) & 15];
    }
}

static int
fd_read(int  fd, void*  to, int  len)
{
    int  ret;

    do {
        ret = read(fd, to, len);
    } while (ret < 0 && errno == EINTR);

    return ret;
}

static int
fd_write(int  fd, const void*  from, int  len)
{
    int  ret;

    do {
        ret = write(fd, from, len);
    } while (ret < 0 && errno == EINTR);

    return ret;
}

static void
fd_setnonblock(int  fd)
{
    int  ret, flags;

    do {
        flags = fcntl(fd, F_GETFD);
    } while (flags < 0 && errno == EINTR);

    if (flags < 0) {
        fatal( "%s: could not get flags for fd %d: %s",
               __FUNCTION__, fd, strerror(errno) );
    }

    do {
        ret = fcntl(fd, F_SETFD, flags | O_NONBLOCK);
    } while (ret < 0 && errno == EINTR);

    if (ret < 0) {
        fatal( "%s: could not set fd %d to non-blocking: %s",
               __FUNCTION__, fd, strerror(errno) );
    }
}


static int
fd_accept(int  fd)
{
    struct sockaddr  from;
    socklen_t        fromlen = sizeof(from);
    int              ret;

    do {
        ret = accept(fd, &from, &fromlen);
    } while (ret < 0 && errno == EINTR);

    return ret;
}

/** FD EVENT LOOP
 **/

/* A Looper object is used to monitor activity on one or more
 * file descriptors (e.g sockets).
 *
 * - call looper_add() to register a function that will be
 *   called when events happen on the file descriptor.
 *
 * - call looper_enable() or looper_disable() to enable/disable
 *   the set of monitored events for a given file descriptor.
 *
 * - call looper_del() to unregister a file descriptor.
 *   this does *not* close the file descriptor.
 *
 * Note that you can only provide a single function to handle
 * all events related to a given file descriptor.

 * You can call looper_enable/_disable/_del within a function
 * callback.
 */

/* the current implementation uses Linux's epoll facility
 * the event mask we use are simply combinations of EPOLLIN
 * EPOLLOUT, EPOLLHUP and EPOLLERR
 */
#include <sys/epoll.h>

#define  MAX_CHANNELS  16
#define  MAX_EVENTS    (MAX_CHANNELS+1)  /* each channel + the serial fd */

/* the event handler function type, 'user' is a user-specific
 * opaque pointer passed to looper_add().
 */
typedef void (*EventFunc)( void*  user, int  events );

/* bit flags for the LoopHook structure.
 *
 * HOOK_PENDING means that an event happened on the
 * corresponding file descriptor.
 *
 * HOOK_CLOSING is used to delay-close monitored
 * file descriptors.
 */
enum {
    HOOK_PENDING = (1 << 0),
    HOOK_CLOSING = (1 << 1),
};

/* A LoopHook structure is used to monitor a given
 * file descriptor and record its event handler.
 */
typedef struct {
    int        fd;
    int        wanted;  /* events we are monitoring */
    int        events;  /* events that occured */
    int        state;   /* see HOOK_XXX constants */
    void*      ev_user; /* user-provided handler parameter */
    EventFunc  ev_func; /* event handler callback */
} LoopHook;

/* Looper is the main object modeling a looper object
 */
typedef struct {
    int                  epoll_fd;
    int                  num_fds;
    int                  max_fds;
    struct epoll_event*  events;
    LoopHook*            hooks;
} Looper;

/* initialize a looper object */
static void
looper_init( Looper*  l )
{
    l->epoll_fd = epoll_create(4);
    l->num_fds  = 0;
    l->max_fds  = 0;
    l->events   = NULL;
    l->hooks    = NULL;
}

/* finalize a looper object */
static void
looper_done( Looper*  l )
{
    xfree(l->events);
    xfree(l->hooks);
    l->max_fds = 0;
    l->num_fds = 0;

    close(l->epoll_fd);
    l->epoll_fd  = -1;
}

/* return the LoopHook corresponding to a given
 * monitored file descriptor, or NULL if not found
 */
static LoopHook*
looper_find( Looper*  l, int  fd )
{
    LoopHook*  hook = l->hooks;
    LoopHook*  end  = hook + l->num_fds;

    for ( ; hook < end; hook++ ) {
        if (hook->fd == fd)
            return hook;
    }
    return NULL;
}

/* grow the arrays in the looper object */
static void
looper_grow( Looper*  l )
{
    int  old_max = l->max_fds;
    int  new_max = old_max + (old_max >> 1) + 4;
    int  n;

    xrenew( l->events, new_max );
    xrenew( l->hooks,  new_max );
    l->max_fds = new_max;

    /* now change the handles to all events */
    for (n = 0; n < l->num_fds; n++) {
        struct epoll_event ev;
        LoopHook*          hook = l->hooks + n;

        ev.events   = hook->wanted;
        ev.data.ptr = hook;
        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
    }
}

/* register a file descriptor and its event handler.
 * no event mask will be enabled
 */
static void
looper_add( Looper*  l, int  fd, EventFunc  func, void*  user )
{
    struct epoll_event  ev;
    LoopHook*           hook;

    if (l->num_fds >= l->max_fds)
        looper_grow(l);

    hook = l->hooks + l->num_fds;

    hook->fd      = fd;
    hook->ev_user = user;
    hook->ev_func = func;
    hook->state   = 0;
    hook->wanted  = 0;
    hook->events  = 0;

    fd_setnonblock(fd);

    ev.events   = 0;
    ev.data.ptr = hook;
    epoll_ctl( l->epoll_fd, EPOLL_CTL_ADD, fd, &ev );

    l->num_fds += 1;
}

/* unregister a file descriptor and its event handler
 */
static void
looper_del( Looper*  l, int  fd )
{
    LoopHook*  hook = looper_find( l, fd );

    if (!hook) {
        D( "%s: invalid fd: %d", __FUNCTION__, fd );
        return;
    }
    /* don't remove the hook yet */
    hook->state |= HOOK_CLOSING;

    epoll_ctl( l->epoll_fd, EPOLL_CTL_DEL, fd, NULL );
}

/* enable monitoring of certain events for a file
 * descriptor. This adds 'events' to the current
 * event mask
 */
static void
looper_enable( Looper*  l, int  fd, int  events )
{
    LoopHook*  hook = looper_find( l, fd );

    if (!hook) {
        D("%s: invalid fd: %d", __FUNCTION__, fd );
        return;
    }

    if (events & ~hook->wanted) {
        struct epoll_event  ev;

        hook->wanted |= events;
        ev.events   = hook->wanted;
        ev.data.ptr = hook;

        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
    }
}

/* disable monitoring of certain events for a file
 * descriptor. This ignores events that are not
 * currently enabled.
 */
static void
looper_disable( Looper*  l, int  fd, int  events )
{
    LoopHook*  hook = looper_find( l, fd );

    if (!hook) {
        D("%s: invalid fd: %d", __FUNCTION__, fd );
        return;
    }

    if (events & hook->wanted) {
        struct epoll_event  ev;

        hook->wanted &= ~events;
        ev.events   = hook->wanted;
        ev.data.ptr = hook;

        epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
    }
}

/* wait until an event occurs on one of the registered file
 * descriptors. Only returns in case of error !!
 */
static void
looper_loop( Looper*  l )
{
    for (;;) {
        int  n, count;

        do {
            count = epoll_wait( l->epoll_fd, l->events, l->num_fds, -1 );
        } while (count < 0 && errno == EINTR);

        if (count < 0) {
            D("%s: error: %s", __FUNCTION__, strerror(errno) );
            return;
        }

        if (count == 0) {
            D("%s: huh ? epoll returned count=0", __FUNCTION__);
            continue;
        }

        /* mark all pending hooks */
        for (n = 0; n < count; n++) {
            LoopHook*  hook = l->events[n].data.ptr;
            hook->state  = HOOK_PENDING;
            hook->events = l->events[n].events;
        }

        /* execute hook callbacks. this may change the 'hooks'
         * and 'events' array, as well as l->num_fds, so be careful */
        for (n = 0; n < l->num_fds; n++) {
            LoopHook*  hook = l->hooks + n;
            if (hook->state & HOOK_PENDING) {
                hook->state &= ~HOOK_PENDING;
                hook->ev_func( hook->ev_user, hook->events );
            }
        }

        /* now remove all the hooks that were closed by
         * the callbacks */
        for (n = 0; n < l->num_fds;) {
            struct epoll_event ev;
            LoopHook*  hook = l->hooks + n;

            if (!(hook->state & HOOK_CLOSING)) {
                n++;
                continue;
            }

            hook[0]     = l->hooks[l->num_fds-1];
            l->num_fds -= 1;
            ev.events   = hook->wanted;
            ev.data.ptr = hook;
            epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
        }
    }
}

#if T_ACTIVE
char*
quote( const void*  data, int  len )
{
    const char*  p   = data;
    const char*  end = p + len;
    int          count = 0;
    int          phase = 0;
    static char*  buff = NULL;

    for (phase = 0; phase < 2; phase++) {
        if (phase != 0) {
            xfree(buff);
            buff = xalloc(count+1);
        }
        count = 0;
        for (p = data; p < end; p++) {
            int  c = *p;

            if (c == '\\') {
                if (phase != 0) {
                    buff[count] = buff[count+1] = '\\';
                }
                count += 2;
                continue;
            }

            if (c >= 32 && c < 127) {
                if (phase != 0)
                    buff[count] = c;
                count += 1;
                continue;
            }


            if (c == '\t') {
                if (phase != 0) {
                    memcpy(buff+count, "<TAB>", 5);
                }
                count += 5;
                continue;
            }
            if (c == '\n') {
                if (phase != 0) {
                    memcpy(buff+count, "<LN>", 4);
                }
                count += 4;
                continue;
            }
            if (c == '\r') {
                if (phase != 0) {
                    memcpy(buff+count, "<CR>", 4);
                }
                count += 4;
                continue;
            }

            if (phase != 0) {
                buff[count+0] = '\\';
                buff[count+1] = 'x';
                buff[count+2] = "0123456789abcdef"[(c >> 4) & 15];
                buff[count+3] = "0123456789abcdef"[     (c) & 15];
            }
            count += 4;
        }
    }
    buff[count] = 0;
    return buff;
}
#endif /* T_ACTIVE */

/** PACKETS
 **
 ** We need a way to buffer data before it can be sent to the
 ** corresponding file descriptor. We use linked list of Packet
 ** objects to do this.
 **/

typedef struct Packet   Packet;

#define  MAX_PAYLOAD  4000

struct Packet {
    Packet*   next;
    int       len;
    int       channel;
    uint8_t   data[ MAX_PAYLOAD ];
};

/* we expect to alloc/free a lot of packets during
 * operations so use a single linked list of free packets
 * to keep things speedy and simple.
 */
static Packet*   _free_packets;

/* Allocate a packet */
static Packet*
packet_alloc(void)
{
    Packet*  p = _free_packets;
    if (p != NULL) {
        _free_packets = p->next;
    } else {
        xnew(p);
    }
    p->next    = NULL;
    p->len     = 0;
    p->channel = -1;
    return p;
}

/* Release a packet. This takes the address of a packet
 * pointer that will be set to NULL on exit (avoids
 * referencing dangling pointers in case of bugs)
 */
static void
packet_free( Packet*  *ppacket )
{
    Packet*  p = *ppacket;
    if (p) {
        p->next       = _free_packets;
        _free_packets = p;
        *ppacket = NULL;
    }
}

/** PACKET RECEIVER
 **
 ** Simple abstraction for something that can receive a packet
 ** from a FDHandler (see below) or something else.
 **
 ** Send a packet to it with 'receiver_post'
 **
 ** Call 'receiver_close' to indicate that the corresponding
 ** packet source was closed.
 **/

typedef void (*PostFunc) ( void*  user, Packet*  p );
typedef void (*CloseFunc)( void*  user );

typedef struct {
    PostFunc   post;
    CloseFunc  close;
    void*      user;
} Receiver;

/* post a packet to a receiver. Note that this transfers
 * ownership of the packet to the receiver.
 */
static __inline__ void
receiver_post( Receiver*  r, Packet*  p )
{
    if (r->post)
        r->post( r->user, p );
    else
        packet_free(&p);
}

/* tell a receiver the packet source was closed.
 * this will also prevent further posting to the
 * receiver.
 */
static __inline__ void
receiver_close( Receiver*  r )
{
    if (r->close) {
        r->close( r->user );
        r->close = NULL;
    }
    r->post  = NULL;
}


/** FD HANDLERS
 **
 ** these are smart listeners that send incoming packets to a receiver
 ** and can queue one or more outgoing packets and send them when
 ** possible to the FD.
 **
 ** note that we support clean shutdown of file descriptors,
 ** i.e. we try to send all outgoing packets before destroying
 ** the FDHandler.
 **/

typedef struct FDHandler      FDHandler;
typedef struct FDHandlerList  FDHandlerList;

struct FDHandler {
    int             fd;
    FDHandlerList*  list;
    char            closing;
    Receiver        receiver[1];

    /* queue of outgoing packets */
    int             out_pos;
    Packet*         out_first;
    Packet**        out_ptail;

    FDHandler*      next;
    FDHandler**     pref;

};

struct FDHandlerList {
    /* the looper that manages the fds */
    Looper*      looper;

    /* list of active FDHandler objects */
    FDHandler*   active;

    /* list of closing FDHandler objects.
     * these are waiting to push their
     * queued packets to the fd before
     * freeing themselves.
     */
    FDHandler*   closing;

};

/* remove a FDHandler from its current list */
static void
fdhandler_remove( FDHandler*  f )
{
    f->pref[0] = f->next;
    if (f->next)
        f->next->pref = f->pref;
}

/* add a FDHandler to a given list */
static void
fdhandler_prepend( FDHandler*  f, FDHandler**  list )
{
    f->next = list[0];
    f->pref = list;
    list[0] = f;
    if (f->next)
        f->next->pref = &f->next;
}

/* initialize a FDHandler list */
static void
fdhandler_list_init( FDHandlerList*  list, Looper*  looper )
{
    list->looper  = looper;
    list->active  = NULL;
    list->closing = NULL;
}


/* close a FDHandler (and free it). Note that this will not
 * perform a graceful shutdown, i.e. all packets in the
 * outgoing queue will be immediately free.
 *
 * this *will* notify the receiver that the file descriptor
 * was closed.
 *
 * you should call fdhandler_shutdown() if you want to
 * notify the FDHandler that its packet source is closed.
 */
static void
fdhandler_close( FDHandler*  f )
{
    /* notify receiver */
    receiver_close(f->receiver);

    /* remove the handler from its list */
    fdhandler_remove(f);

    /* get rid of outgoing packet queue */
    if (f->out_first != NULL) {
        Packet*  p;
        while ((p = f->out_first) != NULL) {
            f->out_first = p->next;
            packet_free(&p);
        }
    }

    /* get rid of file descriptor */
    if (f->fd >= 0) {
        looper_del( f->list->looper, f->fd );
        close(f->fd);
        f->fd = -1;
    }

    f->list = NULL;
    xfree(f);
}

/* Ask the FDHandler to cleanly shutdown the connection,
 * i.e. send any pending outgoing packets then auto-free
 * itself.
 */
static void
fdhandler_shutdown( FDHandler*  f )
{
    /* prevent later fdhandler_close() to
     * call the receiver's close.
     */
    f->receiver->close = NULL;

    if (f->out_first != NULL && !f->closing)
    {
        /* move the handler to the 'closing' list */
        f->closing = 1;
        fdhandler_remove(f);
        fdhandler_prepend(f, &f->list->closing);
        return;
    }

    fdhandler_close(f);
}

/* Enqueue a new packet that the FDHandler will
 * send through its file descriptor.
 */
static void
fdhandler_enqueue( FDHandler*  f, Packet*  p )
{
    Packet*  first = f->out_first;

    p->next         = NULL;
    f->out_ptail[0] = p;
    f->out_ptail    = &p->next;

    if (first == NULL) {
        f->out_pos = 0;
        looper_enable( f->list->looper, f->fd, EPOLLOUT );
    }
}


/* FDHandler file descriptor event callback for read/write ops */
static void
fdhandler_event( FDHandler*  f, int  events )
{
   int  len;

    /* in certain cases, it's possible to have both EPOLLIN and
     * EPOLLHUP at the same time. This indicates that there is incoming
     * data to read, but that the connection was nonetheless closed
     * by the sender. Be sure to read the data before closing
     * the receiver to avoid packet loss.
     */

    if (events & EPOLLIN) {
        Packet*  p = packet_alloc();
        int      len;

        if ((len = fd_read(f->fd, p->data, MAX_PAYLOAD)) < 0) {
            D("%s: can't recv: %s", __FUNCTION__, strerror(errno));
            packet_free(&p);
        } else if (len > 0) {
            p->len     = len;
            p->channel = -101;  /* special debug value, not used */
            receiver_post( f->receiver, p );
        }
    }

    if (events & (EPOLLHUP|EPOLLERR)) {
        /* disconnection */
        D("%s: disconnect on fd %d", __FUNCTION__, f->fd);
        fdhandler_close(f);
        return;
    }

    if (events & EPOLLOUT && f->out_first) {
        Packet*  p = f->out_first;
        int      avail, len;

        avail = p->len - f->out_pos;
        if ((len = fd_write(f->fd, p->data + f->out_pos, avail)) < 0) {
            D("%s: can't send: %s", __FUNCTION__, strerror(errno));
        } else {
            f->out_pos += len;
            if (f->out_pos >= p->len) {
                f->out_pos   = 0;
                f->out_first = p->next;
                packet_free(&p);
                if (f->out_first == NULL) {
                    f->out_ptail = &f->out_first;
                    looper_disable( f->list->looper, f->fd, EPOLLOUT );
                }
            }
        }
    }
}


/* Create a new FDHandler that monitors read/writes */
static FDHandler*
fdhandler_new( int             fd,
               FDHandlerList*  list,
               Receiver*       receiver )
{
    FDHandler*  f = xalloc0(sizeof(*f));

    f->fd          = fd;
    f->list        = list;
    f->receiver[0] = receiver[0];
    f->out_first   = NULL;
    f->out_ptail   = &f->out_first;
    f->out_pos     = 0;

    fdhandler_prepend(f, &list->active);

    looper_add( list->looper, fd, (EventFunc) fdhandler_event, f );
    looper_enable( list->looper, fd, EPOLLIN );

    return f;
}


/* event callback function to monitor accepts() on server sockets.
 * the convention used here is that the receiver will receive a
 * dummy packet with the new client socket in p->channel
 */
static void
fdhandler_accept_event( FDHandler*  f, int  events )
{
    if (events & EPOLLIN) {
        /* this is an accept - send a dummy packet to the receiver */
        Packet*  p = packet_alloc();

        D("%s: accepting on fd %d", __FUNCTION__, f->fd);
        p->data[0] = 1;
        p->len     = 1;
        p->channel = fd_accept(f->fd);
        if (p->channel < 0) {
            D("%s: accept failed ?: %s", __FUNCTION__, strerror(errno));
            packet_free(&p);
            return;
        }
        receiver_post( f->receiver, p );
    }

    if (events & (EPOLLHUP|EPOLLERR)) {
        /* disconnecting !! */
        D("%s: closing accept fd %d", __FUNCTION__, f->fd);
        fdhandler_close(f);
        return;
    }
}


/* Create a new FDHandler used to monitor new connections on a
 * server socket. The receiver must expect the new connection
 * fd in the 'channel' field of a dummy packet.
 */
static FDHandler*
fdhandler_new_accept( int             fd,
                      FDHandlerList*  list,
                      Receiver*       receiver )
{
    FDHandler*  f = xalloc0(sizeof(*f));

    f->fd          = fd;
    f->list        = list;
    f->receiver[0] = receiver[0];

    fdhandler_prepend(f, &list->active);

    looper_add( list->looper, fd, (EventFunc) fdhandler_accept_event, f );
    looper_enable( list->looper, fd, EPOLLIN );
    listen( fd, 5 );

    return f;
}

/** SERIAL CONNECTION STATE
 **
 ** The following is used to handle the framing protocol
 ** used on the serial port connection.
 **/

/* each packet is made of a 6 byte header followed by a payload
 * the header looks like:
 *
 *   offset   size    description
 *       0       2    a 2-byte hex string for the channel number
 *       4       4    a 4-char hex string for the size of the payload
 *       6       n    the payload itself
 */
#define  HEADER_SIZE    6
#define  CHANNEL_OFFSET 0
#define  LENGTH_OFFSET  2
#define  CHANNEL_SIZE   2
#define  LENGTH_SIZE    4

#define  CHANNEL_CONTROL  0

/* The Serial object receives data from the serial port,
 * extracts the payload size and channel index, then sends
 * the resulting messages as a packet to a generic receiver.
 *
 * You can also use serial_send to send a packet through
 * the serial port.
 */
typedef struct Serial {
    FDHandler*  fdhandler;   /* used to monitor serial port fd */
    Receiver    receiver[1]; /* send payload there */
    int         in_len;      /* current bytes in input packet */
    int         in_datalen;  /* payload size, or 0 when reading header */
    int         in_channel;  /* extracted channel number */
    Packet*     in_packet;   /* used to read incoming packets */
} Serial;


/* a callback called when the serial port's fd is closed */
static void
serial_fd_close( Serial*  s )
{
    fatal("unexpected serial port close !!");
}

static void
serial_dump( Packet*  p, const char*  funcname )
{
    T("%s: %03d bytes: '%s'",
      funcname, p->len, quote(p->data, p->len));
}

/* a callback called when a packet arrives from the serial port's FDHandler.
 *
 * This will essentially parse the header, extract the channel number and
 * the payload size and store them in 'in_datalen' and 'in_channel'.
 *
 * After that, the payload is sent to the receiver once completed.
 */
static void
serial_fd_receive( Serial*  s, Packet*  p )
{
    int      rpos  = 0, rcount = p->len;
    Packet*  inp   = s->in_packet;
    int      inpos = s->in_len;

    serial_dump( p, __FUNCTION__ );

    while (rpos < rcount)
    {
        int  avail = rcount - rpos;

        /* first, try to read the header */
        if (s->in_datalen == 0) {
            int  wanted = HEADER_SIZE - inpos;
            if (avail > wanted)
                avail = wanted;

            memcpy( inp->data + inpos, p->data + rpos, avail );
            inpos += avail;
            rpos  += avail;

            if (inpos == HEADER_SIZE) {
                s->in_datalen = hex2int( inp->data + LENGTH_OFFSET,  LENGTH_SIZE );
                s->in_channel = hex2int( inp->data + CHANNEL_OFFSET, CHANNEL_SIZE );

                if (s->in_datalen <= 0) {
                    D("ignoring %s packet from serial port",
                      s->in_datalen ? "empty" : "malformed");
                    s->in_datalen = 0;
                }

                //D("received %d bytes packet for channel %d", s->in_datalen, s->in_channel);
                inpos = 0;
            }
        }
        else /* then, populate the packet itself */
        {
            int   wanted = s->in_datalen - inpos;

            if (avail > wanted)
                avail = wanted;

            memcpy( inp->data + inpos, p->data + rpos, avail );
            inpos += avail;
            rpos  += avail;

            if (inpos == s->in_datalen) {
                if (s->in_channel < 0) {
                    D("ignoring %d bytes addressed to channel %d",
                       inpos, s->in_channel);
                } else {
                    inp->len     = inpos;
                    inp->channel = s->in_channel;
                    receiver_post( s->receiver, inp );
                    s->in_packet  = inp = packet_alloc();
                }
                s->in_datalen = 0;
                inpos         = 0;
            }
        }
    }
    s->in_len = inpos;
    packet_free(&p);
}


/* send a packet to the serial port.
 * this assumes that p->len and p->channel contain the payload's
 * size and channel and will add the appropriate header.
 */
static void
serial_send( Serial*  s, Packet*  p )
{
    Packet*  h = packet_alloc();

    //D("sending to serial %d bytes from channel %d: '%.*s'", p->len, p->channel, p->len, p->data);

    /* insert a small header before this packet */
    h->len = HEADER_SIZE;
    int2hex( p->len,     h->data + LENGTH_OFFSET,  LENGTH_SIZE );
    int2hex( p->channel, h->data + CHANNEL_OFFSET, CHANNEL_SIZE );

    serial_dump( h, __FUNCTION__ );
    serial_dump( p, __FUNCTION__ );

    fdhandler_enqueue( s->fdhandler, h );
    fdhandler_enqueue( s->fdhandler, p );
}


/* initialize serial reader */
static void
serial_init( Serial*         s,
             int             fd,
             FDHandlerList*  list,
             Receiver*       receiver )
{
    Receiver  recv;

    recv.user  = s;
    recv.post  = (PostFunc)  serial_fd_receive;
    recv.close = (CloseFunc) serial_fd_close;

    s->receiver[0] = receiver[0];

    s->fdhandler = fdhandler_new( fd, list, &recv );
    s->in_len     = 0;
    s->in_datalen = 0;
    s->in_channel = 0;
    s->in_packet  = packet_alloc();
}


/** CLIENTS
 **/

typedef struct Client       Client;
typedef struct Multiplexer  Multiplexer;

/* A Client object models a single qemud client socket
 * connection in the emulated system.
 *
 * the client first sends the name of the system service
 * it wants to contact (no framing), then waits for a 2
 * byte answer from qemud.
 *
 * the answer is either "OK" or "KO" to indicate
 * success or failure.
 *
 * In case of success, the client can send messages
 * to the service.
 *
 * In case of failure, it can disconnect or try sending
 * the name of another service.
 */
struct Client {
    Client*       next;
    Client**      pref;
    int           channel;
    char          registered;
    FDHandler*    fdhandler;
    Multiplexer*  multiplexer;
};

struct Multiplexer {
    Client*        clients;
    int            last_channel;
    Serial         serial[1];
    Looper         looper[1];
    FDHandlerList  fdhandlers[1];
};


static int   multiplexer_open_channel( Multiplexer*  mult, Packet*  p );
static void  multiplexer_close_channel( Multiplexer*  mult, int  channel );
static void  multiplexer_serial_send( Multiplexer* mult, int  channel, Packet*  p );

static void
client_dump( Client*  c, Packet*  p, const char*  funcname )
{
    T("%s: client %p (%d): %3d bytes: '%s'",
      funcname, c, c->fdhandler->fd,
      p->len, quote(p->data, p->len));
}

/* destroy a client */
static void
client_free( Client*  c )
{
    /* remove from list */
    c->pref[0] = c->next;
    if (c->next)
        c->next->pref = c->pref;

    c->channel    = -1;
    c->registered = 0;

    /* gently ask the FDHandler to shutdown to
     * avoid losing queued outgoing packets */
    if (c->fdhandler != NULL) {
        fdhandler_shutdown(c->fdhandler);
        c->fdhandler = NULL;
    }

    xfree(c);
}


/* a function called when a client socket receives data */
static void
client_fd_receive( Client*  c, Packet*  p )
{
    client_dump(c, p, __FUNCTION__);

    if (c->registered) {
        /* the client is registered, just send the
         * data through the serial port
         */
        multiplexer_serial_send(c->multiplexer, c->channel, p);
        return;
    }

    if (c->channel > 0) {
        /* the client is waiting registration results.
         * this should not happen because the client
         * should wait for our 'ok' or 'ko'.
         * close the connection.
         */
         D("%s: bad client sending data before end of registration",
           __FUNCTION__);
     BAD_CLIENT:
         packet_free(&p);
         client_free(c);
         return;
    }

    /* the client hasn't registered a service yet,
     * so this must be the name of a service, call
     * the multiplexer to start registration for
     * it.
     */
    D("%s: attempting registration for service '%.*s'",
      __FUNCTION__, p->len, p->data);
    c->channel = multiplexer_open_channel(c->multiplexer, p);
    if (c->channel < 0) {
        D("%s: service name too long", __FUNCTION__);
        goto BAD_CLIENT;
    }
    D("%s:    -> received channel id %d", __FUNCTION__, c->channel);
    packet_free(&p);
}


/* a function called when the client socket is closed. */
static void
client_fd_close( Client*  c )
{
    T("%s: client %p (%d)", __FUNCTION__, c, c->fdhandler->fd);

    /* no need to shutdown the FDHandler */
    c->fdhandler = NULL;

    /* tell the emulator we're out */
    if (c->channel > 0)
        multiplexer_close_channel(c->multiplexer, c->channel);

    /* free the client */
    client_free(c);
}

/* a function called when the multiplexer received a registration
 * response from the emulator for a given client.
 */
static void
client_registration( Client*  c, int  registered )
{
    Packet*  p = packet_alloc();

    /* sends registration status to client */
    if (!registered) {
        D("%s: registration failed for client %d", __FUNCTION__, c->channel);
        memcpy( p->data, "KO", 2 );
        p->len = 2;
    } else {
        D("%s: registration succeeded for client %d", __FUNCTION__, c->channel);
        memcpy( p->data, "OK", 2 );
        p->len = 2;
    }
    client_dump(c, p, __FUNCTION__);
    fdhandler_enqueue(c->fdhandler, p);

    /* now save registration state
     */
    c->registered = registered;
    if (!registered) {
        /* allow the client to try registering another service */
        c->channel = -1;
    }
}

/* send data to a client */
static void
client_send( Client*  c, Packet*  p )
{
    client_dump(c, p, __FUNCTION__);
    fdhandler_enqueue(c->fdhandler, p);
}


/* Create new client socket handler */
static Client*
client_new( Multiplexer*    mult,
            int             fd,
            FDHandlerList*  pfdhandlers,
            Client**        pclients )
{
    Client*   c;
    Receiver  recv;

    xnew(c);

    c->multiplexer = mult;
    c->next        = NULL;
    c->pref        = &c->next;
    c->channel     = -1;
    c->registered  = 0;

    recv.user  = c;
    recv.post  = (PostFunc)  client_fd_receive;
    recv.close = (CloseFunc) client_fd_close;

    c->fdhandler = fdhandler_new( fd, pfdhandlers, &recv );

    /* add to client list */
    c->next   = *pclients;
    c->pref   = pclients;
    *pclients = c;
    if (c->next)
        c->next->pref = &c->next;

    return c;
}

/**  GLOBAL MULTIPLEXER
 **/

/* find a client by its channel */
static Client*
multiplexer_find_client( Multiplexer*  mult, int  channel )
{
    Client* c = mult->clients;

    for ( ; c != NULL; c = c->next ) {
        if (c->channel == channel)
            return c;
    }
    return NULL;
}

/* handle control messages coming from the serial port
 * on CONTROL_CHANNEL.
 */
static void
multiplexer_handle_control( Multiplexer*  mult, Packet*  p )
{
    /* connection registration success */
    if (p->len == 13 && !memcmp(p->data, "ok:connect:", 11)) {
        int      channel = hex2int(p->data+11, 2);
        Client*  client  = multiplexer_find_client(mult, channel);

        /* note that 'client' can be NULL if the corresponding
         * socket was closed before the emulator response arrived.
         */
        if (client != NULL) {
            client_registration(client, 1);
        } else {
            D("%s: NULL client: '%.*s'", __FUNCTION__, p->len, p->data+11);
        }
        goto EXIT;
    }

    /* connection registration failure */
    if (p->len == 13 && !memcmp(p->data, "ko:connect:",11)) {
        int     channel = hex2int(p->data+11, 2);
        Client* client  = multiplexer_find_client(mult, channel);

        if (client != NULL)
            client_registration(client, 0);

        goto EXIT;
    }

    /* emulator-induced client disconnection */
    if (p->len == 13 && !memcmp(p->data, "disconnect:",11)) {
        int      channel = hex2int(p->data+11, 2);
        Client*  client  = multiplexer_find_client(mult, channel);

        if (client != NULL)
            client_free(client);

        goto EXIT;
    }

    /* A message that begins with "X00" is a probe sent by
     * the emulator used to detect which version of qemud it runs
     * against (in order to detect 1.0/1.1 system images. Just
     * silently ignore it there instead of printing an error
     * message.
     */
    if (p->len >= 3 && !memcmp(p->data,"X00",3)) {
        goto EXIT;
    }

    D("%s: unknown control message (%d bytes): '%.*s'",
      __FUNCTION__, p->len, p->len, p->data);

EXIT:
    packet_free(&p);
}

/* a function called when an incoming packet comes from the serial port */
static void
multiplexer_serial_receive( Multiplexer*  mult, Packet*  p )
{
    Client*  client;

    T("%s: channel=%d '%.*s'", __FUNCTION__, p->channel, p->len, p->data);

    if (p->channel == CHANNEL_CONTROL) {
        multiplexer_handle_control(mult, p);
        return;
    }

    client = multiplexer_find_client(mult, p->channel);
    if (client != NULL) {
        client_send(client, p);
        return;
    }

    D("%s: discarding packet for unknown channel %d", __FUNCTION__, p->channel);
    packet_free(&p);
}

/* a function called when the serial reader closes */
static void
multiplexer_serial_close( Multiplexer*  mult )
{
    fatal("unexpected close of serial reader");
}

/* a function called to send a packet to the serial port */
static void
multiplexer_serial_send( Multiplexer*  mult, int  channel, Packet*  p )
{
    p->channel = channel;
    serial_send( mult->serial, p );
}



/* a function used by a client to allocate a new channel id and
 * ask the emulator to open it. 'service' must be a packet containing
 * the name of the service in its payload.
 *
 * returns -1 if the service name is too long.
 *
 * notice that client_registration() will be called later when
 * the answer arrives.
 */
static int
multiplexer_open_channel( Multiplexer*  mult, Packet*  service )
{
    Packet*   p = packet_alloc();
    int       len, channel;

    /* find a free channel number, assume we don't have many
     * clients here. */
    {
        Client*  c;
    TRY_AGAIN:
        channel = (++mult->last_channel) & 0xff;

        for (c = mult->clients; c != NULL; c = c->next)
            if (c->channel == channel)
                goto TRY_AGAIN;
    }

    len = snprintf((char*)p->data, sizeof p->data, "connect:%.*s:%02x", service->len, service->data, channel);
    if (len >= (int)sizeof(p->data)) {
        D("%s: weird, service name too long (%d > %d)", __FUNCTION__, len, sizeof(p->data));
        packet_free(&p);
        return -1;
    }
    p->channel = CHANNEL_CONTROL;
    p->len     = len;

    serial_send(mult->serial, p);
    return channel;
}

/* used to tell the emulator a channel was closed by a client */
static void
multiplexer_close_channel( Multiplexer*  mult, int  channel )
{
    Packet*  p   = packet_alloc();
    int      len = snprintf((char*)p->data, sizeof(p->data), "disconnect:%02x", channel);

    if (len > (int)sizeof(p->data)) {
        /* should not happen */
        return;
    }

    p->channel = CHANNEL_CONTROL;
    p->len     = len;

    serial_send(mult->serial, p);
}

/* this function is used when a new connection happens on the control
 * socket.
 */
static void
multiplexer_control_accept( Multiplexer*  m, Packet*  p )
{
    /* the file descriptor for the new socket connection is
     * in p->channel. See fdhandler_accept_event() */
    int      fd     = p->channel;
    Client*  client = client_new( m, fd, m->fdhandlers, &m->clients );

    D("created client %p listening on fd %d", client, fd);

    /* free dummy packet */
    packet_free(&p);
}

static void
multiplexer_control_close( Multiplexer*  m )
{
    fatal("unexpected multiplexer control close");
}

static void
multiplexer_init( Multiplexer*  m, const char*  serial_dev )
{
    int       fd, control_fd;
    Receiver  recv;

    /* initialize looper and fdhandlers list */
    looper_init( m->looper );
    fdhandler_list_init( m->fdhandlers, m->looper );

    /* open the serial port */
    do {
        fd = open(serial_dev, O_RDWR);
    } while (fd < 0 && errno == EINTR);

    if (fd < 0) {
        fatal( "%s: could not open '%s': %s", __FUNCTION__, serial_dev,
               strerror(errno) );
    }
    // disable echo on serial lines
    if ( !memcmp( serial_dev, "/dev/ttyS", 9 ) ) {
        struct termios  ios;
        tcgetattr( fd, &ios );
        ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
        tcsetattr( fd, TCSANOW, &ios );
    }

    /* initialize the serial reader/writer */
    recv.user  = m;
    recv.post  = (PostFunc)  multiplexer_serial_receive;
    recv.close = (CloseFunc) multiplexer_serial_close;

    serial_init( m->serial, fd, m->fdhandlers, &recv );

    /* open the qemud control socket */
    recv.user  = m;
    recv.post  = (PostFunc)  multiplexer_control_accept;
    recv.close = (CloseFunc) multiplexer_control_close;

    fd = android_get_control_socket(CONTROL_SOCKET_NAME);
    if (fd < 0) {
        fatal("couldn't get fd for control socket '%s'", CONTROL_SOCKET_NAME);
    }

    fdhandler_new_accept( fd, m->fdhandlers, &recv );

    /* initialize clients list */
    m->clients = NULL;
}

/** MAIN LOOP
 **/

static Multiplexer  _multiplexer[1];

int  main( void )
{
    Multiplexer*  m = _multiplexer;

   /* extract the name of our serial device from the kernel
    * boot options that are stored in /proc/cmdline
    */
#define  KERNEL_OPTION  "android.qemud="

    {
        char          buff[1024];
        int           fd, len;
        char*         p;
        char*         q;

        fd = open( "/proc/cmdline", O_RDONLY );
        if (fd < 0) {
            D("%s: can't open /proc/cmdline !!: %s", __FUNCTION__,
            strerror(errno));
            exit(1);
        }

        len = fd_read( fd, buff, sizeof(buff)-1 );
        close(fd);
        if (len < 0) {
            D("%s: can't read /proc/cmdline: %s", __FUNCTION__,
            strerror(errno));
            exit(1);
        }
        buff[len] = 0;

        p = strstr( buff, KERNEL_OPTION );
        if (p == NULL) {
            D("%s: can't find '%s' in /proc/cmdline",
            __FUNCTION__, KERNEL_OPTION );
            exit(1);
        }

        p += sizeof(KERNEL_OPTION)-1;  /* skip option */
        q  = p;
        while ( *q && *q != ' ' && *q != '\t' )
            q += 1;

        snprintf( buff, sizeof(buff), "/dev/%.*s", q-p, p );

        multiplexer_init( m, buff );
    }

    D( "entering main loop");
    looper_loop( m->looper );
    D( "unexpected termination !!" );
    return 0;
}
