/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Encapsulates exchange protocol between the emulator, and an Android device
 * that is connected to the host via USB. The communication is established over
 * a TCP port forwarding, enabled by ADB.
 */

#include "android/android-device.h"
#include "iolooper.h"

#define  E(...)    derror(__VA_ARGS__)
#define  W(...)    dwarning(__VA_ARGS__)
#define  D(...)    VERBOSE_PRINT(adevice,__VA_ARGS__)
#define  D_ACTIVE  VERBOSE_CHECK(adevice)

/********************************************************************************
 *                       Common android device socket
 *******************************************************************************/

/* Milliseconds between retrying asynchronous connections to the device. */
#define ADS_RETRY_CONNECTION_TIMEOUT 3000

/* Socket type. */
typedef enum ADSType {
    /* Query socket. */
    ADS_TYPE_QUERY = 0,
    /* Events socket. */
    ADS_TYPE_EVENT = 1
} ADSType;

/* Status of the socket. */
typedef enum ADSStatus {
    /* Socket is disconnected. */
    ADS_DISCONNECTED,
    /* Connection process has been started. */
    ADS_CONNECTING,
    /* Connection has been established. */
    ADS_CONNECTED,
    /* Socket has been registered with the server. */
    ADS_REGISTERED,
} ADSStatus;

/* Identifies socket as a "query" socket with the server. */
static const char* _ads_query_socket_id = "query";
/* Identifies socket as an "event" socket with the server. */
static const char* _ads_event_socket_id = "event";

/* Android device socket descriptor. */
typedef struct AndroidDevSocket AndroidDevSocket;

/*
 * Callback routines.
 */

/* Callback routine that is called when a socket is connected.
 * Param:
 *  opaque - Opaque pointer associated with the socket. Typicaly it's the same
 *      pointer that is associated with AndroidDevice instance.
 *  ads - Connection socket.
 *  failure - If zero, indicates that socket has been successuly connected. If a
 *      connection error has occured, this parameter contains the error code (as
 *      in 'errno).
 */
typedef void (*ads_socket_connected_cb)(void* opaque,
                                        struct AndroidDevSocket* ads,
                                        int failure);

/* Android device socket descriptor. */
struct AndroidDevSocket {
    /* Socket type. */
    ADSType             type;
    /* Socket status. */
    ADSStatus           socket_status;
    /* TCP address for the socket. */
    SockAddress         address;
    /* Android device descriptor that owns the socket. */
    AndroidDevice*      ad;
    /* Opaque pointer associated with the socket. Typicaly it's the same
     * pointer that is associated with AndroidDevice instance.*/
    void*               opaque;
    /* Deadline for current I/O performed on the socket. */
    Duration            deadline;
    /* Socket's file descriptor. */
    int                 fd;
};

/* Query socket descriptor. */
typedef struct AndroidQuerySocket {
    /* Common device socket. */
    AndroidDevSocket    dev_socket;
} AndroidQuerySocket;

/* Event socket descriptor. */
typedef struct AndroidEventSocket {
    /* Common socket descriptor. */
    AndroidDevSocket        dev_socket;
    /* Asynchronous connector to the device. */
    AsyncConnector          connector[1];
    /* I/O port for asynchronous I/O on this socket. */
    LoopIo                  io[1];
    /* Asynchronous string reader. */
    AsyncLineReader         alr;
    /* Callback to call at the end of the asynchronous connection to this socket.
     * Can be NULL. */
    ads_socket_connected_cb on_connected;
    /* Callback to call when an event is received on this socket. Can be NULL. */
    event_cb                on_event;
} AndroidEventSocket;

/* Android device descriptor. */
struct AndroidDevice {
    /* Query socket for the device. */
    AndroidQuerySocket  query_socket;
    /* Event socket for the device. */
    AndroidEventSocket  event_socket;
    /* An opaque pointer associated with this descriptor. */
    void*               opaque;
    /* I/O looper for synchronous I/O on the sockets for this device. */
    IoLooper*           io_looper;
    /* Timer that is used to retry asynchronous connections. */
    LoopTimer           timer[1];
    /* I/O looper for asynchronous I/O. */
    Looper*             looper;
    /* Callback to call when device is fully connected. */
    device_connected_cb on_connected;
    /* I/O failure callback .*/
    io_failure_cb       on_io_failure;
};

/********************************************************************************
 *                        Common socket declarations
 *******************************************************************************/

/* Initializes common device socket.
 * Param:
 *  ads - Socket descriptor to initialize.
 *  opaque - An opaque pointer to associate with the socket. Typicaly it's the
 *      same pointer that is associated with AndroidDevice instance.
 *  ad - Android device descriptor that owns the socket.
 *  port - Socket's TCP port.
 *  type - Socket type (query, or event).
 */
static int _android_dev_socket_init(AndroidDevSocket* ads,
                                    void* opaque,
                                    AndroidDevice* ad,
                                    int port,
                                    ADSType type);

/* Destroys socket descriptor. */
static void _android_dev_socket_destroy(AndroidDevSocket* ads);

/* Synchronously connects to the socket, and registers it with the server.
 * Param:
 *  ads - Socket to connect. Must have 'deadline' field properly setup.
 * Return:
 *  0 on success, -1 on failure with errno containing the reason for failure.
 */
