/* Copyright (C) 2010 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/

/*
 * Contains the Core-side implementation of the "ui-core-control" service that is
 * part of the UI control protocol. Here we handle UI control commands sent by
 * the UI to the Core.
 */

#include "android/android.h"
#include "android/globals.h"
#include "telephony/modem_driver.h"
#include "android/trace.h"
#include "android/looper.h"
#include "android/async-utils.h"
#include "android/sync-utils.h"
#include "android/utils/debug.h"
#include "android/protocol/core-commands.h"
#include "android/protocol/core-commands-impl.h"

/* Enumerates state values for the command reader in the CoreCmdImpl descriptor.
 */
typedef enum CoreCmdImplState {
    /* The reader is waiting on command header. */
    EXPECTS_HEADER,

    /* The reader is waiting on command parameters. */
    EXPECTS_PARAMETERS,
} CoreCmdImplState;

/* Descriptor for the Core-side implementation of the "ui-core-control" service.
 */
typedef struct CoreCmdImpl {
    /* Reader to detect UI disconnection. */
    AsyncReader         async_reader;

    /* I/O associated with this descriptor. */
    LoopIo              io;

    /* Looper used to communicate with the UI. */
    Looper*             looper;

    /* Writer to send responses to the UI commands. */
    SyncSocket*         sync_writer;

    /* Socket descriptor for this service. */
    int                 sock;

    /* Command reader state. */
    CoreCmdImplState    cmd_state;

    /* Incoming command header. */
    UICmdHeader         cmd_header;

    /* A small preallocated buffer for command parameters. */
    uint8_t             cmd_param[256];

    /* Buffer to use for reading command parameters. Depending on expected size
     * of the parameters this buffer can point to cmd_param field of this
     * structure (for small commands), or can be allocated for large commands. */
    void*               cmd_param_buf;
} CoreCmdImpl;

/* One and only one CoreCmdImpl instance. */
static CoreCmdImpl    _coreCmdImpl;

/* Implemented in android/console.c */
extern void destroy_corecmd_client(void);
/* Implemented in vl-android.c */
extern char* qemu_find_file(int type, const char* filename);

/* Properly initializes cmd_param_buf field in CoreCmdImpl instance to receive
 * the expected command parameters.
 */
static uint8_t*
_alloc_cmd_param_buf(CoreCmdImpl* corecmd, uint32_t size)
{
    if (size < sizeof(corecmd->cmd_param)) {
        // cmd_param can contain all request data.
        corecmd->cmd_param_buf = &corecmd->cmd_param[0];
    } else {
        // Expected request us too large to fit into preallocated buffer.
        corecmd->cmd_param_buf = g_malloc(size);
    }
    return corecmd->cmd_param_buf;
}

/* Properly frees cmd_param_buf field in CoreCmdImpl instance.
 */
static void
_free_cmd_param_buf(CoreCmdImpl* corecmd)
{
    if (corecmd->cmd_param_buf != &corecmd->cmd_param[0]) {
        g_free(corecmd->cmd_param_buf);
        corecmd->cmd_param_buf = &corecmd->cmd_param[0];
    }
}

/* Calculates timeout for transferring the given number of bytes via socket.
 * Return:
 *  Number of milliseconds during which the entire number of bytes is expected
 *  to be transferred via socket for this service.
 */
static int
_coreCmdImpl_get_timeout(size_t data_size)
{
    // Min 2 seconds + 10 millisec for each transferring byte.
    // TODO: Come up with a better arithmetics here.
    return 2000 + data_size * 10;
}

/* Sends command response back to the UI.
 * Param:
 *  corecmd - CoreCmdImpl instance to use to send the response.
 *  resp - Response header.
 *  resp_data - Response data. Data size is defined by the header.
 * Return:
 *  0 on success, or < 0 on failure.
 */
static int
_coreCmdImpl_respond(CoreCmdImpl* corecmd, UICmdRespHeader* resp, void* resp_data)
{
    int status = syncsocket_start_write(corecmd->sync_writer);
    if (!status) {
        // Write the header
        status = syncsocket_write(corecmd->sync_writer, resp,
                                  sizeof(UICmdRespHeader),
                                  _coreCmdImpl_get_timeout(sizeof(UICmdRespHeader)));
        // Write response data (if any).
        if (status > 0 && resp_data != NULL && resp->resp_data_size != 0) {
            status = syncsocket_write(corecmd->sync_writer, resp_data,
                                      resp->resp_data_size,
                                      _coreCmdImpl_get_timeout(resp->resp_data_size));
        }
        status = syncsocket_result(status);
        syncsocket_stop_write(corecmd->sync_writer);
    }
    if (status < 0) {
        derror("Core is unable to respond with %u bytes to the UI control command: %s\n",
               resp->resp_data_size, errno_str);
    }
    return status;
}

/* Handles UI control command received from the UI.
 * Param:
 *  corecmd - CoreCmdImpl instance that received the command.
 *  cmd_header - Command header.
 *  cmd_param - Command data.
 */
