/*
 * 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.
 */

#include "qemu-common.h"
#include "android/globals.h"  /* for android_hw */
#include "android/hw-qemud.h"
#include "android/utils/misc.h"
#include "android/utils/system.h"
#include "android/utils/debug.h"
#include "android/adb-server.h"
#include "android/adb-qemud.h"

#define  E(...)    derror(__VA_ARGS__)
#define  W(...)    dwarning(__VA_ARGS__)
#define  D(...)    VERBOSE_PRINT(adbclient,__VA_ARGS__)
#define  DD(...)   VERBOSE_PRINT(adb,__VA_ARGS__)
#define  D_ACTIVE  VERBOSE_CHECK(adbclient)
#define  DD_ACTIVE VERBOSE_CHECK(adb)
#define  QB(b, s)  quote_bytes((const char*)b, (s < 32) ? s : 32)

#define SERVICE_NAME        "adb"
#define DEBUG_SERVICE_NAME  "adb-debug"
/* Maximum length of the message that can be received from the guest. */
#define ADB_MAX_MSG_LEN     8
/* Enumerates ADB client state values. */
typedef enum AdbClientState {
    /* Waiting on a connection from ADB host. */
    ADBC_STATE_WAIT_ON_HOST,
    /* ADB host is connected. Waiting on the transport initialization completion
     * in the guest. */
    ADBC_STATE_HOST_CONNECTED,
    /* Connection between ADB host and ADB guest is fully established. */
    ADBC_STATE_CONNECTED,
    /* ADB host has been disconnected. */
    ADBC_STATE_HOST_DISCONNECTED,
    /* ADB guest has been disconnected. */
    ADBC_STATE_GUEST_DISCONNECTED,
} AdbClientState;

/* ADB client descriptor. */
typedef struct AdbClient AdbClient;
struct AdbClient {
    /* Opaque pointer returned from adb_server_register_guest API. */
    void*           opaque;
    /* QEMUD client pipe for this client. */
    QemudClient*    qemud_client;
    /* Connection state. */
    AdbClientState  state;
    /* Buffer, collecting accept / stop messages from client. */
    char            msg_buffer[ADB_MAX_MSG_LEN];
    /* Current position in message buffer. */
    int             msg_cur;
};

/* ADB debugging client descriptor. */
typedef struct AdbDbgClient AdbDbgClient;
struct AdbDbgClient {
    /* QEMUD client pipe for this client. */
    QemudClient*    qemud_client;
};

/********************************************************************************
 *                      ADB host communication.
 *******************************************************************************/

/* A callback that is invoked when the host is connected.
 * Param:
 *  opaque - AdbClient instance.
 *  connection - An opaque pointer that identifies connection with the ADB host.
 */
static void
_adb_on_host_connected(void* opaque, void* connection)
{
    AdbClient* const adb_client = (AdbClient*)opaque;

    if (adb_client->state == ADBC_STATE_WAIT_ON_HOST) {
        D("ADB client %p(o=%p) is connected to the host %p",
          adb_client, adb_client->opaque, connection);

        /* Bump the state up. */
         adb_client->state = ADBC_STATE_HOST_CONNECTED;

        /* Notify the ADB guest that host has been  connected.This will unblock
         * the guest from a 'read', then guest will register the transport, and
         * will send 'setart' request, indicating that it is ready to receive
         * data from the host. */
        qemud_client_send(adb_client->qemud_client, (const uint8_t*)"ok", 2);
    } else {
        D("Unexpected ADB host connection while state is %d", adb_client->state);
    }
}

/* A callback that is invoked when the host gets disconnected.
 * Param:
 *  opaque - AdbClient instance.
 *  connection - An opaque pointer that identifies connection with the ADB host.
 */
static void
_adb_on_host_disconnect(void* opaque, void* connection)
{
    AdbClient* const adb_client = (AdbClient*)opaque;

    D("ADB client %p(o=%p) is disconnected from the host %p",
      adb_client, adb_client->opaque, connection);
    adb_client->state = ADBC_STATE_HOST_DISCONNECTED;
}

/* A callback that is invoked when the host sends data.
 * Param:
 *  opaque - AdbClient instance.
 *  connection - An opaque pointer that identifies connection with the ADB host.
 *  buff, size - Buffer containing the host data.
 */