static int _android_dev_socket_connect(AndroidDevSocket* ads);

/* Synchronously registers a connected socket with the server.
 * Param:
 *  ads - Socket to register. Must be connected, and must have 'deadline' field
 *      properly setup.
 * Return:
 *  0 on success, -1 on failure with errno containing the reason for failure.
 */
static int _android_dev_socket_register(AndroidDevSocket* ads);

/* Disconnects the socket (if it was connected) */
static void _android_dev_socket_disconnect(AndroidDevSocket* ads);

/* Synchronously sends data to the socket.
 * Param:
 *  ads - Socket to send the data to. Must be connected, and must have 'deadline'
 *      field properly setup.
 *  buff, buffsize - Buffer to send.
 * Return:
 *  Number of bytes sent on success, or -1 on failure with errno containing the
 *  reason for failure.
 */
static int _android_dev_socket_send(AndroidDevSocket* ads,
                                    const char* buff,
                                    int buffsize);

/* Synchronously receives data from the socket.
 * Param:
 *  ads - Socket to receive the data from. Must be connected, and must have
 *      'deadline' field properly setup.
 *  buff, buffsize - Buffer where to receive data.
 * Return:
 *  Number of bytes received on success, or -1 on failure with errno containing
 *  the reason for failure.
 */
static int _android_dev_socket_recv(AndroidDevSocket* ads,
                                    char* buf,
                                    int bufsize);

/* Synchronously reads zero-terminated string from the socket.
 * Param:
 *  ads - Socket to read the string from. Must be connected, and must have
 *      'deadline' field properly setup.
 *  str, strsize - Buffer where to read the string.
 * Return:
 *  Number of charactes read into the string buffer (including zero-terminator)
 *  on success, or -1 on failure with 'errno' containing the reason for failure.
 *  If this routine returns -1, and errno contains ENOMEM, this is an indicator
 *  that supplied string buffer was too small for the receiving string.
 */
static int _android_dev_socket_read_string(AndroidDevSocket* ads,
                                           char* str,
                                           int strsize);

/* Synchronously reads zero-terminated query response from the socket.
 * All queries respond with an 'ok', or 'ko' prefix, indicating a success, or
 * failure. Prefix can be followed by more query response data, separated from
 * the prefix with a ':' character. This routine helps separating prefix from the
 * data, by placing only the query response data into provided buffer. 'ko' or
 * 'ok' will be encoded in the return value.
 * Param:
 *  ads - Socket to read the response from. Must be connected, and must have
 *      'deadline' field properly setup.
 *  data, datasize - Buffer where to read the query response data.
 * Return:
 *  Number of charactes read into the data buffer (including zero-terminator) on
 *  success, or -1 on failure with errno containing the reason for failure.
 *  If the query has been completed with 'ko', this routine will return -1, with
 *  errno set to 0. If this routine returned -1, and errno is set to EINVAL, this
 *  indicates that reply string didn't match expected query reply format.
 */
static int _android_dev_socket_read_response(AndroidDevSocket* ads,
                                             char* str,
                                             int strsize);

/* Gets ID string for the channel. */
AINLINED const char*
_ads_id_str(AndroidDevSocket* ads)
{
    return (ads->type == ADS_TYPE_QUERY) ? _ads_query_socket_id :
                                           _ads_event_socket_id;
}

/* Gets socket's TCP port. */
AINLINED int
_ads_port(AndroidDevSocket* ads)
{
    return sock_address_get_port(&ads->address);
}

/* Gets synchronous I/O looper for the socket. */
AINLINED IoLooper*
_ads_io_looper(AndroidDevSocket* ads)
{
    return ads->ad->io_looper;
}

/* Sets deadline on a socket operation, given relative timeout.
 * Param:
 *  ads - Socket descriptor to set deadline for.
 *  to - Relative timeout (in millisec) for the operation.
 *      AD_INFINITE_WAIT passed in this parameter means "no deadline".
 */
AINLINED void
_ads_set_deadline(AndroidDevSocket* ads, int to)
{
    ads->deadline = (to == AD_INFINITE_WAIT) ? DURATION_INFINITE :
                                               iolooper_now() + to;
}

/********************************************************************************
 *                        Common socket implementation
 *******************************************************************************/

static int
_android_dev_socket_init(AndroidDevSocket* ads,
                         void* opaque,
                         AndroidDevice* ad,
                         int port,
                         ADSType type)
{
    ads->type = type;
    ads->socket_status = ADS_DISCONNECTED;
    ads->opaque = opaque;
    ads->ad = ad;
    ads->fd = -1;
    sock_address_init_inet(&ads->address, SOCK_ADDRESS_INET_LOOPBACK, port);

    return 0;
}

static void
_android_dev_socket_destroy(AndroidDevSocket* ads)
{
    /* Make sure it's disconnected. */
    _android_dev_socket_disconnect(ads);

    /* Finalize socket address. */
    sock_address_done(&ads->address);
    memset(&ads->address, 0, sizeof(ads->address));
}

