static void smartcard_init(void) { ChannelCbs channel_cbs = { NULL, }; ClientCbs client_cbs = { NULL, }; uint32_t migration_flags = SPICE_MIGRATE_NEED_FLUSH | SPICE_MIGRATE_NEED_DATA_TRANSFER; spice_assert(!g_smartcard_channel); channel_cbs.config_socket = smartcard_channel_client_config_socket; channel_cbs.on_disconnect = smartcard_channel_on_disconnect; channel_cbs.send_item = smartcard_channel_send_item; channel_cbs.hold_item = smartcard_channel_hold_pipe_item; channel_cbs.release_item = smartcard_channel_release_pipe_item; channel_cbs.alloc_recv_buf = smartcard_channel_alloc_msg_rcv_buf; channel_cbs.release_recv_buf = smartcard_channel_release_msg_rcv_buf; channel_cbs.handle_migrate_flush_mark = smartcard_channel_client_handle_migrate_flush_mark; channel_cbs.handle_migrate_data = smartcard_channel_client_handle_migrate_data; g_smartcard_channel = (SmartCardChannel*)red_channel_create(sizeof(SmartCardChannel), core, SPICE_CHANNEL_SMARTCARD, 0, FALSE /* handle_acks */, smartcard_channel_handle_message, &channel_cbs, migration_flags); if (!g_smartcard_channel) { spice_error("failed to allocate Smartcard Channel"); } client_cbs.connect = smartcard_connect_client; red_channel_register_client_cbs(&g_smartcard_channel->base, &client_cbs); reds_register_channel(&g_smartcard_channel->base); }
SpiceCharDeviceState *spicevmc_device_connect(SpiceCharDeviceInstance *sin, uint8_t channel_type) { static uint8_t id[256] = { 0, }; SpiceVmcState *state; ChannelCbs channel_cbs = { NULL, }; ClientCbs client_cbs = { NULL, }; SpiceCharDeviceCallbacks char_dev_cbs = {NULL, }; channel_cbs.config_socket = spicevmc_red_channel_client_config_socket; channel_cbs.on_disconnect = spicevmc_red_channel_client_on_disconnect; channel_cbs.send_item = spicevmc_red_channel_send_item; channel_cbs.hold_item = spicevmc_red_channel_hold_pipe_item; channel_cbs.release_item = spicevmc_red_channel_release_pipe_item; channel_cbs.alloc_recv_buf = spicevmc_red_channel_alloc_msg_rcv_buf; channel_cbs.release_recv_buf = spicevmc_red_channel_release_msg_rcv_buf; channel_cbs.handle_migrate_flush_mark = spicevmc_channel_client_handle_migrate_flush_mark; channel_cbs.handle_migrate_data = spicevmc_channel_client_handle_migrate_data; state = (SpiceVmcState*)red_channel_create(sizeof(SpiceVmcState), core, channel_type, id[channel_type]++, FALSE /* handle_acks */, spicevmc_red_channel_client_handle_message, &channel_cbs, SPICE_MIGRATE_NEED_FLUSH | SPICE_MIGRATE_NEED_DATA_TRANSFER); red_channel_init_outgoing_messages_window(&state->channel); client_cbs.connect = spicevmc_connect; red_channel_register_client_cbs(&state->channel, &client_cbs); char_dev_cbs.read_one_msg_from_device = spicevmc_chardev_read_msg_from_dev; char_dev_cbs.ref_msg_to_client = spicevmc_chardev_ref_msg_to_client; char_dev_cbs.unref_msg_to_client = spicevmc_chardev_unref_msg_to_client; char_dev_cbs.send_msg_to_client = spicevmc_chardev_send_msg_to_client; char_dev_cbs.send_tokens_to_client = spicevmc_char_dev_send_tokens_to_client; char_dev_cbs.remove_client = spicevmc_char_dev_remove_client; state->chardev_st = spice_char_device_state_create(sin, 0, /* tokens interval */ ~0, /* self tokens */ &char_dev_cbs, state); state->chardev_sin = sin; reds_register_channel(&state->channel); return state->chardev_st; }
static void smartcard_link(Channel *channel, RedsStreamContext *peer, int migration, int num_common_caps, uint32_t *common_caps, int num_caps, uint32_t *caps) { if (g_smartcard_channel) { red_channel_destroy(&g_smartcard_channel->base); } g_smartcard_channel = (SmartCardChannel *)red_channel_create(sizeof(*g_smartcard_channel), peer, core, migration, FALSE /* handle_acks */, smartcard_channel_config_socket, smartcard_channel_disconnect, smartcard_channel_handle_message, smartcard_channel_alloc_msg_rcv_buf, smartcard_channel_release_msg_rcv_buf, smartcard_channel_send_item, smartcard_channel_release_pipe_item); if (!g_smartcard_channel) { return; } red_channel_init_outgoing_messages_window(&g_smartcard_channel->base); }