static void
_adb_on_host_data(void* opaque, void* connection, const void* buff, int size)
{
    AdbClient* const adb_client = (AdbClient*)opaque;
    D("ADB client %p(o=%p) received from the host %p %d bytes in %s",
      adb_client, adb_client->opaque, connection, size, QB(buff, size));

    if (adb_client->state == ADBC_STATE_CONNECTED) {
        /* Dispatch data down to the guest. */
        qemud_client_send(adb_client->qemud_client, (const uint8_t*)buff, size);
    } else {
        D("Unexpected data from ADB host %p while client %p(o=%p) is in state %d",
          connection, adb_client, adb_client->opaque, adb_client->state);
    }
}

/* ADB guest API required for adb_server_register_guest */
static AdbGuestRoutines _adb_client_routines = {
    /* A callback that is invoked when the host is connected. */
    _adb_on_host_connected,
    /* A callback that is invoked when the host gets disconnected. */
    _adb_on_host_disconnect,
    /* A callback that is invoked when the host sends data. */
    _adb_on_host_data,
};

/********************************************************************************
 *                      ADB guest communication.
 *******************************************************************************/

/* Allocates AdbClient instance. */
static AdbClient*
_adb_client_new(void)
{
    AdbClient* adb_client;

    ANEW0(adb_client);

    return adb_client;
}

/* Frees AdbClient instance, allocated with _adb_client_new */
static void
_adb_client_free(AdbClient* adb_client)
{
    if (adb_client != NULL) {
        free(adb_client);
    }
}

/* A callback that is invoked when ADB guest sends data to the service.
 * Param:
 *  opaque - AdbClient instance.
 *  msg, msglen - Message received from the ADB guest.
 *  client - adb QEMUD client.
 */
static void
_adb_client_recv(void* opaque, uint8_t* msg, int msglen, QemudClient* client)
{
    AdbClient* const adb_client = (AdbClient*)opaque;

    D("ADB client %p(o=%p) received from guest %d bytes in %s",
      adb_client, adb_client->opaque, msglen, QB(msg, msglen));

    if (adb_client->state == ADBC_STATE_CONNECTED) {
        /* Connection is fully established. Dispatch the message to the host. */
        adb_server_on_guest_message(adb_client->opaque, msg, msglen);
        return;
    }

    /*
     * At this point we expect either "accept", or "start" messages. Depending
     * on the state of the pipe (although small) these messages could be broken
     * into pieces. So, simply checking msg for "accept", or "start" may not
     * work. Lets collect them first in internal buffer, and then will see.
     */

    /* Make sure tha message doesn't overflow the buffer. */
    if ((msglen + adb_client->msg_cur) > sizeof(adb_client->msg_buffer)) {
        D("Unexpected message in ADB client.");
        adb_client->msg_cur = 0;
        return;
    }
    /* Append to current message. */
    memcpy(adb_client->msg_buffer + adb_client->msg_cur, msg, msglen);
    adb_client->msg_cur += msglen;

    /* Properly dispatch the message, depending on the client state. */
    switch (adb_client->state) {
        case ADBC_STATE_WAIT_ON_HOST:
            /* At this state the only message that is allowed is 'accept' */
            if (adb_client->msg_cur == 6 &&
                !memcmp(adb_client->msg_buffer, "accept", 6)) {
                adb_client->msg_cur = 0;
                /* Register ADB guest connection with the ADB server. */
                adb_client->opaque =
                    adb_server_register_guest(adb_client, &_adb_client_routines);
                if (adb_client->opaque == NULL) {
                    D("Unable to register ADB guest with the ADB server.");
                    /* KO the guest. */
                    qemud_client_send(adb_client->qemud_client,
                                      (const uint8_t*)"ko", 2);
                }
            } else {
                D("Unexpected guest request while waiting on ADB host to connect.");
            }
            break;

        case ADBC_STATE_HOST_CONNECTED:
            /* At this state the only message that is allowed is 'start' */
            if (adb_client->msg_cur &&
                !memcmp(adb_client->msg_buffer, "start", 5)) {
                adb_client->msg_cur = 0;
                adb_client->state = ADBC_STATE_CONNECTED;
                adb_server_complete_connection(adb_client->opaque);
            } else {
                D("Unexpected request while waiting on connection to start.");
            }
            break;

        default:
            D("Unexpected ADB guest request '%s' while client state is %d.",
              QB(msg, msglen), adb_client->state);
            break;
    }
}

/* A callback that is invoked when ADB guest disconnects from the service. */
static void
_adb_client_close(void* opaque)
{
    AdbClient* const adb_client = (AdbClient*)opaque;

    D("ADB client %p(o=%p) is disconnected from the guest.",
      adb_client, adb_client->opaque);
    adb_client->state = ADBC_STATE_GUEST_DISCONNECTED;
    if (adb_client->opaque != NULL) {
        /* Close connection with the host. */
        adb_server_on_guest_closed(adb_client->opaque);
    }
    _adb_client_free(adb_client);
}

