Esempio n. 1
0
void smartcard_char_device_wakeup(SpiceCharDeviceInstance *sin)
{
    SmartCardDeviceState* state = SPICE_CONTAINEROF(
                            sin->st, SmartCardDeviceState, base);
    SpiceCharDeviceInterface *sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
    VSCMsgHeader *vheader = (VSCMsgHeader*)state->buf;
    int n;
    int remaining;

    while ((n = sif->read(sin, state->buf_pos, state->buf_size - state->buf_used)) > 0) {
        state->buf_pos += n;
        state->buf_used += n;
        if (state->buf_used < sizeof(VSCMsgHeader)) {
            continue;
        }
        if (vheader->length > state->buf_size) {
            state->buf_size = MAX(state->buf_size*2, vheader->length + sizeof(VSCMsgHeader));
            state->buf = spice_realloc(state->buf, state->buf_size);
            ASSERT(state->buf != NULL);
        }
        if (state->buf_used - sizeof(VSCMsgHeader) < vheader->length) {
            continue;
        }
        smartcard_char_device_on_message_from_device(state, vheader);
        remaining = state->buf_used - sizeof(VSCMsgHeader) > vheader->length;
        if (remaining > 0) {
            memcpy(state->buf, state->buf_pos, remaining);
        }
        state->buf_pos = state->buf;
        state->buf_used = remaining;
    }
}
Esempio n. 2
0
static void spicevmc_red_channel_client_on_disconnect(RedChannelClient *rcc)
{
    SpiceVmcState *state;
    SpiceCharDeviceInstance *sin;
    SpiceCharDeviceInterface *sif;

    if (!rcc) {
        return;
    }

    state = SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel);
    sin = state->chardev_sin;
    sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);

    if (state->chardev_st) {
        if (spice_char_device_client_exists(state->chardev_st, rcc->client)) {
            spice_char_device_client_remove(state->chardev_st, rcc->client);
        } else {
            spice_printerr("client %p have already been removed from char dev %p",
                           rcc->client, state->chardev_st);
        }
    }

    /* Don't destroy the rcc if it is already being destroyed, as then
       red_client_destroy/red_channel_client_destroy will already do this! */
    if (!rcc->destroying)
        red_channel_client_destroy(rcc);

    state->rcc = NULL;
    if (sif->state) {
        sif->state(sin, 0);
    }
}
Esempio n. 3
0
static uint8_t *spicevmc_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
                                                       uint16_t type,
                                                       uint32_t size)
{
    SpiceVmcState *state;

    state = SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel);

    switch (type) {
    case SPICE_MSGC_SPICEVMC_DATA:
        assert(!state->recv_from_client_buf);

        state->recv_from_client_buf = spice_char_device_write_buffer_get(state->chardev_st,
                                                                         rcc->client,
                                                                         size);
        if (!state->recv_from_client_buf) {
            spice_error("failed to allocate write buffer");
            return NULL;
        }
        return state->recv_from_client_buf->buf;

    default:
        return spice_malloc(size);
    }

}
Esempio n. 4
0
static int spicevmc_red_channel_client_handle_message(RedChannelClient *rcc,
                                                      uint16_t type,
                                                      uint32_t size,
                                                      uint8_t *msg)
{
    SpiceVmcState *state;
    SpiceCharDeviceInstance *sin;
    SpiceCharDeviceInterface *sif;

    state = spicevmc_red_channel_client_get_state(rcc);
    sin = state->chardev_sin;
    sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);

    switch (type) {
    case SPICE_MSGC_SPICEVMC_DATA:
        spice_assert(state->recv_from_client_buf->buf == msg);
        state->recv_from_client_buf->buf_used = size;
        spice_char_device_write_buffer_add(state->chardev_st, state->recv_from_client_buf);
        state->recv_from_client_buf = NULL;
        break;
    case SPICE_MSGC_PORT_EVENT:
        if (size != sizeof(uint8_t)) {
            spice_warning("bad port event message size");
            return FALSE;
        }
        if (sif->base.minor_version >= 2 && sif->event != NULL)
            sif->event(sin, *msg);
        break;
    default:
        return red_channel_client_handle_message(rcc, size, type, msg);
    }

    return TRUE;
}
Esempio n. 5
0
void smartcard_device_disconnect(SpiceCharDeviceInstance *char_device)
{
    SmartCardDeviceState *st = SPICE_CONTAINEROF(char_device->st,
        SmartCardDeviceState, base);

    smartcard_device_state_free(st);
}
Esempio n. 6
0
static void cursor_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item)
{
    SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
    CursorChannelClient *ccc = RCC_TO_CCC(rcc);

    switch (pipe_item->type) {
    case PIPE_ITEM_TYPE_CURSOR:
        cursor_marshall(rcc, m, SPICE_CONTAINEROF(pipe_item, CursorPipeItem, base));
        break;
    case PIPE_ITEM_TYPE_INVAL_ONE:
        red_marshall_inval(rcc, m, (CacheItem *)pipe_item);
        break;
    case PIPE_ITEM_TYPE_VERB:
        red_marshall_verb(rcc, (VerbItem*)pipe_item);
        break;
    case PIPE_ITEM_TYPE_CURSOR_INIT:
        red_reset_cursor_cache(rcc);
        red_marshall_cursor_init(rcc, m, pipe_item);
        break;
    case PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE:
        red_reset_cursor_cache(rcc);
        red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_INVAL_ALL, NULL);
        break;
    default:
        spice_error("invalid pipe item type");
    }

    cursor_channel_client_release_item_before_push(ccc, pipe_item);
    red_channel_client_begin_send_message(rcc);
}
Esempio n. 7
0
static void smartcard_channel_send_migrate_data(RedChannelClient *rcc,
                                                SpiceMarshaller *m, PipeItem *item)
{
    SmartCardChannelClient *scc;
    SmartCardDeviceState *state;
    SpiceMarshaller *m2;

    scc = SPICE_CONTAINEROF(rcc, SmartCardChannelClient, base);
    state = scc->smartcard_state;
    red_channel_client_init_send_data(rcc, SPICE_MSG_MIGRATE_DATA, item);
    spice_marshaller_add_uint32(m, SPICE_MIGRATE_DATA_SMARTCARD_MAGIC);
    spice_marshaller_add_uint32(m, SPICE_MIGRATE_DATA_SMARTCARD_VERSION);

    if (!state) {
        spice_char_device_state_migrate_data_marshall_empty(m);
        spice_marshaller_add_uint8(m, 0);
        spice_marshaller_add_uint32(m, 0);
        spice_marshaller_add_uint32(m, 0);
        spice_debug("null char dev state");
    } else {
        spice_char_device_state_migrate_data_marshall(state->chardev_st, m);
        spice_marshaller_add_uint8(m, state->reader_added);
        spice_marshaller_add_uint32(m, state->buf_used);
        m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
        spice_marshaller_add_ref(m2, state->buf, state->buf_used);
        spice_debug("reader added %d partial read size %u", state->reader_added, state->buf_used);
    }
}
Esempio n. 8
0
static uint8_t *smartcard_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
                                                    uint16_t type,
                                                    uint32_t size)
{
    SmartCardChannelClient *scc = SPICE_CONTAINEROF(rcc, SmartCardChannelClient, base);

    /* todo: only one reader is actually supported. When we fix the code to support
     * multiple readers, we will porbably associate different devices to
     * differenc channels */
    if (!scc->smartcard_state) {
        scc->msg_in_write_buf = FALSE;
        return spice_malloc(size);
    } else {
        SmartCardDeviceState *st;

        spice_assert(g_smartcard_readers.num == 1);
        st = scc->smartcard_state;
        spice_assert(st->scc || scc->smartcard_state);
        spice_assert(!scc->write_buf);
        scc->write_buf = spice_char_device_write_buffer_get(st->chardev_st, rcc->client, size);

        if (!scc->write_buf) {
            spice_error("failed to allocate write buffer");
            return NULL;
        }
        scc->msg_in_write_buf = TRUE;
        return scc->write_buf->buf;
    }
}
static void begin_decode(SpiceJpegDecoder *decoder,
                         uint8_t* data, int data_size,
                         int* out_width, int* out_height)
{
    GlibJpegDecoder *d = SPICE_CONTAINEROF(decoder, GlibJpegDecoder, base);

    g_return_if_fail(data != NULL);
    g_return_if_fail(data_size != 0);

    if (d->_data)
        jpeg_abort_decompress(&d->_cinfo);

    d->_data = data;
    d->_data_size = data_size;

    d->_cinfo.src->next_input_byte = d->_data;
    d->_cinfo.src->bytes_in_buffer = d->_data_size;

    jpeg_read_header(&d->_cinfo, TRUE);

    d->_cinfo.out_color_space = JCS_RGB;
    d->_width = d->_cinfo.image_width;
    d->_height = d->_cinfo.image_height;

    *out_width = d->_width;
    *out_height = d->_height;
}
void jpeg_decoder_destroy(SpiceJpegDecoder *decoder)
{
    GlibJpegDecoder *d = SPICE_CONTAINEROF(decoder, GlibJpegDecoder, base);

    jpeg_destroy_decompress(&d->_cinfo);
    free(d);
}
static void decode(SpiceJpegDecoder *decoder,
                   uint8_t* dest, int stride, int format)
{
    GlibJpegDecoder *d = SPICE_CONTAINEROF(decoder, GlibJpegDecoder, base);
    uint8_t* scan_line = g_alloca(d->_width * 3);
    converter_rgb_t converter = NULL;
    int row;

    switch (format) {
    case SPICE_BITMAP_FMT_24BIT:
        converter = convert_rgb_to_bgr;
        break;
    case SPICE_BITMAP_FMT_32BIT:
        converter = convert_rgb_to_bgrx;
        break;
    default:
        g_warning("bad bitmap format, %d", format);
        return;
    }

    g_return_if_fail(converter != NULL);

    jpeg_start_decompress(&d->_cinfo);

    for (row = 0; row < d->_height; row++) {
        jpeg_read_scanlines(&d->_cinfo, &scan_line, 1);
        converter(scan_line, dest, d->_width);
        dest += stride;
    }

    jpeg_finish_decompress(&d->_cinfo);
}
Esempio n. 12
0
static void spicevmc_connect(RedChannel *channel, RedClient *client,
    RedsStream *stream, int migration, int num_common_caps,
    uint32_t *common_caps, int num_caps, uint32_t *caps)
{
    RedChannelClient *rcc;
    SpiceVmcState *state;
    SpiceCharDeviceInstance *sin;
    SpiceCharDeviceInterface *sif;

    state = SPICE_CONTAINEROF(channel, SpiceVmcState, channel);
    sin = state->chardev_sin;
    sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);

    if (state->rcc) {
        spice_printerr("channel client %d:%d (%p) already connected, refusing second connection",
                       channel->type, channel->id, state->rcc);
        // TODO: notify client in advance about the in use channel using
        // SPICE_MSG_MAIN_CHANNEL_IN_USE (for example)
        reds_stream_free(stream);
        return;
    }

    rcc = red_channel_client_create(sizeof(RedChannelClient), channel, client, stream,
                                    FALSE,
                                    num_common_caps, common_caps,
                                    num_caps, caps);
    if (!rcc) {
        return;
    }
    state->rcc = rcc;
    red_channel_client_ack_zero_messages_window(rcc);

    if (strcmp(sin->subtype, "port") == 0) {
        spicevmc_port_send_init(rcc);
    }

    if (!spice_char_device_client_add(state->chardev_st, client, FALSE, 0, ~0, ~0,
                                      red_channel_client_waits_for_migrate_data(rcc))) {
        spice_warning("failed to add client to spicevmc");
        red_channel_client_disconnect(rcc);
        return;
    }

    if (sif->state) {
        sif->state(sin, 1);
    }
}
static void mjpeg_src_init(struct jpeg_decompress_struct *cinfo)
{
    display_stream *st = SPICE_CONTAINEROF(cinfo->src, display_stream, mjpeg_src);
    uint8_t *data;

    cinfo->src->bytes_in_buffer = stream_get_current_frame(st, &data);
    cinfo->src->next_input_byte = data;
}
Esempio n. 14
0
static void smartcard_char_device_attach(
    SpiceCharDeviceInstance *char_device, SmartCardChannel *smartcard_channel)
{
    SmartCardDeviceState *st = SPICE_CONTAINEROF(char_device->st, SmartCardDeviceState, base);

    if (st->attached == TRUE) {
        return;
    }
    st->attached = TRUE;
    VSCMsgHeader vheader = {.type = VSC_ReaderAdd, .reader_id=st->reader_id,
        .length=0};
    smartcard_channel_write_to_reader(smartcard_channel, &vheader);
}