static int
_android_dev_socket_connect(AndroidDevSocket* ads)
{
    int res;

    /* Create communication socket. */
    ads->fd = socket_create_inet(SOCKET_STREAM);
    if (ads->fd < 0) {
        D("Unable to create socket for channel '%s'@%d: %s",
          _ads_id_str(ads), _ads_port(ads), strerror(errno));
        return -1;
    }
    socket_set_nonblock(ads->fd);

    /* Synchronously connect to it. */
    ads->socket_status = ADS_CONNECTING;
    iolooper_add_write(_ads_io_looper(ads), ads->fd);
    res = socket_connect(ads->fd, &ads->address);
    while (res < 0 && errno == EINTR) {
        res = socket_connect(ads->fd, &ads->address);
    }

    if (res && (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN)) {
        /* Connection is delayed. Wait for it until timeout expires. */
        res = iolooper_wait_absolute(_ads_io_looper(ads), ads->deadline);
        if (res > 0) {
            /* Pick up on possible connection error. */
            errno = socket_get_error(ads->fd);
            res = (errno == 0) ? 0 : -1;
        } else {
            res = -1;
        }
    }
    iolooper_del_write(_ads_io_looper(ads), ads->fd);

    if (res == 0) {
        D("Channel '%s'@%d is connected", _ads_id_str(ads), _ads_port(ads));
        /* Socket is connected. Now register it with the server. */
        ads->socket_status = ADS_CONNECTED;
        res = _android_dev_socket_register(ads);
    } else {
        D("Unable to connect channel '%s' to port %d: %s",
          _ads_id_str(ads), _ads_port(ads), strerror(errno));
    }

    if (res) {
        _android_dev_socket_disconnect(ads);
    }

    return res;
}

static int
_android_dev_socket_register(AndroidDevSocket* ads)
{
    /* Make sure that socket is connected. */
    if (ads->socket_status < ADS_CONNECTED) {
        D("Attempt to register a disconnected channel '%s'@%d",
          _ads_id_str(ads),  _ads_port(ads));
        errno = ECONNRESET;
        return -1;
    }

    /* Register this socket accordingly to its type. */
    const char* reg_str = _ads_id_str(ads);
    int res = _android_dev_socket_send(ads, reg_str, strlen(reg_str) + 1);
    if (res > 0) {
        /* Receive reply. Note that according to the protocol, the server should
         * reply to channel registration with 'ok', or 'ko' (just like with queries),
         * so we can use query reply reader here. */
        char reply[256];
        res = _android_dev_socket_read_response(ads, reply, sizeof(reply));
        if (res >= 0) {
            /* Socket is now registered. */
            ads->socket_status = ADS_REGISTERED;
            D("Channel '%s'@%d is registered", _ads_id_str(ads), _ads_port(ads));
            res = 0;
        } else {
            if (errno == 0) {
                /* 'ko' condition */
                D("Device failed registration of channel '%s'@%d: %s",
                  _ads_id_str(ads), _ads_port(ads), reply);
                errno = EINVAL;
            } else {
                D("I/O failure while registering channel '%s'@%d: %s",
                  _ads_id_str(ads), _ads_port(ads), strerror(errno));
            }
            res = -1;
        }
    } else {
        D("Unable to send registration query for channel '%s'@%d: %s",
          _ads_id_str(ads), _ads_port(ads), strerror(errno));
        res = -1;
    }

    return res;
}

static void
_android_dev_socket_disconnect(AndroidDevSocket* ads)
{
    /* Preserve errno */
    const int save_error = errno;
    if (ads->socket_status != ADS_DISCONNECTED) {
        /* Reset I/O looper for this socket. */
        iolooper_modify(_ads_io_looper(ads), ads->fd,
                        IOLOOPER_READ | IOLOOPER_WRITE, 0);

        /* Mark as disconnected. */
        ads->socket_status = ADS_DISCONNECTED;

        /* Close socket. */
        if (ads->fd >= 0) {
            socket_close(ads->fd);
            ads->fd = -1;
        }
    }
    errno = save_error;
}

static int
_android_dev_socket_send(AndroidDevSocket* ads, const char* buff, int to_send)
{
    int sent = 0;

    /* Make sure that socket is connected. */
    if (ads->socket_status < ADS_CONNECTED) {
        D("Attempt to send via disconnected channel '%s'@%d",
          _ads_id_str(ads),  _ads_port(ads));
        errno = ECONNRESET;
        return -1;
    }

    iolooper_add_write(_ads_io_looper(ads), ads->fd);
    do {
        int res = socket_send(ads->fd, buff + sent, to_send - sent);
        if (res == 0) {
            /* Disconnection. */
            errno = ECONNRESET;
            sent = -1;
            break;
        }

        if (res < 0) {
            if (errno == EINTR) {
                /* loop on EINTR */
                continue;
            }

            if (errno == EWOULDBLOCK || errno == EAGAIN) {
                res = iolooper_wait_absolute(_ads_io_looper(ads), ads->deadline);
                if (res > 0) {
                    /* Ready to write. */
                    continue;
                }
            }
            sent = -1;
            break;
        }
        sent += res;
    } while (sent < to_send);
    iolooper_del_write(_ads_io_looper(ads), ads->fd);

    /* In case of an I/O failure we have to invoke failure callback. Note that we
     * report I/O failures only on registered sockets. */
    if (sent < 0) {
        D("I/O error while sending data via channel '%s'@%d: %s",
          _ads_id_str(ads), _ads_port(ads), strerror(errno));

        if (ads->ad->on_io_failure != NULL && ads->socket_status > ADS_CONNECTED) {
            const char save_error = errno;
            ads->ad->on_io_failure(ads->opaque, ads->ad, save_error);
            errno = save_error;
        }
    }

    return sent;
}