/* A callback that is invoked when ADB daemon running inside the guest connects
 * to the service.
 * Client parameters are ignored here. Typically they contain the ADB port number
 * which is always 5555 for the device / emulated system.
 */
static QemudClient*
_adb_service_connect(void*          opaque,
                     QemudService*  serv,
                     int            channel,
                     const char*    client_param)
{
    /* Create new QEMUD client for the connection with ADB daemon. */
    AdbClient* const adb_client = _adb_client_new();

    D("Connecting ADB guest: '%s'", client_param ? client_param : "<null>");
    adb_client->qemud_client =
        qemud_client_new(serv, channel, client_param, adb_client,
                         _adb_client_recv, _adb_client_close, NULL, NULL);
    if (adb_client->qemud_client == NULL) {
        D("Unable to create QEMUD client for ADB guest.");
        _adb_client_free(adb_client);
        return NULL;
    }

    return adb_client->qemud_client;
}

/********************************************************************************
 *                      Debugging ADB guest communication.
 *******************************************************************************/

/* Allocates AdbDbgClient instance. */
static AdbDbgClient*
_adb_dbg_client_new(void)
{
    AdbDbgClient* adb_dbg_client;

    ANEW0(adb_dbg_client);

    return adb_dbg_client;
}

/* Frees AdbDbgClient instance, allocated with _adb_dbg_client_new */
static void
_adb_dbg_client_free(AdbDbgClient* adb_dbg_client)
{
    if (adb_dbg_client != NULL) {
        free(adb_dbg_client);
    }
}

/* A callback that is invoked when ADB debugging guest sends data to the service.
 * Param:
 *  opaque - AdbDbgClient instance.
 *  msg, msglen - Message received from the ADB guest.
 *  client - adb-debug QEMUD client.
 */
static void
_adb_dbg_client_recv(void* opaque, uint8_t* msg, int msglen, QemudClient* client)
{
    if (DD_ACTIVE) {
        fprintf(stderr, "ADB: %s", (const char*)msg);
    }
}

/* A callback that is invoked when ADB debugging guest disconnects from the
 * service. */
static void
_adb_dbg_client_close(void* opaque)
{
    AdbDbgClient* const adb_dbg_client = (AdbDbgClient*)opaque;

    DD("ADB debugging client %p is disconnected from the guest.", adb_dbg_client);
    _adb_dbg_client_free(adb_dbg_client);
}

/* A callback that is invoked when ADB daemon running inside the guest connects
 * to the debugging service.
 * Client parameters are ignored here.
 */
static QemudClient*
_adb_debug_service_connect(void*          opaque,
                           QemudService*  serv,
                           int            channel,
                           const char*    client_param)
{
    /* Create new QEMUD client for the connection with ADB debugger. */
    AdbDbgClient* const adb_dbg_client = _adb_dbg_client_new();

    DD("Connecting ADB debugging guest: '%s'",
       client_param ? client_param : "<null>");
    adb_dbg_client->qemud_client =
        qemud_client_new(serv, channel, client_param, adb_dbg_client,
                         _adb_dbg_client_recv, _adb_dbg_client_close, NULL, NULL);
    if (adb_dbg_client->qemud_client == NULL) {
        DD("Unable to create QEMUD client for ADB debugging guest.");
        _adb_dbg_client_free(adb_dbg_client);
        return NULL;
    }

    return adb_dbg_client->qemud_client;
}

/********************************************************************************
 *                      ADB service API.
 *******************************************************************************/

void
android_adb_service_init(void)
{
static int _inited = 0;

    if (!adb_server_is_initialized()) {
        return;
    }

    if (!_inited) {
        /* Register main ADB service. */
        QemudService*  serv = qemud_service_register(SERVICE_NAME, 0, NULL,
                                                     _adb_service_connect,
                                                     NULL, NULL);
        if (serv == NULL) {
            derror("%s: Could not register '%s' service",
                   __FUNCTION__, SERVICE_NAME);
            return;
        }
        D("%s: Registered '%s' qemud service", __FUNCTION__, SERVICE_NAME);

        /* Register debugging ADB service. */
        serv = qemud_service_register(DEBUG_SERVICE_NAME, 0, NULL,
                                      _adb_debug_service_connect, NULL, NULL);
        if (serv != NULL) {
            DD("Registered '%s' qemud service", DEBUG_SERVICE_NAME);
        } else {
            dwarning("%s: Could not register '%s' service",
                   __FUNCTION__, DEBUG_SERVICE_NAME);
        }
    }
}