static void
_coreCmdImpl_handle_command(CoreCmdImpl* corecmd,
                            const UICmdHeader* cmd_header,
                            const uint8_t* cmd_param)
{
    switch (cmd_header->cmd_type) {
        case AUICMD_SET_COARSE_ORIENTATION:
        {
            UICmdSetCoarseOrientation* cmd =
                (UICmdSetCoarseOrientation*)cmd_param;
            android_sensors_set_coarse_orientation(cmd->orient);
            break;
        }

        case AUICMD_TOGGLE_NETWORK:
            qemu_net_disable = !qemu_net_disable;
            if (android_modem) {
                amodem_set_data_registration(
                        android_modem,
                qemu_net_disable ? A_REGISTRATION_UNREGISTERED
                    : A_REGISTRATION_HOME);
            }
            break;

        case AUICMD_TRACE_CONTROL:
        {
            UICmdTraceControl* cmd = (UICmdTraceControl*)cmd_param;
            if (cmd->start) {
                start_tracing();
            } else {
                stop_tracing();
            }
            break;
        }

        case AUICMD_CHK_NETWORK_DISABLED:
        {
            UICmdRespHeader resp;
            resp.resp_data_size = 0;
            resp.result = qemu_net_disable;
            _coreCmdImpl_respond(corecmd, &resp, NULL);
            break;
        }

        case AUICMD_GET_NETSPEED:
        {
            UICmdRespHeader resp;
            UICmdGetNetSpeedResp* resp_data = NULL;
            UICmdGetNetSpeed* cmd = (UICmdGetNetSpeed*)cmd_param;

            resp.resp_data_size = 0;
            resp.result = 0;

            if (cmd->index >= android_netspeeds_count ||
                android_netspeeds[cmd->index].name == NULL) {
                resp.result = -1;
            } else {
                const NetworkSpeed* netspeed = &android_netspeeds[cmd->index];
                // Calculate size of the response data:
                // fixed header + zero-terminated netspeed name.
                resp.resp_data_size = sizeof(UICmdGetNetSpeedResp) +
                                      strlen(netspeed->name) + 1;
                // Count in zero-terminated netspeed display.
                if (netspeed->display != NULL) {
                    resp.resp_data_size += strlen(netspeed->display) + 1;
                } else {
                    resp.resp_data_size++;
                }
                // Allocate and initialize response data buffer.
                resp_data =
                    (UICmdGetNetSpeedResp*)g_malloc(resp.resp_data_size);
                resp_data->upload = netspeed->upload;
                resp_data->download = netspeed->download;
                strcpy(resp_data->name, netspeed->name);
                if (netspeed->display != NULL) {
                    strcpy(resp_data->name + strlen(resp_data->name) + 1,
                           netspeed->display);
                } else {
                    strcpy(resp_data->name + strlen(resp_data->name) + 1, "");
                }
            }
            _coreCmdImpl_respond(corecmd, &resp, resp_data);
            if (resp_data != NULL) {
                g_free(resp_data);
            }
            break;
        }

        case AUICMD_GET_NETDELAY:
        {
            UICmdRespHeader resp;
            UICmdGetNetDelayResp* resp_data = NULL;
            UICmdGetNetDelay* cmd = (UICmdGetNetDelay*)cmd_param;

            resp.resp_data_size = 0;
            resp.result = 0;

            if (cmd->index >= android_netdelays_count ||
                android_netdelays[cmd->index].name == NULL) {
                resp.result = -1;
            } else {
                const NetworkLatency* netdelay = &android_netdelays[cmd->index];
                // Calculate size of the response data:
                // fixed header + zero-terminated netdelay name.
                resp.resp_data_size = sizeof(UICmdGetNetDelayResp) +
                                      strlen(netdelay->name) + 1;
                // Count in zero-terminated netdelay display.
                if (netdelay->display != NULL) {
                    resp.resp_data_size += strlen(netdelay->display) + 1;
                } else {
                    resp.resp_data_size++;
                }
                // Allocate and initialize response data buffer.
                resp_data =
                    (UICmdGetNetDelayResp*)g_malloc(resp.resp_data_size);
                resp_data->min_ms = netdelay->min_ms;
                resp_data->max_ms = netdelay->max_ms;
                strcpy(resp_data->name, netdelay->name);
                if (netdelay->display != NULL) {
                    strcpy(resp_data->name + strlen(resp_data->name) + 1,
                           netdelay->display);
                } else {
                    strcpy(resp_data->name + strlen(resp_data->name) + 1, "");
                }
            }
            _coreCmdImpl_respond(corecmd, &resp, resp_data);
            if (resp_data != NULL) {
                g_free(resp_data);
            }
            break;
        }

        case AUICMD_GET_QEMU_PATH:
        {
            UICmdRespHeader resp;
            UICmdGetQemuPath* cmd = (UICmdGetQemuPath*)cmd_param;
            char* filepath = NULL;

            resp.resp_data_size = 0;
            resp.result = -1;
            filepath = qemu_find_file(cmd->type, cmd->filename);
            if (filepath != NULL) {
                resp.resp_data_size = strlen(filepath) + 1;
            }
            _coreCmdImpl_respond(corecmd, &resp, filepath);
            if (filepath != NULL) {
                g_free(filepath);
            }
            break;
        }

        case AUICMD_GET_LCD_DENSITY:
        {
            UICmdRespHeader resp;
            resp.resp_data_size = 0;
            resp.result = android_hw->hw_lcd_density;
            _coreCmdImpl_respond(corecmd, &resp, NULL);
            break;
        }

        default:
            derror("Unknown UI control command %d is received by the Core.\n",
                   cmd_header->cmd_type);
            break;
    }
}