static int
_android_dev_socket_recv(AndroidDevSocket* ads, char* buf, int bufsize)
{
    int recvd = 0;

    /* Make sure that socket is connected. */
    if (ads->socket_status < ADS_CONNECTED) {
        D("Attempt to receive from disconnected channel '%s'@%d",
          _ads_id_str(ads),  _ads_port(ads));
        errno = ECONNRESET;
        return -1;
    }

    iolooper_add_read(_ads_io_looper(ads), ads->fd);
    do {
        int res = socket_recv(ads->fd, buf + recvd, bufsize - recvd);
        if (res == 0) {
            /* Disconnection. */
            errno = ECONNRESET;
            recvd = -1;
            break;
        }

        if (res < 0) {
            if (errno == EINTR) {
                /* loop on EINTR */
                continue;
            }

            if (errno == EWOULDBLOCK || errno == EAGAIN) {
                res = iolooper_wait_absolute(_ads_io_looper(ads), ads->deadline);
                if (res > 0) {
                    /* Ready to read. */
                    continue;
                }
            }
            recvd = -1;
            break;
        }
        recvd += res;
    } while (recvd < bufsize);
    iolooper_del_read(_ads_io_looper(ads), ads->fd);

    /* In case of an I/O failure we have to invoke failure callback. Note that we
     * report I/O failures only on registered sockets. */
    if (recvd < 0) {
        D("I/O error while receiving from channel '%s'@%d: %s",
          _ads_id_str(ads), _ads_port(ads), strerror(errno));

         if (ads->ad->on_io_failure != NULL && ads->socket_status > ADS_CONNECTED) {
            const char save_error = errno;
            ads->ad->on_io_failure(ads->opaque, ads->ad, save_error);
            errno = save_error;
         }
    }

    return recvd;
}

static int
_android_dev_socket_read_string(AndroidDevSocket* ads, char* str, int strsize)
{
    int n;

    /* Char by char read from the socket, until zero-terminator is read. */
    for (n = 0; n < strsize; n++) {
        if (_android_dev_socket_recv(ads, str + n, 1) > 0) {
            if (str[n] == '\0') {
                /* Done. */
                return n + 1;   /* Including zero-terminator. */
            }
        } else {
            /* I/O error. */
            return -1;
        }
    }

    /* Buffer was too small. Report that by setting errno to ENOMEM. */
    D("Buffer %d is too small to receive a string from channel '%s'@%d",
       strsize, _ads_id_str(ads), _ads_port(ads));
    errno = ENOMEM;
    return -1;
}

static int
_android_dev_socket_read_response(AndroidDevSocket* ads, char* data, int datasize)
{
    int n, res;
    int success = 0;
    int failure = 0;
    int bad_format = 0;
    char ok[4];

    *data = '\0';

    /* Char by char read from the socket, until ok/ko is read. */
    for (n = 0; n < 2; n++) {
        res = _android_dev_socket_recv(ads, ok + n, 1);
        if (res > 0) {
            if (ok[n] == '\0') {
                /* EOS is unexpected here! */
                D("Bad query reply format on channel '%s'@%d: '%s' is too short.",
                  _ads_id_str(ads), _ads_port(ads), ok);
                errno = EINVAL;
                return -1;
            }
        } else {
            /* I/O error. */
            return -1;
        }
    }

    /* Next character must be either ':', or '\0' */
    res = _android_dev_socket_recv(ads, ok + n, 1);
    if (res <= 0) {
        /* I/O error. */
        return -1;
    }

    /*
     * Verify format.
     */

    /* Check ok / ko */
    success = memcmp(ok, "ok", 2) == 0;
    failure = memcmp(ok, "ko", 2) == 0;

    /* Check the prefix: 'ok'|'ko' & ':'|'\0' */
    if ((success || failure) && (ok[n] == '\0' || ok[n] == ':')) {
        /* Format is good. */
        if (ok[n] == '\0') {
            /* We're done: no extra data in response. */
            errno = 0;
            return success ? 0 : -1;
        }
        /* Reset buffer offset, so we will start to read the remaining query
         * data to the beginning of the supplied buffer. */
        n = 0;
    } else {
        /* Bad format. Lets move what we've read to the main buffer, and
         * continue filling it in. */
        bad_format = 1;
        n++;
        memcpy(data, ok, n);
    }

    /* Read the remainder of reply to the supplied data buffer. */
    res = _android_dev_socket_read_string(ads, data + n, datasize - n);
    if (res < 0) {
        return res;
    }

    /* Lets see if format was bad */
    if (bad_format) {
        D("Bad query reply format on channel '%s'@%d: %s.",
          _ads_id_str(ads), _ads_port(ads), data);
        errno = EINVAL;
        return -1;
    } else {
        errno = 0;
        return success ? n : -1;
    }
}

