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; } }
static SpiceCharDeviceMsgToClient *spicevmc_chardev_read_msg_from_dev(SpiceCharDeviceInstance *sin, void *opaque) { SpiceVmcState *state = opaque; SpiceCharDeviceInterface *sif; SpiceVmcPipeItem *msg_item; int n; sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base); if (!state->rcc) { return NULL; } if (!state->pipe_item) { msg_item = spice_new0(SpiceVmcPipeItem, 1); msg_item->refs = 1; red_channel_pipe_item_init(&state->channel, &msg_item->base, PIPE_ITEM_TYPE_SPICEVMC_DATA); } else { spice_assert(state->pipe_item->buf_used == 0); msg_item = state->pipe_item; state->pipe_item = NULL; } n = sif->read(sin, msg_item->buf, sizeof(msg_item->buf)); if (n > 0) { spice_debug("read from dev %d", n); msg_item->buf_used = n; return msg_item; } else { state->pipe_item = msg_item; return NULL; } }
SpiceCharDeviceMsgToClient *smartcard_read_msg_from_device(SpiceCharDeviceInstance *sin, void *opaque) { SmartCardDeviceState *state = opaque; SpiceCharDeviceInterface *sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base); VSCMsgHeader *vheader = (VSCMsgHeader*)state->buf; int n; int remaining; int actual_length; while ((n = sif->read(sin, state->buf_pos, state->buf_size - state->buf_used)) > 0) { MsgItem *msg_to_client; state->buf_pos += n; state->buf_used += n; if (state->buf_used < sizeof(VSCMsgHeader)) { continue; } smartcard_read_buf_prepare(state, vheader); actual_length = ntohl(vheader->length); if (state->buf_used - sizeof(VSCMsgHeader) < actual_length) { continue; } msg_to_client = smartcard_char_device_on_message_from_device(state, vheader); remaining = state->buf_used - sizeof(VSCMsgHeader) - actual_length; if (remaining > 0) { memcpy(state->buf, state->buf_pos, remaining); } state->buf_pos = state->buf; state->buf_used = remaining; if (msg_to_client) { return msg_to_client; } } return NULL; }