static void smartcard_connect_client(RedChannel *channel, RedClient *client, RedsStream *stream, int migration, int num_common_caps, uint32_t *common_caps, int num_caps, uint32_t *caps) { SpiceCharDeviceInstance *char_device = smartcard_readers_get_unattached(); SmartCardChannelClient *scc; scc = (SmartCardChannelClient *)red_channel_client_create(sizeof(SmartCardChannelClient), channel, client, stream, num_common_caps, common_caps, num_caps, caps); if (!scc) { return; } red_channel_client_ack_zero_messages_window(&scc->base); if (char_device) { smartcard_char_device_attach_client(char_device, scc); } else { spice_printerr("char dev unavailable"); } }
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); } }
static void smartcard_add_reader(SmartCardChannelClient *scc, uint8_t *name) { if (!scc->smartcard_state) { /* we already tried to attach a reader to the client when it connected */ SpiceCharDeviceInstance *char_device = smartcard_readers_get_unattached(); if (!char_device) { smartcard_push_error(&scc->base, VSCARD_UNDEFINED_READER_ID, VSC_CANNOT_ADD_MORE_READERS); return; } smartcard_char_device_attach_client(char_device, scc); } smartcard_char_device_notify_reader_add(scc->smartcard_state); // The device sends a VSC_Error message, we will let it through, no // need to send our own. We already set the correct reader_id, from // our SmartCardDeviceState. }
static int smartcard_channel_client_handle_migrate_data(RedChannelClient *rcc, uint32_t size, void *message) { SmartCardChannelClient *scc; SpiceMigrateDataHeader *header; SpiceMigrateDataSmartcard *mig_data; scc = SPICE_CONTAINEROF(rcc, SmartCardChannelClient, base); header = (SpiceMigrateDataHeader *)message; mig_data = (SpiceMigrateDataSmartcard *)(header + 1); if (size < sizeof(SpiceMigrateDataHeader) + sizeof(SpiceMigrateDataSmartcard)) { spice_error("bad message size"); return FALSE; } if (!migration_protocol_validate_header(header, SPICE_MIGRATE_DATA_SMARTCARD_MAGIC, SPICE_MIGRATE_DATA_SMARTCARD_VERSION)) { spice_error("bad header"); return FALSE; } if (!mig_data->base.connected) { /* client wasn't attached to a smartcard */ return TRUE; } if (!scc->smartcard_state) { SpiceCharDeviceInstance *char_device = smartcard_readers_get_unattached(); if (!char_device) { spice_warning("no unattached device available"); return TRUE; } else { smartcard_char_device_attach_client(char_device, scc); } } spice_debug("reader added %d partial read_size %u", mig_data->reader_added, mig_data->read_size); scc->smartcard_state->reader_added = mig_data->reader_added; smartcard_device_state_restore_partial_read(scc->smartcard_state, mig_data); return spice_char_device_state_restore(scc->smartcard_state->chardev_st, &mig_data->base); }