/********************************************************************************
 *                        Query socket declarations
 *******************************************************************************/

/* Initializes query socket descriptor.
 * Param:
 *  adsquery - Socket descriptor to initialize.
 *  opaque - An opaque pointer to associate with the socket. Typicaly it's the
 *      same pointer that is associated with AndroidDevice instance.
 *  ad - Android device descriptor that owns the socket.
 *  port - TCP socket port.
 */
static int _android_query_socket_init(AndroidQuerySocket* adsquery,
                                      void* opaque,
                                      AndroidDevice* ad,
                                      int port);

/* Destroys query socket descriptor. */
static void _android_query_socket_destroy(AndroidQuerySocket* adsquery);

/* Synchronously connects the query socket, and registers it with the server.
 * Param:
 *  adsquery - Descriptor for the query socket to connect. Must have 'deadline'
 *      field properly setup.
 *  cb - Callback to invoke when socket connection is completed. Can be NULL.
 * Return:
 *  Zero on success, or non-zero on failure.
 */
static int _android_query_socket_connect(AndroidQuerySocket* adsquery);

/* Disconnects the query socket. */
static void _android_query_socket_disconnect(AndroidQuerySocket* adsquery);

/********************************************************************************
 *                        Query socket implementation
 *******************************************************************************/

static int
_android_query_socket_init(AndroidQuerySocket* adsquery,
                           void* opaque,
                           AndroidDevice* ad,
                           int port)
{
    return _android_dev_socket_init(&adsquery->dev_socket, opaque, ad, port,
                                    ADS_TYPE_QUERY);
}

static void
_android_query_socket_destroy(AndroidQuerySocket* adsquery)
{
    _android_query_socket_disconnect(adsquery);
    _android_dev_socket_destroy(&adsquery->dev_socket);
}

static int
_android_query_socket_connect(AndroidQuerySocket* adsquery)
{
    return _android_dev_socket_connect(&adsquery->dev_socket);
}

static void
_android_query_socket_disconnect(AndroidQuerySocket* adsquery)
{
    _android_dev_socket_disconnect(&adsquery->dev_socket);
}

/********************************************************************************
 *                       Events socket declarations
 *******************************************************************************/

/* Initializes event socket descriptor.
 * Param:
 *  adsevent - Socket descriptor to initialize.
 *  opaque - An opaque pointer to associate with the socket.  Typicaly it's the
 *      same pointer that is associated with AndroidDevice instance.
 *  ad - Android device descriptor that owns the socket.
 *  port - TCP socket port.
 */
static int _android_event_socket_init(AndroidEventSocket* adsevent,
                                      void* opaque,
                                      AndroidDevice* ad,
                                      int port);

/* Destroys the event socket descriptor. */
static void _android_event_socket_destroy(AndroidEventSocket* adsevent);

/* Synchronously connects event socket.
 * Param:
 *  adsevent - Descriptor for the event socket to connect. Must have 'deadline'
 *      field properly setup.
 * Return:
 *  Zero on success, or non-zero on failure.
 */
static int _android_event_socket_connect_sync(AndroidEventSocket* adsevent);

/* Initiates asynchronous event socket connection.
 * Param:
 *  adsevent - Descriptor for the event socket to connect.  Must have 'deadline'
 *      field properly setup.
 *  cb - Callback to invoke when socket connection is completed. Can be NULL.
 * Return:
 *  Zero on success, or non-zero on failure.
 */
static int _android_event_socket_connect_async(AndroidEventSocket* adsevent,
                                               ads_socket_connected_cb cb);

/* Disconnects the event socket. */
static void _android_event_socket_disconnect(AndroidEventSocket* adsevent);

/* Initiates listening on the event socket.
 * Param:
 *  adsevent - Descriptor for the event socket to listen on.
 *  str, strsize - Buffer where to read the string.
 *  cb - A callback to call when the event string is read. Can be NULL.
 * Return:
 *  Zero on success, or non-zero on failure.
 */
static int _android_event_socket_listen(AndroidEventSocket* adsevent,
                                        char* str,
                                        int strsize,
                                        event_cb cb);

/* Event socket's asynchronous I/O looper callback.
 * Param:
 *  opaque - AndroidEventSocket instance.
 *  fd - Socket's FD.
 *  events - I/O type bitsmask (read | write).
 */
static void _on_event_socket_io(void* opaque, int fd, unsigned events);

/* Callback that is invoked when asynchronous event socket connection is
 * completed. */
static void _on_event_socket_connected(AndroidEventSocket* adsevent, int failure);

/* Callback that is invoked when an event is received from the device. */
static void _on_event_received(AndroidEventSocket* adsevent);

/* Gets I/O looper for asynchronous I/O on event socket. */
AINLINED Looper*
_aes_looper(AndroidEventSocket* adsevent)
{
    return adsevent->dev_socket.ad->looper;
}

/********************************************************************************
 *                       Events socket implementation
 *******************************************************************************/