/* Asynchronous I/O callback reading UI control commands.
 * Param:
 *  opaque - CoreCmdImpl instance.
 *  events - Lists I/O event (read or write) this callback is called for.
 */
static void
_coreCmdImpl_io_func(void* opaque, int fd, unsigned events)
{
    AsyncStatus status;
    CoreCmdImpl* corecmd;

    if (events & LOOP_IO_WRITE) {
        // We don't use async writer here, so we don't expect
        // any write callbacks.
        derror("Unexpected LOOP_IO_WRITE in _coreCmdImpl_io_func\n");
        return;
    }

    corecmd = (CoreCmdImpl*)opaque;

    // Read whatever is expected from the socket.
    status = asyncReader_read(&corecmd->async_reader);
    switch (status) {
        case ASYNC_COMPLETE:
            switch (corecmd->cmd_state) {
                case EXPECTS_HEADER:
                    // We just read the command  header. Now we expect the param.
                    if (corecmd->cmd_header.cmd_param_size != 0) {
                        corecmd->cmd_state = EXPECTS_PARAMETERS;
                        // Setup the reader to read expected amount of data.
                        _alloc_cmd_param_buf(corecmd,
                                             corecmd->cmd_header.cmd_param_size);
                        asyncReader_init(&corecmd->async_reader,
                                         corecmd->cmd_param_buf,
                                         corecmd->cmd_header.cmd_param_size,
                                         &corecmd->io);
                    } else {
                        // Command doesn't have param. Go ahead and handle it.
                        _coreCmdImpl_handle_command(corecmd, &corecmd->cmd_header,
                                                NULL);
                        // Prepare for the next header.
                        corecmd->cmd_state = EXPECTS_HEADER;
                        asyncReader_init(&corecmd->async_reader,
                                         &corecmd->cmd_header,
                                         sizeof(corecmd->cmd_header),
                                         &corecmd->io);
                    }
                    break;

                case EXPECTS_PARAMETERS:
                    // Entore command is received. Handle it.
                    _coreCmdImpl_handle_command(corecmd, &corecmd->cmd_header,
                                            corecmd->cmd_param_buf);
                    _free_cmd_param_buf(corecmd);
                    // Prepare for the next command.
                    corecmd->cmd_state = EXPECTS_HEADER;
                    asyncReader_init(&corecmd->async_reader, &corecmd->cmd_header,
                                     sizeof(corecmd->cmd_header), &corecmd->io);
                    break;
            }
            break;

        case ASYNC_ERROR:
            loopIo_dontWantRead(&corecmd->io);
            if (errno == ECONNRESET) {
                // UI has exited. We need to destroy the service.
                destroy_corecmd_client();
            }
            break;

        case ASYNC_NEED_MORE:
            // Transfer will eventually come back into this routine.
            return;
    }
}

int
coreCmdImpl_create(int fd)
{
    _coreCmdImpl.sock = fd;
    _coreCmdImpl.looper = looper_newCore();
    loopIo_init(&_coreCmdImpl.io, _coreCmdImpl.looper, _coreCmdImpl.sock,
                _coreCmdImpl_io_func, &_coreCmdImpl);
    _coreCmdImpl.cmd_state = EXPECTS_HEADER;
    _coreCmdImpl.cmd_param_buf = &_coreCmdImpl.cmd_param[0];
    asyncReader_init(&_coreCmdImpl.async_reader, &_coreCmdImpl.cmd_header,
                     sizeof(_coreCmdImpl.cmd_header), &_coreCmdImpl.io);
    _coreCmdImpl.sync_writer = syncsocket_init(fd);
    if (_coreCmdImpl.sync_writer == NULL) {
        derror("Unable to create writer for CoreCmdImpl instance: %s\n",
               errno_str);
        coreCmdImpl_destroy();
        return -1;
    }
    return 0;
}

void
coreCmdImpl_destroy()
{
    // Destroy the writer
    if (_coreCmdImpl.sync_writer != NULL) {
        syncsocket_close(_coreCmdImpl.sync_writer);
        syncsocket_free(_coreCmdImpl.sync_writer);
    }
    if (_coreCmdImpl.looper != NULL) {
        // Stop all I/O that may still be going on.
        loopIo_done(&_coreCmdImpl.io);
        looper_free(_coreCmdImpl.looper);
        _coreCmdImpl.looper = NULL;
    }
    // Free allocated memory.
    _free_cmd_param_buf(&_coreCmdImpl);
}