static void smartcard_char_device_detach(
    SpiceCharDeviceInstance *char_device, SmartCardChannel *smartcard_channel)
{
    SmartCardDeviceState *st = SPICE_CONTAINEROF(char_device->st, SmartCardDeviceState, base);

    if (st->attached == FALSE) {
        return;
    }
    st->attached = FALSE;
    VSCMsgHeader vheader = {.type = VSC_ReaderRemove, .reader_id=st->reader_id,
        .length=0};
    smartcard_channel_write_to_reader(smartcard_channel, &vheader);
}

static int smartcard_channel_config_socket(RedChannel *channel)
{
    return TRUE;
}

static uint8_t *smartcard_channel_alloc_msg_rcv_buf(RedChannel *channel, SpiceDataHeader *msg_header)
{
    //red_printf("allocing %d bytes", msg_header->size);
    return spice_malloc(msg_header->size);
}

static void smartcard_channel_release_msg_rcv_buf(RedChannel *channel, SpiceDataHeader *msg_header,
                                               uint8_t *msg)
{
    red_printf("freeing %d bytes", msg_header->size);
    free(msg);
}
Esempio n. 15
0
static void spicevmc_red_channel_send_data(RedChannelClient *rcc,
                                           SpiceMarshaller *m,
                                           PipeItem *item)
{
    SpiceVmcPipeItem *i = SPICE_CONTAINEROF(item, SpiceVmcPipeItem, base);

    red_channel_client_init_send_data(rcc, SPICE_MSG_SPICEVMC_DATA, item);
    spice_marshaller_add_ref(m, i->buf, i->buf_used);
}
Esempio n. 16
0
static void cursor_channel_hold_pipe_item(RedChannelClient *rcc, PipeItem *item)
{
    CursorPipeItem *cursor_pipe_item;

    spice_return_if_fail(item);

    cursor_pipe_item = SPICE_CONTAINEROF(item, CursorPipeItem, base);
    cursor_pipe_item_ref(cursor_pipe_item);
}
Esempio n. 17
0
static void spicevmc_port_send_init(RedChannelClient *rcc)
{
    SpiceVmcState *state = SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel);
    SpiceCharDeviceInstance *sin = state->chardev_sin;
    PortInitPipeItem *item = spice_malloc(sizeof(PortInitPipeItem));

    red_channel_pipe_item_init(rcc->channel, &item->base, PIPE_ITEM_TYPE_PORT_INIT);
    item->name = strdup(sin->portname);
    item->opened = state->port_opened;
    red_channel_client_pipe_add_push(rcc, &item->base);
}
Esempio n. 18
0
static void smartcard_channel_on_disconnect(RedChannelClient *rcc)
{
    SmartCardChannelClient *scc = SPICE_CONTAINEROF(rcc, SmartCardChannelClient, base);

    if (scc->smartcard_state) {
        SmartCardDeviceState *st = scc->smartcard_state;

        smartcard_char_device_detach_client(scc);
        smartcard_char_device_notify_reader_remove(st);
    }
}
Esempio n. 19
0
static void spicevmc_red_channel_send_port_event(RedChannelClient *rcc,
                                                 SpiceMarshaller *m,
                                                 PipeItem *item)
{
    PortEventPipeItem *i = SPICE_CONTAINEROF(item, PortEventPipeItem, base);
    SpiceMsgPortEvent event;

    red_channel_client_init_send_data(rcc, SPICE_MSG_PORT_EVENT, item);
    event.event = i->event;
    spice_marshall_msg_port_event(m, &event);
}
Esempio n. 20
0
static int record_zlib_more_input(ZlibEncoderUsrContext *usr, uint8_t **input)
{
    RecordEncoderData *data = SPICE_CONTAINEROF(usr, RecordEncoderData, base);

    if (data->buf == NULL) {
        fprintf(stderr, "%s: error: no more data\n", __FUNCTION__);
        exit(1);
    }
    *input = data->buf;
    data->buf = 0;
    return data->size;
}
Esempio n. 21
0
static int smartcard_char_device_add_to_readers(SpiceCharDeviceInstance *char_device)
{
    SmartCardDeviceState* state = SPICE_CONTAINEROF(
                            char_device->st, SmartCardDeviceState, base);

    if (g_smartcard_readers.num >= SMARTCARD_MAX_READERS) {
        return -1;
    }
    state->reader_id = g_smartcard_readers.num;
    g_smartcard_readers.sin[g_smartcard_readers.num++] = char_device;
    return 0;
}
Esempio n. 22
0
static void cursor_marshall(RedChannelClient *rcc,
                            SpiceMarshaller *m, CursorPipeItem *cursor_pipe_item)
{
    CursorChannel *cursor_channel = SPICE_CONTAINEROF(rcc->channel, CursorChannel, common.base);
    CursorChannelClient *ccc = RCC_TO_CCC(rcc);
    CursorItem *item = cursor_pipe_item->cursor_item;
    PipeItem *pipe_item = &cursor_pipe_item->base;
    RedCursorCmd *cmd;

    spice_return_if_fail(cursor_channel);

    cmd = item->red_cursor;
    switch (cmd->type) {
    case QXL_CURSOR_MOVE:
        {
            SpiceMsgCursorMove cursor_move;
            red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_MOVE, pipe_item);
            cursor_move.position = cmd->u.position;
            spice_marshall_msg_cursor_move(m, &cursor_move);
            break;
        }
    case QXL_CURSOR_SET:
        {
            SpiceMsgCursorSet cursor_set;
            AddBufInfo info;

            red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_SET, pipe_item);
            cursor_set.position = cmd->u.set.position;
            cursor_set.visible = cursor_channel->cursor_visible;

            cursor_fill(ccc, &cursor_set.cursor, item, &info);
            spice_marshall_msg_cursor_set(m, &cursor_set);
            add_buf_from_info(m, &info);
            break;
        }
    case QXL_CURSOR_HIDE:
        red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_HIDE, pipe_item);
        break;
    case QXL_CURSOR_TRAIL:
        {
            SpiceMsgCursorTrail cursor_trail;

            red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_TRAIL, pipe_item);
            cursor_trail.length = cmd->u.trail.length;
            cursor_trail.frequency = cmd->u.trail.frequency;
            spice_marshall_msg_cursor_trail(m, &cursor_trail);
        }
        break;
    default:
        spice_error("bad cursor command %d", cmd->type);
    }
}
Esempio n. 23
0
static void spicevmc_red_channel_send_migrate_data(RedChannelClient *rcc,
                                                   SpiceMarshaller *m,
                                                   PipeItem *item)
{
    SpiceVmcState *state;

    state = SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel);
    red_channel_client_init_send_data(rcc, SPICE_MSG_MIGRATE_DATA, item);
    spice_marshaller_add_uint32(m, SPICE_MIGRATE_DATA_SPICEVMC_MAGIC);
    spice_marshaller_add_uint32(m, SPICE_MIGRATE_DATA_SPICEVMC_VERSION);

    spice_char_device_state_migrate_data_marshall(state->chardev_st, m);
}
Esempio n. 24
0
static void cursor_channel_client_release_item_after_push(CursorChannelClient *ccc,
                                                          PipeItem *item)
{
    switch (item->type) {
        case PIPE_ITEM_TYPE_CURSOR: {
            CursorPipeItem *cursor_pipe_item = SPICE_CONTAINEROF(item, CursorPipeItem, base);
            put_cursor_pipe_item(ccc, cursor_pipe_item);
            break;
        }
        default:
            spice_critical("invalid item type");
    }
}
Esempio n. 25
0
static void spicevmc_red_channel_send_port_init(RedChannelClient *rcc,
                                                SpiceMarshaller *m,
                                                PipeItem *item)
{
    PortInitPipeItem *i = SPICE_CONTAINEROF(item, PortInitPipeItem, base);
    SpiceMsgPortInit init;

    red_channel_client_init_send_data(rcc, SPICE_MSG_PORT_INIT, item);
    init.name = (uint8_t *)i->name;
    init.name_size = strlen(i->name) + 1;
    init.opened = i->opened;
    spice_marshall_msg_port_init(m, &init);
}
Esempio n. 26
0
static SpiceCharDeviceInstance *smartcard_readers_get_unattached()
{
    int i;
    SmartCardDeviceState* state;

    for (i = 0; i < g_smartcard_readers.num; ++i) {
        state = SPICE_CONTAINEROF(g_smartcard_readers.sin[i]->st,
                                  SmartCardDeviceState, base);
        if (!state->attached) {
            return g_smartcard_readers.sin[i];
        }
    }
    return NULL;
}
Esempio n. 27
0
static void set_client_capabilities(QXLInstance *qin,
                                    uint8_t client_present,
                                    uint8_t caps[58])
{
    Test *test = SPICE_CONTAINEROF(qin, Test, qxl_instance);

    printf("%s: present %d caps %d\n", __func__, client_present, caps[0]);
    if (test->on_client_connected && client_present) {
        test->on_client_connected(test);
    }
    if (test->on_client_disconnected && !client_present) {
        test->on_client_disconnected(test);
    }
}
Esempio n. 28
0
static int smartcard_channel_handle_message(RedChannelClient *rcc,
                                            uint16_t type,
                                            uint32_t size,
                                            uint8_t *msg)
{
    VSCMsgHeader* vheader = (VSCMsgHeader*)msg;
    SmartCardChannelClient *scc = SPICE_CONTAINEROF(rcc, SmartCardChannelClient, base);

    if (type != SPICE_MSGC_SMARTCARD_DATA) {
        /* Handles seamless migration protocol. Also handles ack's,
         * spicy sends them while spicec does not */
        return red_channel_client_handle_message(rcc, size, type, msg);
    }

    spice_assert(size == vheader->length + sizeof(VSCMsgHeader));
    switch (vheader->type) {
        case VSC_ReaderAdd:
            smartcard_add_reader(scc, msg + sizeof(VSCMsgHeader));
            return TRUE;
            break;
        case VSC_ReaderRemove:
            smartcard_remove_reader(scc, vheader->reader_id);
            return TRUE;
            break;
        case VSC_Init:
            // ignore - we should never get this anyway
            return TRUE;
            break;
        case VSC_Error:
        case VSC_ATR:
        case VSC_CardRemove:
        case VSC_APDU:
            break; // passed on to device
        default:
            printf("ERROR: unexpected message on smartcard channel\n");
            return TRUE;
    }

    /* todo: fix */
    if (vheader->reader_id >= g_smartcard_readers.num) {
        spice_printerr("ERROR: received message for non existing reader: %d, %d, %d", vheader->reader_id,
            vheader->type, vheader->length);
        return FALSE;
    }
    spice_assert(scc->write_buf->buf == msg);
    smartcard_channel_write_to_reader(scc->write_buf);

    return TRUE;
}
Esempio n. 29
0
static void smartcard_channel_write_to_reader(
    SmartCardChannel *smartcard_channel, VSCMsgHeader *vheader)
{
    SpiceCharDeviceInstance *sin;
    SpiceCharDeviceInterface *sif;
    uint32_t n;

    ASSERT(vheader->reader_id >= 0 &&
           vheader->reader_id <= g_smartcard_readers.num);
    sin = g_smartcard_readers.sin[vheader->reader_id];
    sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
    n = sif->write(sin, (uint8_t*)vheader,
                   vheader->length + sizeof(VSCMsgHeader));
    // TODO - add ring
    ASSERT(n == vheader->length + sizeof(VSCMsgHeader));
}
Esempio n. 30
0
static void smartcard_add_reader(SmartCardChannel *smartcard_channel, uint8_t *name)
{
    // TODO - save name somewhere
    SpiceCharDeviceInstance *char_device =
            smartcard_readers_get_unattached();
    SmartCardDeviceState *state;

    if (char_device != NULL) {
        state = SPICE_CONTAINEROF(char_device->st, SmartCardDeviceState, base);
        smartcard_char_device_attach(char_device, smartcard_channel);
        smartcard_push_reader_add_response(smartcard_channel, state->reader_id);
    } else {
        smartcard_push_error(smartcard_channel, VSCARD_UNDEFINED_READER_ID,
            VSC_CANNOT_ADD_MORE_READERS);
    }
}