static int
_android_event_socket_init(AndroidEventSocket* adsevent,
                           void* opaque,
                           AndroidDevice* ad,
                           int port)
{
    return _android_dev_socket_init(&adsevent->dev_socket, opaque, ad, port,
                                    ADS_TYPE_EVENT);
}

static void
_android_event_socket_destroy(AndroidEventSocket* adsevent)
{
    _android_event_socket_disconnect(adsevent);
    _android_dev_socket_destroy(&adsevent->dev_socket);
}


static int
_android_event_socket_connect_sync(AndroidEventSocket* adsevent)
{
    AndroidDevSocket* ads = &adsevent->dev_socket;
    const int res = _android_dev_socket_connect(&adsevent->dev_socket);
    if (res == 0) {
        /* Prepare for async I/O on the event socket. */
        loopIo_init(adsevent->io, _aes_looper(adsevent), ads->fd,
                    _on_event_socket_io, adsevent);
    }
    return res;
}

static int
_android_event_socket_connect_async(AndroidEventSocket* adsevent,
                                    ads_socket_connected_cb cb)
{
    AsyncStatus status;
    AndroidDevSocket* ads = &adsevent->dev_socket;

    /* Create asynchronous socket. */
    ads->fd = socket_create_inet(SOCKET_STREAM);
    if (ads->fd < 0) {
        D("Unable to create socket for channel '%s'@%d: %s",
          _ads_id_str(ads), _ads_port(ads), strerror(errno));
        if (cb != NULL) {
            cb(ads->opaque, ads, errno);
        }
        return -1;
    }
    socket_set_nonblock(ads->fd);

    /* Prepare for async I/O on the event socket. */
    loopIo_init(adsevent->io, _aes_looper(adsevent), ads->fd,
                _on_event_socket_io, adsevent);

    /* Try to connect. */
    ads->socket_status = ADS_CONNECTING;
    adsevent->on_connected = cb;
    status = asyncConnector_init(adsevent->connector, &ads->address, adsevent->io);
    switch (status) {
        case ASYNC_COMPLETE:
            /* We're connected to the device socket. */
            ads->socket_status = ADS_CONNECTED;
            _on_event_socket_connected(adsevent, 0);
            break;
        case ASYNC_ERROR:
            _on_event_socket_connected(adsevent, errno);
            break;
        case ASYNC_NEED_MORE:
            /* Attempt to connect would block, so connection competion is
             * delegates to the looper's I/O routine. */
        default:
            break;
    }

    return 0;
}

static void
_android_event_socket_disconnect(AndroidEventSocket* adsevent)
{
    AndroidDevSocket* ads = &adsevent->dev_socket;

    if (ads->socket_status != ADS_DISCONNECTED) {
        /* Stop all async I/O. */
        loopIo_done(adsevent->io);

        /* Disconnect common socket. */
        _android_dev_socket_disconnect(ads);
    }
}

static int
_android_event_socket_listen(AndroidEventSocket* adsevent,
                             char* str,
                             int strsize,
                             event_cb cb)
{
    AsyncStatus  status;
    AndroidDevSocket* ads = &adsevent->dev_socket;

    /* Make sure that device is connected. */
    if (ads->socket_status < ADS_CONNECTED) {
        D("Attempt to listen on a disconnected channel '%s'@%d",
          _ads_id_str(ads),  _ads_port(ads));
        errno = ECONNRESET;
        return -1;
    }

    /* NOTE: only one reader at any given time! */
    adsevent->on_event = cb;
    asyncLineReader_init(&adsevent->alr, str, strsize, adsevent->io);
    /* Default EOL for the line reader was '\n'. */
    asyncLineReader_setEOL(&adsevent->alr, '\0');
    status = asyncLineReader_read(&adsevent->alr);
    if (status == ASYNC_COMPLETE) {
        /* Data has been transferred immediately. Do the callback here. */
        _on_event_received(adsevent);
    } else if (status == ASYNC_ERROR) {
        D("Error while listening on channel '%s'@%d: %s",
          _ads_id_str(ads),  _ads_port(ads), strerror(errno));
        /* There is one special failure here, when buffer was too small to
         * contain the entire string. This is not an I/O, but rather a
         * protocol error. So we don't report it to the I/O failure
         * callback. */
        if (errno == ENOMEM) {
            _on_event_received(adsevent);
        } else {
            if (ads->ad->on_io_failure != NULL) {
                ads->ad->on_io_failure(ads->ad->opaque, ads->ad, errno);
            }
        }
        return -1;
    }
    return 0;
}

