[Spice-devel] [PATCH spice 5/5] Rename usbredir channel code to spicevmc

Hans de Goede hdegoede at redhat.com
Thu Aug 25 03:42:15 PDT 2011


Attached is a better diff, showing the actual changes to the
renamed file.

On 08/25/2011 12:19 PM, Hans de Goede wrote:
> While discussing various things with Alon in Vancouver, it came up that
> having a channel which simply passes through data coming out of a qemu
> chardev frontend unmodified, like the usbredir channel does, can be used
> for a lot of other cases too. To facilitate this the usbredir channel code
> will be turned into a generic spicevmc channel, which is just a passthrough
> to the client, from the spicevmc chardev.
>
> This patch renames usbredir.c to spicevmc.c and changes the prefix of all
> functions / structs to match. This should make clear that the code is not
> usbredir specific.
>
> Some examples of why having a generic spicevmc pass through is good:
> 1) We could add a monitor channel, allowing access to the qemu monitor from
> the spice client, since the monitor is a chardev frontend we could re-use
> the generic spicevmc channel server code, so all that is needed to add this
> (server side) would be reserving a new channel id for this.
>
> 2) We could allow users to come up with new channels of their own, without
> requiring qemu or server modification. The idea is to allow doing something
> like this on the qemu startup cmdline:
> -chardev spicevmc,name=generic,channelid=128
>
> To ensure these new "generic" channels cannot conflict with newly added
> official types, they must start at the SPICE_CHANNEL_USER_DEFINED_START value
> (128).
>
> These new user defined channels could then either be used with a special
> modified client, with client plugins (if we add support for those), or
> by exporting them on the client side for use by an external ap, see below.
>
> 3) We could also add support to the client to make user-defined channels
> end in a unix socket / pipe, allowing handling of the data by an external app,
> we could for example have a new spice client cmdline argument like this:
> --custom-channel unixsocket=/tmp/mysocket,channelid=128
>
> This would allow for something like:
> $random app on guest ->  virtio-serial ->  spicevmc chardev ->
>   ->  spicevmc channel ->  unix socket ->  $random app on client
>
> 4) On hind sight this could also have been used for the smartcard stuff,
> with a 1 channel / reader model, rather then the current multiplexing code
> where we've our own multiplexing protocol wrapper over the libcacard
> smartcard protocol.
>
> Signed-off-by: Hans de Goede<hdegoede at redhat.com>
> ---
>   server/Makefile.am   |    2 +-
>   server/char_device.h |    6 +-
>   server/reds.c        |    6 +-
>   server/spicevmc.c    |  275 +++++++++++++++++++++++++++++++++++++++++++++++++
>   server/usbredir.c    |  276 --------------------------------------------------
>   5 files changed, 281 insertions(+), 284 deletions(-)
>   create mode 100644 server/spicevmc.c
>   delete mode 100644 server/usbredir.c
>
> diff --git a/server/Makefile.am b/server/Makefile.am
> index b9be242..a7cdd84 100644
> --- a/server/Makefile.am
> +++ b/server/Makefile.am
> @@ -95,7 +95,7 @@ libspice_server_la_SOURCES =			\
>   	spice-experimental.h			\
>   	spice.h					\
>   	stat.h					\
> -	usbredir.c				\
> +	spicevmc.c				\
>   	zlib_encoder.c				\
>   	zlib_encoder.h				\
>   	$(NULL)
> diff --git a/server/char_device.h b/server/char_device.h
> index 4b55869..bdb32ae 100644
> --- a/server/char_device.h
> +++ b/server/char_device.h
> @@ -7,8 +7,8 @@ struct SpiceCharDeviceState {
>       void (*wakeup)(SpiceCharDeviceInstance *sin);
>   };
>
> -int usbredir_device_connect(SpiceCharDeviceInstance *char_device);
> -void usbredir_device_disconnect(SpiceCharDeviceInstance *char_device);
> +void spicevmc_device_connect(SpiceCharDeviceInstance *sin,
> +                             uint8_t channel_type);
> +void spicevmc_device_disconnect(SpiceCharDeviceInstance *char_device);
>
>   #endif // __CHAR_DEVICE_H__
> -
> diff --git a/server/reds.c b/server/reds.c
> index d140afd..c58586a 100644
> --- a/server/reds.c
> +++ b/server/reds.c
> @@ -3283,9 +3283,7 @@ static int spice_server_char_device_add_interface(SpiceServer *s,
>       }
>   #endif
>       else if (strcmp(char_device->subtype, SUBTYPE_USBREDIR) == 0) {
> -        if (usbredir_device_connect(char_device) == -1) {
> -            return -1;
> -        }
> +        spicevmc_device_connect(char_device, SPICE_CHANNEL_USBREDIR);
>       }
>       return 0;
>   }
> @@ -3307,7 +3305,7 @@ static void spice_server_char_device_remove_interface(SpiceBaseInstance *sin)
>       }
>   #endif
>       else if (strcmp(char_device->subtype, SUBTYPE_USBREDIR) == 0) {
> -        usbredir_device_disconnect(char_device);
> +        spicevmc_device_disconnect(char_device);
>       }
>   }
>
> diff --git a/server/spicevmc.c b/server/spicevmc.c
> new file mode 100644
> index 0000000..9ccc0d1
> --- /dev/null
> +++ b/server/spicevmc.c
> @@ -0,0 +1,275 @@
> +/* spice-server spicevmc passthrough channel code
> +
> +   Copyright (C) 2011 Red Hat, Inc.
> +
> +   Red Hat Authors:
> +   Hans de Goede<hdegoede at redhat.com>
> +
> +   This library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   This library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with this library; if not, see<http://www.gnu.org/licenses/>.
> +*/
> +#ifdef HAVE_CONFIG_H
> +#include<config.h>
> +#endif
> +
> +#include<assert.h>
> +
> +#include "server/char_device.h"
> +#include "server/red_channel.h"
> +#include "server/reds.h"
> +
> +/* 64K should be enough for all but the largest writes + 32 bytes hdr */
> +#define BUF_SIZE (64 * 1024 + 32)
> +
> +typedef struct SpiceVmcPipeItem {
> +    PipeItem base;
> +    /* writes which don't fit this will get split, this is not a problem */
> +    uint8_t buf[BUF_SIZE];
> +    uint32_t buf_used;
> +} SpiceVmcPipeItem;
> +
> +typedef struct SpiceVmcState {
> +    RedChannel channel; /* Must be the first item */
> +    RedChannelClient *rcc;
> +    SpiceCharDeviceState chardev_st;
> +    SpiceCharDeviceInstance *chardev_sin;
> +    SpiceVmcPipeItem *pipe_item;
> +    uint8_t *rcv_buf;
> +    uint32_t rcv_buf_size;
> +    int rcv_buf_in_use;
> +} SpiceVmcState;
> +
> +static void spicevmc_chardev_wakeup(SpiceCharDeviceInstance *sin)
> +{
> +    SpiceVmcState *state;
> +    SpiceCharDeviceInterface *sif;
> +    int n;
> +
> +    state = SPICE_CONTAINEROF(sin->st, SpiceVmcState, chardev_st);
> +    sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
> +
> +    if (!state->rcc) {
> +        return;
> +    }
> +
> +    do {
> +        if (!state->pipe_item) {
> +            state->pipe_item = spice_malloc(sizeof(SpiceVmcPipeItem));
> +            red_channel_pipe_item_init(&state->channel,
> +&state->pipe_item->base, 0);
> +        }
> +
> +        n = sif->read(sin, state->pipe_item->buf,
> +                      sizeof(state->pipe_item->buf));
> +        if (n>  0) {
> +            state->pipe_item->buf_used = n;
> +            red_channel_client_pipe_add_push(state->rcc,
> +&state->pipe_item->base);
> +            state->pipe_item = NULL;
> +        }
> +    } while (n>  0);
> +}
> +
> +static int spicevmc_red_channel_client_config_socket(RedChannelClient *rcc)
> +{
> +    return TRUE;
> +}
> +
> +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);
> +
> +    red_channel_client_destroy(rcc);
> +    state->rcc = NULL;
> +    if (sif->state) {
> +        sif->state(sin, 0);
> +    }
> +}
> +
> +static int spicevmc_red_channel_client_handle_message(RedChannelClient *rcc,
> +    SpiceDataHeader *header, uint8_t *msg)
> +{
> +    SpiceVmcState *state;
> +    SpiceCharDeviceInstance *sin;
> +    SpiceCharDeviceInterface *sif;
> +
> +    state = SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel);
> +    sin = state->chardev_sin;
> +    sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
> +
> +    if (header->type != SPICE_MSGC_SPICEVMC_DATA) {
> +        return red_channel_client_handle_message(rcc, header->size,
> +                                                 header->type, msg);
> +    }
> +
> +    /*
> +     * qemu spicevmc will consume everything we give it, no need for
> +     * flow control checks (or to use a pipe).
> +     */
> +    sif->write(sin, msg, header->size);
> +
> +    return TRUE;
> +}
> +
> +static uint8_t *spicevmc_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
> +    SpiceDataHeader *msg_header)
> +{
> +    SpiceVmcState *state;
> +
> +    state = SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel);
> +
> +    assert(!state->rcv_buf_in_use);
> +
> +    if (msg_header->size>  state->rcv_buf_size) {
> +        state->rcv_buf = spice_realloc(state->rcv_buf, msg_header->size);
> +        state->rcv_buf_size = msg_header->size;
> +    }
> +
> +    state->rcv_buf_in_use = 1;
> +
> +    return state->rcv_buf;
> +}
> +
> +static void spicevmc_red_channel_release_msg_rcv_buf(RedChannelClient *rcc,
> +    SpiceDataHeader *msg_header, uint8_t *msg)
> +{
> +    SpiceVmcState *state;
> +
> +    state = SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel);
> +
> +    /* NOOP, we re-use the buffer every time and only free it on destruction */
> +    state->rcv_buf_in_use = 0;
> +}
> +
> +static void spicevmc_red_channel_hold_pipe_item(RedChannelClient *rcc,
> +    PipeItem *item)
> +{
> +    /* NOOP */
> +}
> +
> +static void spicevmc_red_channel_send_item(RedChannelClient *rcc,
> +    PipeItem *item)
> +{
> +    SpiceVmcPipeItem *i = SPICE_CONTAINEROF(item, SpiceVmcPipeItem, base);
> +    SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
> +
> +    red_channel_client_init_send_data(rcc, SPICE_MSG_SPICEVMC_DATA, item);
> +    spice_marshaller_add_ref(m, i->buf, i->buf_used);
> +    red_channel_client_begin_send_message(rcc);
> +}
> +
> +static void spicevmc_red_channel_release_pipe_item(RedChannelClient *rcc,
> +    PipeItem *item, int item_pushed)
> +{
> +    free(item);
> +}
> +
> +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) {
> +        WARN("channel client %d:%d (%p) already connected, refusing second connection\n",
> +             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);
> +    if (!rcc) {
> +        return;
> +    }
> +    state->rcc = rcc;
> +    red_channel_client_ack_zero_messages_window(rcc);
> +
> +    if (sif->state) {
> +        sif->state(sin, 1);
> +    }
> +}
> +
> +static void spicevmc_migrate(RedChannelClient *rcc)
> +{
> +    /* NOOP */
> +}
> +
> +void spicevmc_device_connect(SpiceCharDeviceInstance *sin,
> +    uint8_t channel_type)
> +{
> +    static uint8_t id[256] = { 0, };
> +    SpiceVmcState *state;
> +    ChannelCbs channel_cbs = {0,};
> +    ClientCbs client_cbs = {0,};
> +
> +    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;
> +
> +    state = (SpiceVmcState*)red_channel_create(sizeof(SpiceVmcState),
> +                                   core, channel_type, id[channel_type]++,
> +                                   FALSE /* migration - TODO? */,
> +                                   FALSE /* handle_acks */,
> +                                   spicevmc_red_channel_client_handle_message,
> +&channel_cbs);
> +    red_channel_init_outgoing_messages_window(&state->channel);
> +    state->chardev_st.wakeup = spicevmc_chardev_wakeup;
> +    state->chardev_sin = sin;
> +    state->rcv_buf = spice_malloc(BUF_SIZE);
> +    state->rcv_buf_size = BUF_SIZE;
> +
> +    client_cbs.connect = spicevmc_connect;
> +    client_cbs.migrate = spicevmc_migrate;
> +    red_channel_register_client_cbs(&state->channel,&client_cbs);
> +
> +    sin->st =&state->chardev_st;
> +
> +    reds_register_channel(&state->channel);
> +}
> +
> +/* Must be called from RedClient handling thread. */
> +void spicevmc_device_disconnect(SpiceCharDeviceInstance *sin)
> +{
> +    SpiceVmcState *state;
> +
> +    state = SPICE_CONTAINEROF(sin->st, SpiceVmcState, chardev_st);
> +
> +    reds_unregister_channel(&state->channel);
> +
> +    free(state->pipe_item);
> +    free(state->rcv_buf);
> +    red_channel_destroy(&state->channel);
> +}
> diff --git a/server/usbredir.c b/server/usbredir.c
> deleted file mode 100644
> index 7860389..0000000
> --- a/server/usbredir.c
> +++ /dev/null
> @@ -1,276 +0,0 @@
> -/* spice-server usbredir code
> -
> -   Copyright (C) 2011 Red Hat, Inc.
> -
> -   Red Hat Authors:
> -   Hans de Goede<hdegoede at redhat.com>
> -
> -   This library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   This library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with this library; if not, see<http://www.gnu.org/licenses/>.
> -*/
> -#ifdef HAVE_CONFIG_H
> -#include<config.h>
> -#endif
> -
> -#include<assert.h>
> -
> -#include "server/char_device.h"
> -#include "server/red_channel.h"
> -#include "server/reds.h"
> -
> -/* 64K should be enough for all but the largest bulk xfers + 32 bytes hdr */
> -#define BUF_SIZE (64 * 1024 + 32)
> -
> -typedef struct UsbRedirPipeItem {
> -    PipeItem base;
> -    /* packets which don't fit this will get split, this is not a problem */
> -    uint8_t buf[BUF_SIZE];
> -    uint32_t buf_used;
> -} UsbRedirPipeItem;
> -
> -typedef struct UsbRedirState {
> -    RedChannel channel; /* Must be the first item */
> -    RedChannelClient *rcc;
> -    SpiceCharDeviceState chardev_st;
> -    SpiceCharDeviceInstance *chardev_sin;
> -    UsbRedirPipeItem *pipe_item;
> -    uint8_t *rcv_buf;
> -    uint32_t rcv_buf_size;
> -    int rcv_buf_in_use;
> -} UsbRedirState;
> -
> -static void usbredir_chardev_wakeup(SpiceCharDeviceInstance *sin)
> -{
> -    UsbRedirState *state;
> -    SpiceCharDeviceInterface *sif;
> -    int n;
> -
> -    state = SPICE_CONTAINEROF(sin->st, UsbRedirState, chardev_st);
> -    sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
> -
> -    if (!state->rcc) {
> -        return;
> -    }
> -
> -    do {
> -        if (!state->pipe_item) {
> -            state->pipe_item = spice_malloc(sizeof(UsbRedirPipeItem));
> -            red_channel_pipe_item_init(&state->channel,
> -&state->pipe_item->base, 0);
> -        }
> -
> -        n = sif->read(sin, state->pipe_item->buf,
> -                      sizeof(state->pipe_item->buf));
> -        if (n>  0) {
> -            state->pipe_item->buf_used = n;
> -            red_channel_client_pipe_add_push(state->rcc,
> -&state->pipe_item->base);
> -            state->pipe_item = NULL;
> -        }
> -    } while (n>  0);
> -}
> -
> -static int usbredir_red_channel_client_config_socket(RedChannelClient *rcc)
> -{
> -    return TRUE;
> -}
> -
> -static void usbredir_red_channel_client_on_disconnect(RedChannelClient *rcc)
> -{
> -    UsbRedirState *state;
> -    SpiceCharDeviceInstance *sin;
> -    SpiceCharDeviceInterface *sif;
> -
> -    if (!rcc) {
> -        return;
> -    }
> -
> -    state = SPICE_CONTAINEROF(rcc->channel, UsbRedirState, channel);
> -    sin = state->chardev_sin;
> -    sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
> -
> -    red_channel_client_destroy(rcc);
> -    state->rcc = NULL;
> -    if (sif->state) {
> -        sif->state(sin, 0);
> -    }
> -}
> -
> -static int usbredir_red_channel_client_handle_message(RedChannelClient *rcc,
> -    SpiceDataHeader *header, uint8_t *msg)
> -{
> -    UsbRedirState *state;
> -    SpiceCharDeviceInstance *sin;
> -    SpiceCharDeviceInterface *sif;
> -
> -    state = SPICE_CONTAINEROF(rcc->channel, UsbRedirState, channel);
> -    sin = state->chardev_sin;
> -    sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
> -
> -    if (header->type != SPICE_MSGC_USBREDIR_DATA) {
> -        return red_channel_client_handle_message(rcc, header->size,
> -                                                 header->type, msg);
> -    }
> -
> -    /*
> -     * qemu usbredir will consume everything we give it, no need for
> -     * flow control checks (or to use a pipe).
> -     */
> -    sif->write(sin, msg, header->size);
> -
> -    return TRUE;
> -}
> -
> -static uint8_t *usbredir_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
> -    SpiceDataHeader *msg_header)
> -{
> -    UsbRedirState *state;
> -
> -    state = SPICE_CONTAINEROF(rcc->channel, UsbRedirState, channel);
> -
> -    assert(!state->rcv_buf_in_use);
> -
> -    if (msg_header->size>  state->rcv_buf_size) {
> -        state->rcv_buf = spice_realloc(state->rcv_buf, msg_header->size);
> -        state->rcv_buf_size = msg_header->size;
> -    }
> -
> -    state->rcv_buf_in_use = 1;
> -
> -    return state->rcv_buf;
> -}
> -
> -static void usbredir_red_channel_release_msg_rcv_buf(RedChannelClient *rcc,
> -    SpiceDataHeader *msg_header, uint8_t *msg)
> -{
> -    UsbRedirState *state;
> -
> -    state = SPICE_CONTAINEROF(rcc->channel, UsbRedirState, channel);
> -
> -    /* NOOP, we re-use the buffer every time and only free it on destruction */
> -    state->rcv_buf_in_use = 0;
> -}
> -
> -static void usbredir_red_channel_hold_pipe_item(RedChannelClient *rcc,
> -    PipeItem *item)
> -{
> -    /* NOOP */
> -}
> -
> -static void usbredir_red_channel_send_item(RedChannelClient *rcc,
> -    PipeItem *item)
> -{
> -    UsbRedirPipeItem *i = SPICE_CONTAINEROF(item, UsbRedirPipeItem, base);
> -    SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
> -
> -    red_channel_client_init_send_data(rcc, SPICE_MSG_USBREDIR_DATA, item);
> -    spice_marshaller_add_ref(m, i->buf, i->buf_used);
> -    red_channel_client_begin_send_message(rcc);
> -}
> -
> -static void usbredir_red_channel_release_pipe_item(RedChannelClient *rcc,
> -    PipeItem *item, int item_pushed)
> -{
> -    free(item);
> -}
> -
> -static void usbredir_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;
> -    UsbRedirState *state;
> -    SpiceCharDeviceInstance *sin;
> -    SpiceCharDeviceInterface *sif;
> -
> -    state = SPICE_CONTAINEROF(channel, UsbRedirState, channel);
> -    sin = state->chardev_sin;
> -    sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
> -
> -    if (state->rcc) {
> -        WARN("channel client %d:%d (%p) already connected, refusing second connection\n",
> -             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);
> -    if (!rcc) {
> -        return;
> -    }
> -    state->rcc = rcc;
> -    red_channel_client_ack_zero_messages_window(rcc);
> -
> -    if (sif->state) {
> -        sif->state(sin, 1);
> -    }
> -}
> -
> -static void usbredir_migrate(RedChannelClient *rcc)
> -{
> -    /* NOOP */
> -}
> -
> -int usbredir_device_connect(SpiceCharDeviceInstance *sin)
> -{
> -    static int id = 0;
> -    UsbRedirState *state;
> -    ChannelCbs channel_cbs = {0,};
> -    ClientCbs client_cbs = {0,};
> -
> -    channel_cbs.config_socket = usbredir_red_channel_client_config_socket;
> -    channel_cbs.on_disconnect = usbredir_red_channel_client_on_disconnect;
> -    channel_cbs.send_item = usbredir_red_channel_send_item;
> -    channel_cbs.hold_item = usbredir_red_channel_hold_pipe_item;
> -    channel_cbs.release_item = usbredir_red_channel_release_pipe_item;
> -    channel_cbs.alloc_recv_buf = usbredir_red_channel_alloc_msg_rcv_buf;
> -    channel_cbs.release_recv_buf = usbredir_red_channel_release_msg_rcv_buf;
> -
> -    state = (UsbRedirState*)red_channel_create(sizeof(UsbRedirState),
> -                                   core, SPICE_CHANNEL_USBREDIR, id++,
> -                                   FALSE /* migration - TODO? */,
> -                                   FALSE /* handle_acks */,
> -                                   usbredir_red_channel_client_handle_message,
> -&channel_cbs);
> -    red_channel_init_outgoing_messages_window(&state->channel);
> -    state->chardev_st.wakeup = usbredir_chardev_wakeup;
> -    state->chardev_sin = sin;
> -    state->rcv_buf = spice_malloc(BUF_SIZE);
> -    state->rcv_buf_size = BUF_SIZE;
> -
> -    client_cbs.connect = usbredir_connect;
> -    client_cbs.migrate = usbredir_migrate;
> -    red_channel_register_client_cbs(&state->channel,&client_cbs);
> -
> -    sin->st =&state->chardev_st;
> -
> -    reds_register_channel(&state->channel);
> -
> -    return 0;
> -}
> -
> -/* Must be called from RedClient handling thread. */
> -void usbredir_device_disconnect(SpiceCharDeviceInstance *sin)
> -{
> -    UsbRedirState *state;
> -
> -    state = SPICE_CONTAINEROF(sin->st, UsbRedirState, chardev_st);
> -
> -    reds_unregister_channel(&state->channel);
> -
> -    free(state->pipe_item);
> -    free(state->rcv_buf);
> -    red_channel_destroy(&state->channel);
> -}
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: 0001-Rename-usbredir-channel-code-to-spicevmc.patch
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20110825/2c989c64/attachment.asc>


More information about the Spice-devel mailing list