static int
_uiCmdProxy_send_command(uint8_t cmd_type,
                         void* cmd_param,
                         uint32_t cmd_param_size)
{
    UICmdHeader header;
    int status = syncsocket_start_write(_uiCmdProxy.sync_writer);
    if (!status) {
        
        header.cmd_type = cmd_type;
        header.cmd_param_size = cmd_param_size;
        status = syncsocket_write(_uiCmdProxy.sync_writer, &header, sizeof(header),
                                  _uiCmdProxy_get_timeout(sizeof(header)));
        
        if (status > 0 && cmd_param != NULL && cmd_param_size > 0) {
            status = syncsocket_write(_uiCmdProxy.sync_writer, cmd_param,
                                      cmd_param_size,
                                      _uiCmdProxy_get_timeout(cmd_param_size));
        }
        status = syncsocket_result(status);
        syncsocket_stop_write(_uiCmdProxy.sync_writer);
    }
    if (status < 0) {
        derror("Send UI command %d (%u bytes) has failed: %s\n",
               cmd_type, cmd_param_size, errno_str);
    }
    return status;
}
static int
_userEventsProxy_send(uint8_t event, const void* event_param, size_t size)
{
    int res;
    UserEventHeader header;

    header.event_type = event;
    res = syncsocket_start_write(_userEventsProxy.sync_writer);
    if (!res) {
        
        res = syncsocket_write(_userEventsProxy.sync_writer, &header,
                               sizeof(header),
                               core_connection_get_timeout(sizeof(header)));
        if (res > 0) {
            
            res = syncsocket_write(_userEventsProxy.sync_writer, event_param,
                                   size,
                                   core_connection_get_timeout(sizeof(size)));
        }
        res = syncsocket_result(res);
        syncsocket_stop_write(_userEventsProxy.sync_writer);
    }
    if (res < 0) {
        derror("Unable to send user event: %s\n", errno_str);
    }
    return res;
}
Пример #3
0
/* Sends UI command to the core.
 * Param:
 *  cmd_type, cmd_param, cmd_param_size - Define the command.
 * Return:
 *  0 On success, or < 0 on failure.
 */
static int
_coreCmdProxy_send_command(uint8_t cmd_type,
                           void* cmd_param,
                           uint32_t cmd_param_size)
{
    int status;
    UICmdHeader header;

    // Prepare the command header.
    header.cmd_type = cmd_type;
    header.cmd_param_size = cmd_param_size;
    status = syncsocket_start_write(_coreCmdProxy.sync_writer);
    if (!status) {
        // Send the header.
        status = syncsocket_write(_coreCmdProxy.sync_writer, &header,
                                  sizeof(header),
                                  core_connection_get_timeout(sizeof(header)));
        // If there is request data, send it too.
        if (status > 0 && cmd_param != NULL && cmd_param_size > 0) {
            status = syncsocket_write(_coreCmdProxy.sync_writer, cmd_param,
                                      cmd_param_size,
                                      core_connection_get_timeout(cmd_param_size));
        }
        status = syncsocket_result(status);
        syncsocket_stop_write(_coreCmdProxy.sync_writer);
    }
    if (status < 0) {
        derror("Unable to send UI control command %d (size %u): %s\n",
               cmd_type, cmd_param_size, errno_str);
    }
    return status;
}
/* 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;
}
ClientFramebuffer*
clientfb_create(SockAddress* console_socket,
                const char* protocol,
                QFrameBuffer* fb)
{
    char* connect_message = NULL;
    char switch_cmd[256];

    // Connect to the framebuffer service.
    _client_fb.core_connection = core_connection_create(console_socket);
    if (_client_fb.core_connection == NULL) {
        derror("Framebuffer client is unable to connect to the console: %s\n",
               errno_str);
        return NULL;
    }
    if (core_connection_open(_client_fb.core_connection)) {
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        derror("Framebuffer client is unable to open the console: %s\n",
               errno_str);
        return NULL;
    }
    snprintf(switch_cmd, sizeof(switch_cmd), "framebuffer %s", protocol);
    if (core_connection_switch_stream(_client_fb.core_connection, switch_cmd,
                                      &connect_message)) {
        derror("Unable to attach to the framebuffer %s: %s\n",
               switch_cmd, connect_message ? connect_message : "");
        if (connect_message != NULL) {
            free(connect_message);
        }
        core_connection_close(_client_fb.core_connection);
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        return NULL;
    }

    // We expect core framebuffer to return us bits per pixel property in
    // the handshake message.
    _client_fb.bits_per_pixel = 0;
    if (connect_message != NULL) {
        char* bpp = strstr(connect_message, "bitsperpixel=");
        if (bpp != NULL) {
            char* end;
            bpp += strlen("bitsperpixel=");
            end = strchr(bpp, ' ');
            if (end == NULL) {
                end = bpp + strlen(bpp);
            }
            _client_fb.bits_per_pixel = strtol(bpp, &end, 0);
        }
    }

    if (!_client_fb.bits_per_pixel) {
        derror("Unexpected core framebuffer reply: %s\n"
               "Bits per pixel property is not there, or is invalid\n", connect_message);
        core_connection_close(_client_fb.core_connection);
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        return NULL;
    }

    // Now that we're connected lets initialize the descriptor.
    _client_fb.fb = fb;
    _client_fb.sock = core_connection_get_socket(_client_fb.core_connection);
    _client_fb.fb_state = WAIT_HEADER;
    _client_fb.reader_buffer = (uint8_t*)&_client_fb.update_header;
    _client_fb.reader_offset = 0;
    _client_fb.reader_bytes = sizeof(FBUpdateMessage);

    if (connect_message != NULL) {
        free(connect_message);
    }

    // At last setup read callback, and start receiving the updates.
    if (qemu_set_fd_handler(_client_fb.sock, _clientfb_read_cb, NULL, &_client_fb)) {
        derror("Unable to set up framebuffer read callback\n");
        core_connection_close(_client_fb.core_connection);
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        return NULL;
    }
    {
        // Force the core to send us entire framebuffer now, when we're prepared
        // to receive it.
        FBRequestHeader hd;
        SyncSocket* sk = syncsocket_init(_client_fb.sock);

        hd.request_type = AFB_REQUEST_REFRESH;
        syncsocket_start_write(sk);
        syncsocket_write(sk, &hd, sizeof(hd), 500);
        syncsocket_stop_write(sk);
        syncsocket_free(sk);
    }
    fprintf(stdout, "Framebuffer %s is now attached to the core %s\n",
            protocol, sock_address_to_string(console_socket));

    return &_client_fb;
}