static void
_on_event_socket_io(void* opaque, int fd, unsigned events)
{
    AsyncStatus status;
    AndroidEventSocket* adsevent = (AndroidEventSocket*)opaque;
    AndroidDevSocket* ads = &adsevent->dev_socket;

    /* Lets see if we're still wating on a connection to occur. */
    if (ads->socket_status == ADS_CONNECTING) {
        /* Complete socket connection. */
        status = asyncConnector_run(adsevent->connector);
        if (status == ASYNC_COMPLETE) {
            /* We're connected to the device socket. */
            ads->socket_status = ADS_CONNECTED;
            D("Channel '%s'@%d is connected asynchronously",
              _ads_id_str(ads), _ads_port(ads));
            _on_event_socket_connected(adsevent, 0);
        } else if (status == ASYNC_ERROR) {
            _on_event_socket_connected(adsevent, adsevent->connector->error);
        }
        return;
    }

    /*
     * Device is connected. Continue with the data transfer. We don't expect
     * any writes here, since we always write to the event socket synchronously.
     */

    if ((events & LOOP_IO_READ) != 0) {
        /* Continue reading data. */
        status = asyncLineReader_read(&adsevent->alr);
        if (status == ASYNC_COMPLETE) {
            _on_event_received(adsevent);
        } else if (status == ASYNC_ERROR) {
            D("I/O failure while reading from channel '%s'@%d: %s",
              _ads_id_str(ads),  _ads_port(ads), strerror(errno));
            /* There is one special failure here, when buffer was too small to
             * contain the entire string. This is not an I/O, but rather a
             * protocol error. So we don't report it to the I/O failure
             * callback. */
            if (errno == ENOMEM) {
                _on_event_received(adsevent);
            } else {
                if (ads->ad->on_io_failure != NULL) {
                    ads->ad->on_io_failure(ads->ad->opaque, ads->ad, errno);
                }
            }
        }
    }
}

static void
_on_event_socket_connected(AndroidEventSocket* adsevent, int failure)
{
    int res;
    AndroidDevSocket* ads = &adsevent->dev_socket;

    if (failure) {
        _android_event_socket_disconnect(adsevent);
        if (adsevent->on_connected != NULL) {
            adsevent->on_connected(ads->opaque, ads, failure);
        }
        return;
    }

    /* Complete event socket connection by identifying it as "event" socket with
     * the application. */
    res = _android_dev_socket_register(ads);
    if (res) {
        const int save_error = errno;
        _android_event_socket_disconnect(adsevent);
        errno = save_error;
    }

    /* Notify callback about connection completion. */
    if (adsevent->on_connected != NULL) {
        if (res) {
            adsevent->on_connected(ads->opaque, ads, errno);
        } else {
            adsevent->on_connected(ads->opaque, ads, 0);
        }
    }
}

static void
_on_event_received(AndroidEventSocket* adsevent)
{
    if (adsevent->on_event != NULL) {
        AndroidDevice* ad = adsevent->dev_socket.ad;
        adsevent->on_event(ad->opaque, ad, (char*)adsevent->alr.buffer,
                           adsevent->alr.pos);
    }
}

/********************************************************************************
 *                          Android device connection
 *******************************************************************************/

/* Callback that is invoked when event socket is connected and registered as part
 * of the _android_device_connect_async API.
 * Param:
 *  opaque - Opaque pointer associated with AndroidDevice instance.
 *  ads - Common socket descriptor for the event socket.
 *  failure - If zero connection has succeeded, otherwise contains 'errno'-reason
 *      for connection failure.
 */
static void
_on_android_device_connected_async(void* opaque,
                                   AndroidDevSocket* ads,
                                   int failure)
{
    int res;
    AndroidDevice* ad = ads->ad;

    if (failure) {
        /* Depending on the failure code we will either retry, or bail out. */
        switch (failure) {
            case EPIPE:
            case EAGAIN:
            case EINPROGRESS:
            case EALREADY:
            case EHOSTUNREACH:
            case EHOSTDOWN:
            case ECONNREFUSED:
            case ESHUTDOWN:
            case ENOTCONN:
            case ECONNRESET:
            case ECONNABORTED:
            case ENETRESET:
            case ENETUNREACH:
            case ENETDOWN:
            case EBUSY:
#if !defined(_DARWIN_C_SOURCE) && !defined(_WIN32)
            case ERESTART:
            case ECOMM:
            case ENONET:
#endif  /* !_DARWIN_C_SOURCE && !_WIN32 */
                /* Device is not available / reachable at the moment.
                 * Retry connection later. */
                loopTimer_startRelative(ad->timer, ADS_RETRY_CONNECTION_TIMEOUT);
                return;
            default:
                D("Failed to asynchronously connect channel '%s':%d %s",
                  _ads_id_str(ads), _ads_port(ads), strerror(errno));
            if (ad->on_connected != NULL) {
                ad->on_connected(ad->opaque, ad, failure);
            }
            break;
        }
        return;
    }

    /* Event socket is connected. Connect the query socket now. Give it 5
     * seconds to connect. */
    _ads_set_deadline(&ad->query_socket.dev_socket, 5000);
    res = _android_query_socket_connect(&ad->query_socket);
    if (res == 0) {
        /* Query socket is connected. */
        if (ad->on_connected != NULL) {
            ad->on_connected(ad->opaque, ad, 0);
        }
    } else {
        /* If connection completion has failed - disconnect the sockets. */
        _android_event_socket_disconnect(&ad->event_socket);
        _android_query_socket_disconnect(&ad->query_socket);

        if (ad->on_connected != NULL) {
            ad->on_connected(ad->opaque, ad, errno);
        }
    }
}

static void
_on_timer(void* opaque)
{
    /* Retry the connection. */
    AndroidDevice* ad = (AndroidDevice*)opaque;
    android_device_connect_async(ad, ad->on_connected);
}

