diff options
author | Alon Levy <alevy@redhat.com> | 2010-11-13 13:23:02 +0200 |
---|---|---|
committer | Alon Levy <alevy@redhat.com> | 2011-08-23 17:42:36 +0300 |
commit | 7e8e13593ee681cf04c349bca57dd225d7802494 (patch) | |
tree | f47be108ffe570dfa942502b8bad837551db4720 /server/smartcard.c | |
parent | 75b6a305ff9c42a89c9db91277027d5dc6d103ef (diff) | |
download | spice-7e8e13593ee681cf04c349bca57dd225d7802494.tar.gz spice-7e8e13593ee681cf04c349bca57dd225d7802494.tar.xz spice-7e8e13593ee681cf04c349bca57dd225d7802494.zip |
server/red_channel (all): introduce RedChannelClient
This commit adds a RedChannelClient that now owns the stream connection,
but still doesn't own the pipe. There is only a single RCC per RC
right now (and RC still means RedChannel, RedClient will be introduced
later). All internal api changes are in server/red_channel.h, hence
the need to update all channels. red_worker.c is affected the most because
it makes use of direct access to some of RedChannel still.
API changes:
1. red_channel_client_create added.
rec_channel_create -> (red_channel_create, red_channel_client_create)
2. two way connection: rcc->channel, channel->rcc (later channel will
hold a list, and there will be a RedClient to hold the list of channels
per client)
3. seperation of channel disconnect and channel_client_disconnect
TODO:
usbredir added untested.
Diffstat (limited to 'server/smartcard.c')
-rw-r--r-- | server/smartcard.c | 147 |
1 files changed, 73 insertions, 74 deletions
diff --git a/server/smartcard.c b/server/smartcard.c index 3f59317f..a8a7beb8 100644 --- a/server/smartcard.c +++ b/server/smartcard.c @@ -36,6 +36,7 @@ typedef struct SmartCardDeviceState { uint32_t buf_size; uint8_t *buf_pos; uint32_t buf_used; + RedChannelClient *rcc; // client providing the remote card } SmartCardDeviceState; enum { @@ -58,8 +59,6 @@ typedef struct SmartCardChannel { RedChannel base; } SmartCardChannel; -static SmartCardChannel *g_smartcard_channel = NULL; - static struct Readers { uint32_t num; SpiceCharDeviceInstance* sin[SMARTCARD_MAX_READERS]; @@ -69,16 +68,14 @@ static SpiceCharDeviceInstance* smartcard_readers_get_unattached(); static SpiceCharDeviceInstance* smartcard_readers_get(uint32_t reader_id); static int smartcard_char_device_add_to_readers(SpiceCharDeviceInstance *sin); static void smartcard_char_device_attach( - SpiceCharDeviceInstance *char_device, SmartCardChannel *smartcard_channel); -static void smartcard_char_device_detach( - SpiceCharDeviceInstance *char_device, SmartCardChannel *smartcard_channel); -static void smartcard_channel_write_to_reader( - SmartCardChannel *smartcard_channel, VSCMsgHeader *vheader); + SpiceCharDeviceInstance *char_device, RedChannelClient *rcc); +static void smartcard_char_device_detach(SpiceCharDeviceInstance *char_device); +static void smartcard_channel_write_to_reader(VSCMsgHeader *vheader); static void smartcard_char_device_on_message_from_device( SmartCardDeviceState *state, VSCMsgHeader *header); static void smartcard_on_message_from_device( - SmartCardChannel *smartcard_channel, VSCMsgHeader *vheader); + RedChannelClient *rcc, VSCMsgHeader *vheader); static SmartCardDeviceState* smartcard_device_state_new(); static void smartcard_device_state_free(SmartCardDeviceState* st); static void smartcard_register_channel(void); @@ -139,12 +136,13 @@ void smartcard_char_device_on_message_from_device( if (state->reader_id == VSCARD_UNDEFINED_READER_ID && vheader->type != VSC_Init) { red_printf("error: reader_id not assigned for message of type %d", vheader->type); } - ASSERT(g_smartcard_channel != NULL); sent_header = spice_memdup(vheader, sizeof(*vheader) + vheader->length); /* We patch the reader_id, since the device only knows about itself, and * we know about the sum of readers. */ sent_header->reader_id = state->reader_id; - smartcard_on_message_from_device(g_smartcard_channel, sent_header); + if (state->rcc) { + smartcard_on_message_from_device(state->rcc, sent_header); + } } static void smartcard_readers_detach_all(SmartCardChannel *smartcard_channel) @@ -152,8 +150,7 @@ static void smartcard_readers_detach_all(SmartCardChannel *smartcard_channel) int i; for (i = 0 ; i < g_smartcard_readers.num; ++i) { - smartcard_char_device_detach(g_smartcard_readers.sin[i], - smartcard_channel); + smartcard_char_device_detach(g_smartcard_readers.sin[i]); } } @@ -204,6 +201,7 @@ static SmartCardDeviceState* smartcard_device_state_new() st->buf = spice_malloc(st->buf_size); st->buf_pos = st->buf; st->buf_used = 0; + st->rcc = NULL; return st; } @@ -235,7 +233,7 @@ int smartcard_device_connect(SpiceCharDeviceInstance *char_device) } static void smartcard_char_device_attach( - SpiceCharDeviceInstance *char_device, SmartCardChannel *smartcard_channel) + SpiceCharDeviceInstance *char_device, RedChannelClient *rcc) { SmartCardDeviceState *st = SPICE_CONTAINEROF(char_device->st, SmartCardDeviceState, base); @@ -243,13 +241,13 @@ static void smartcard_char_device_attach( return; } st->attached = TRUE; + st->rcc = rcc; VSCMsgHeader vheader = {.type = VSC_ReaderAdd, .reader_id=st->reader_id, .length=0}; - smartcard_channel_write_to_reader(smartcard_channel, &vheader); + smartcard_channel_write_to_reader(&vheader); } -static void smartcard_char_device_detach( - SpiceCharDeviceInstance *char_device, SmartCardChannel *smartcard_channel) +static void smartcard_char_device_detach(SpiceCharDeviceInstance *char_device) { SmartCardDeviceState *st = SPICE_CONTAINEROF(char_device->st, SmartCardDeviceState, base); @@ -257,75 +255,75 @@ static void smartcard_char_device_detach( return; } st->attached = FALSE; + st->rcc = NULL; VSCMsgHeader vheader = {.type = VSC_ReaderRemove, .reader_id=st->reader_id, .length=0}; - smartcard_channel_write_to_reader(smartcard_channel, &vheader); + smartcard_channel_write_to_reader(&vheader); } -static int smartcard_channel_config_socket(RedChannel *channel) +static int smartcard_channel_config_socket(RedChannelClient *rcc) { return TRUE; } -static uint8_t *smartcard_channel_alloc_msg_rcv_buf(RedChannel *channel, SpiceDataHeader *msg_header) +static uint8_t *smartcard_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, + 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) +static void smartcard_channel_release_msg_rcv_buf(RedChannelClient *rcc, + SpiceDataHeader *msg_header, uint8_t *msg) { red_printf("freeing %d bytes", msg_header->size); free(msg); } -static void smartcard_channel_send_data(RedChannel *channel, SpiceMarshaller *m, +static void smartcard_channel_send_data(RedChannelClient *rcc, SpiceMarshaller *m, PipeItem *item, VSCMsgHeader *vheader) { - ASSERT(channel); + ASSERT(rcc); ASSERT(vheader); - red_channel_init_send_data(channel, SPICE_MSG_SMARTCARD_DATA, item); - + red_channel_client_init_send_data(rcc, SPICE_MSG_SMARTCARD_DATA, item); spice_marshaller_add_ref(m, (uint8_t*)vheader, sizeof(VSCMsgHeader)); if (vheader->length > 0) { spice_marshaller_add_ref(m, (uint8_t*)(vheader+1), vheader->length); } - red_channel_begin_send_message(channel); + red_channel_client_begin_send_message(rcc); } static void smartcard_channel_send_error( - SmartCardChannel *smartcard_channel, SpiceMarshaller *m, PipeItem *item) + RedChannelClient *rcc, SpiceMarshaller *m, PipeItem *item) { ErrorItem* error_item = (ErrorItem*)item; - smartcard_channel_send_data(&smartcard_channel->base, m, item, &error_item->vheader); + smartcard_channel_send_data(rcc, m, item, &error_item->vheader); } -static void smartcard_channel_send_msg( - SmartCardChannel *smartcard_channel, SpiceMarshaller *m, PipeItem *item) +static void smartcard_channel_send_msg(RedChannelClient *rcc, + SpiceMarshaller *m, PipeItem *item) { MsgItem* msg_item = (MsgItem*)item; - smartcard_channel_send_data(&smartcard_channel->base, m, item, msg_item->vheader); + smartcard_channel_send_data(rcc, m, item, msg_item->vheader); } -static void smartcard_channel_send_item(RedChannel *channel, PipeItem *item) +static void smartcard_channel_send_item(RedChannelClient *rcc, PipeItem *item) { - SmartCardChannel *smartcard_channel = (SmartCardChannel *)channel; - SpiceMarshaller *m = red_channel_get_marshaller(channel); + SpiceMarshaller *m = red_channel_client_get_marshaller(rcc); switch (item->type) { case PIPE_ITEM_TYPE_ERROR: - smartcard_channel_send_error(smartcard_channel, m, item); + smartcard_channel_send_error(rcc, m, item); break; case PIPE_ITEM_TYPE_MSG: - smartcard_channel_send_msg(smartcard_channel, m, item); + smartcard_channel_send_msg(rcc, m, item); } } -static void smartcard_channel_release_pipe_item(RedChannel *channel, PipeItem *item, int item_pushed) +static void smartcard_channel_release_pipe_item(RedChannelClient *rcc, PipeItem *item, int item_pushed) { if (item->type == PIPE_ITEM_TYPE_MSG) { free(((MsgItem*)item)->vheader); @@ -333,22 +331,21 @@ static void smartcard_channel_release_pipe_item(RedChannel *channel, PipeItem *i free(item); } -static void smartcard_channel_disconnect(RedChannel *channel) +static void smartcard_channel_disconnect(RedChannelClient *rcc) { - smartcard_readers_detach_all((SmartCardChannel*)channel); - red_channel_destroy(channel); - g_smartcard_channel = NULL; + smartcard_readers_detach_all((SmartCardChannel*)(rcc->channel)); + red_channel_client_destroy(rcc); } /* this is called from both device input and client input. since the device is * a usb device, the context is still the main thread (kvm_main_loop, timers) * so no mutex is required. */ -static void smartcard_channel_pipe_add_push(SmartCardChannel *channel, PipeItem *item) +static void smartcard_channel_pipe_add_push(RedChannelClient *rcc, PipeItem *item) { - red_channel_pipe_add_push(&channel->base, item); + red_channel_pipe_add_push(rcc->channel, item); } -static void smartcard_push_error(SmartCardChannel* channel, uint32_t reader_id, VSCErrorCode error) +static void smartcard_push_error(RedChannelClient *rcc, uint32_t reader_id, VSCErrorCode error) { ErrorItem *error_item = spice_new0(ErrorItem, 1); @@ -357,63 +354,61 @@ static void smartcard_push_error(SmartCardChannel* channel, uint32_t reader_id, error_item->vheader.type = VSC_Error; error_item->vheader.length = sizeof(error_item->error); error_item->error.code = error; - smartcard_channel_pipe_add_push(channel, &error_item->base); + smartcard_channel_pipe_add_push(rcc, &error_item->base); } -static void smartcard_push_vscmsg(SmartCardChannel *channel, VSCMsgHeader *vheader) +static void smartcard_push_vscmsg(RedChannelClient *rcc, VSCMsgHeader *vheader) { MsgItem *msg_item = spice_new0(MsgItem, 1); msg_item->base.type = PIPE_ITEM_TYPE_MSG; msg_item->vheader = vheader; - smartcard_channel_pipe_add_push(channel, &msg_item->base); + smartcard_channel_pipe_add_push(rcc, &msg_item->base); } -void smartcard_on_message_from_device(SmartCardChannel *smartcard_channel, - VSCMsgHeader* vheader) +void smartcard_on_message_from_device(RedChannelClient *rcc, VSCMsgHeader* vheader) { - smartcard_push_vscmsg(smartcard_channel, vheader); + smartcard_push_vscmsg(rcc, vheader); } -static void smartcard_remove_reader(SmartCardChannel *smartcard_channel, uint32_t reader_id) +static void smartcard_remove_reader(RedChannelClient *rcc, uint32_t reader_id) { SpiceCharDeviceInstance *char_device = smartcard_readers_get(reader_id); SmartCardDeviceState *state; if (char_device == NULL) { - smartcard_push_error(smartcard_channel, reader_id, + smartcard_push_error(rcc, reader_id, VSC_GENERAL_ERROR); return; } state = SPICE_CONTAINEROF(char_device->st, SmartCardDeviceState, base); if (state->attached == FALSE) { - smartcard_push_error(smartcard_channel, reader_id, + smartcard_push_error(rcc, reader_id, VSC_GENERAL_ERROR); return; } - smartcard_char_device_detach(char_device, smartcard_channel); + smartcard_char_device_detach(char_device); } -static void smartcard_add_reader(SmartCardChannel *smartcard_channel, uint8_t *name) +static void smartcard_add_reader(RedChannelClient *rcc, uint8_t *name) { // TODO - save name somewhere SpiceCharDeviceInstance *char_device = smartcard_readers_get_unattached(); if (char_device != NULL) { - smartcard_char_device_attach(char_device, smartcard_channel); + smartcard_char_device_attach(char_device, rcc); // 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. } else { - smartcard_push_error(smartcard_channel, VSCARD_UNDEFINED_READER_ID, + smartcard_push_error(rcc, VSCARD_UNDEFINED_READER_ID, VSC_CANNOT_ADD_MORE_READERS); } } -static void smartcard_channel_write_to_reader( - SmartCardChannel *smartcard_channel, VSCMsgHeader *vheader) +static void smartcard_channel_write_to_reader(VSCMsgHeader *vheader) { SpiceCharDeviceInstance *sin; SpiceCharDeviceInterface *sif; @@ -434,25 +429,25 @@ static void smartcard_channel_write_to_reader( ASSERT(n == actual_length + sizeof(VSCMsgHeader)); } -static int smartcard_channel_handle_message(RedChannel *channel, SpiceDataHeader *header, uint8_t *msg) +static int smartcard_channel_handle_message(RedChannelClient *rcc, + SpiceDataHeader *header, + uint8_t *msg) { VSCMsgHeader* vheader = (VSCMsgHeader*)msg; - SmartCardChannel* smartcard_channel = (SmartCardChannel*)channel; if (header->type != SPICE_MSGC_SMARTCARD_DATA) { /* handle ack's, spicy sends them while spicec does not */ - return red_channel_handle_message(channel, header->size, header->type, - msg); + return red_channel_client_handle_message(rcc, header->size, header->type, msg); } ASSERT(header->size == vheader->length + sizeof(VSCMsgHeader)); switch (vheader->type) { case VSC_ReaderAdd: - smartcard_add_reader(smartcard_channel, msg + sizeof(VSCMsgHeader)); + smartcard_add_reader(rcc, msg + sizeof(VSCMsgHeader)); return TRUE; break; case VSC_ReaderRemove: - smartcard_remove_reader(smartcard_channel, vheader->reader_id); + smartcard_remove_reader(rcc, vheader->reader_id); return TRUE; break; case VSC_Init: @@ -474,11 +469,11 @@ static int smartcard_channel_handle_message(RedChannel *channel, SpiceDataHeader vheader->type, vheader->length); return FALSE; } - smartcard_channel_write_to_reader(smartcard_channel, vheader); + smartcard_channel_write_to_reader(vheader); return TRUE; } -static void smartcard_channel_hold_pipe_item(RedChannel *channel, PipeItem *item) +static void smartcard_channel_hold_pipe_item(RedChannelClient *rcc, PipeItem *item) { } @@ -487,12 +482,13 @@ static void smartcard_link(Channel *channel, RedsStream *stream, uint32_t *common_caps, int num_caps, uint32_t *caps) { - if (g_smartcard_channel) { - red_channel_destroy(&g_smartcard_channel->base); + if (channel->data) { + red_channel_destroy((RedChannel*)channel->data); + channel->data = NULL; } - g_smartcard_channel = - (SmartCardChannel *)red_channel_create(sizeof(*g_smartcard_channel), - stream, core, + if (!channel->data) { + channel->data = red_channel_create(sizeof(SmartCardChannel), + core, migration, FALSE /* handle_acks */, smartcard_channel_config_socket, smartcard_channel_disconnect, @@ -505,10 +501,13 @@ static void smartcard_link(Channel *channel, RedsStream *stream, NULL, NULL, NULL); - if (!g_smartcard_channel) { + } + if (!channel->data) { + red_printf("ERROR: smartcard channel creation failed"); return; } - red_channel_init_outgoing_messages_window(&g_smartcard_channel->base); + red_channel_client_create(sizeof(RedChannelClient), channel->data, stream); + red_channel_init_outgoing_messages_window((RedChannel*)channel->data); } static void smartcard_shutdown(Channel *channel) |