/* Destroys and frees the descriptor. */
static void
_android_device_free(AndroidDevice* ad)
{
    if (ad != NULL) {
        _android_event_socket_destroy(&ad->event_socket);
        _android_query_socket_destroy(&ad->query_socket);

        /* Delete asynchronous I/O looper. */
        if (ad->looper != NULL ) {
            loopTimer_done(ad->timer);
            looper_free(ad->looper);
        }

        /* Delete synchronous I/O looper. */
        if (ad->io_looper != NULL) {
            iolooper_reset(ad->io_looper);
            iolooper_free(ad->io_looper);
        }

        AFREE(ad);
    }
}

/********************************************************************************
 *                          Android device API
 *******************************************************************************/

AndroidDevice*
android_device_init(void* opaque, int port, io_failure_cb on_io_failure)
{
    int res;
    AndroidDevice* ad;

    ANEW0(ad);

    ad->opaque = opaque;
    ad->on_io_failure = on_io_failure;

    /* Create I/O looper for synchronous I/O on the device. */
    ad->io_looper = iolooper_new();
    if (ad->io_looper == NULL) {
        E("Unable to create synchronous I/O looper for android device.");
        _android_device_free(ad);
        return NULL;
    }

    /* Create a looper for asynchronous I/O on the device. */
    ad->looper = looper_newCore();
    if (ad->looper != NULL) {
        /* Create a timer that will be used for connection retries. */
        loopTimer_init(ad->timer, ad->looper, _on_timer, ad);
    } else {
        E("Unable to create asynchronous I/O looper for android device.");
        _android_device_free(ad);
        return NULL;
    }

    /* Init query socket. */
    res = _android_query_socket_init(&ad->query_socket, opaque, ad, port);
    if (res) {
        _android_device_free(ad);
        return NULL;
    }

    /* Init event socket. */
    res = _android_event_socket_init(&ad->event_socket, opaque, ad, port);
    if (res) {
        _android_device_free(ad);
        return NULL;
    }

    return ad;
}

void
android_device_destroy(AndroidDevice* ad)
{
    if (ad != NULL) {
        _android_device_free(ad);
    }
}

int
android_device_connect_sync(AndroidDevice* ad, int to)
{
    int res;

    /* Setup deadline for the connections. */
    _ads_set_deadline(&ad->query_socket.dev_socket, to);
    ad->event_socket.dev_socket.deadline = ad->query_socket.dev_socket.deadline;

    /* Connect the query socket first. */
    res = _android_query_socket_connect(&ad->query_socket);
    if (!res) {
        /* Connect to the event socket next. */
        res = _android_event_socket_connect_sync(&ad->event_socket);
    }

    return res;
}

int
android_device_connect_async(AndroidDevice* ad, device_connected_cb on_connected)
{
    /* No deadline for async connections. */
    ad->query_socket.dev_socket.deadline = DURATION_INFINITE;
    ad->event_socket.dev_socket.deadline = DURATION_INFINITE;

    /* Connect to the event socket first, and delegate query socket connection
     * into callback invoked when event socket is connected. NOTE: In case of
     * failure 'on_connected' callback has already been called from
     * _on_android_device_connected_async routine. */
    ad->on_connected = on_connected;
    return _android_event_socket_connect_async(&ad->event_socket,
                                               _on_android_device_connected_async);
}

void
android_device_disconnect(AndroidDevice* ad)
{
    _android_event_socket_disconnect(&ad->event_socket);
    _android_query_socket_disconnect(&ad->query_socket);
}

int
android_device_query(AndroidDevice* ad,
                     const char* query,
                     char* buff,
                     size_t buffsize,
                     int to)
{
    int res;

    /* Setup deadline for the query. */
    _ads_set_deadline(&ad->query_socket.dev_socket, to);

    /* Send the query. */
    res = _android_dev_socket_send(&ad->query_socket.dev_socket, query,
                                   strlen(query) + 1);
    if (res > 0) {
        /* Receive the response. */
        res = _android_dev_socket_read_response(&ad->query_socket.dev_socket,
                                                buff, buffsize);
        return (res >= 0) ? 0 : -1;
    }

    return -1;
}

int
android_device_start_query(AndroidDevice* ad, const char* query, int to)
{
    int res;

    /* Setup deadline for the query. */
    _ads_set_deadline(&ad->query_socket.dev_socket, to);

    /* Send the query header. */
    res = _android_dev_socket_send(&ad->query_socket.dev_socket, query,
                                   strlen(query) + 1);
    return (res > 0) ? 0 : -1;
}

int
android_device_send_query_data(AndroidDevice* ad, const void* data, int size)
{
    return _android_dev_socket_send(&ad->query_socket.dev_socket, data, size);
}

int
android_device_complete_query(AndroidDevice* ad, char* buff, size_t buffsize)
{
    /* Receive the response to the query. */
    const int res = _android_dev_socket_read_response(&ad->query_socket.dev_socket,
                                                      buff, buffsize);
    return (res >= 0) ? 0 : -1;
}

int
android_device_listen(AndroidDevice* ad,
                      char* buff,
                      int buffsize,
                      event_cb on_event)
{
    return _android_event_socket_listen(&ad->event_socket, buff, buffsize,
                                        on_event);
}
