summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2011-08-25 12:16:06 +0200
committerHans de Goede <hdegoede@redhat.com>2011-08-25 14:04:27 +0200
commitc030382abbd14c3ae09db030719e52efa8600f15 (patch)
treee870a2c9670121f632e5725fc0f7d5382423124e /server
parent073cf20ac57b9e035f247f180a109f29333dacb8 (diff)
downloadspice-c030382abbd14c3ae09db030719e52efa8600f15.tar.gz
spice-c030382abbd14c3ae09db030719e52efa8600f15.tar.xz
spice-c030382abbd14c3ae09db030719e52efa8600f15.zip
Rename usbredir channel code to spicevmc
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@redhat.com>
Diffstat (limited to 'server')
-rw-r--r--server/Makefile.am2
-rw-r--r--server/char_device.h6
-rw-r--r--server/reds.c6
-rw-r--r--server/spicevmc.c (renamed from server/usbredir.c)113
4 files changed, 62 insertions, 65 deletions
diff --git a/server/Makefile.am b/server/Makefile.am
index b9be242a..a7cdd840 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 4b558698..bdb32ae9 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 d140afd4..c58586a7 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/usbredir.c b/server/spicevmc.c
index 7860389a..9ccc0d17 100644
--- a/server/usbredir.c
+++ b/server/spicevmc.c
@@ -1,4 +1,4 @@
-/* spice-server usbredir code
+/* spice-server spicevmc passthrough channel code
Copyright (C) 2011 Red Hat, Inc.
@@ -28,34 +28,34 @@
#include "server/red_channel.h"
#include "server/reds.h"
-/* 64K should be enough for all but the largest bulk xfers + 32 bytes hdr */
+/* 64K should be enough for all but the largest writes + 32 bytes hdr */
#define BUF_SIZE (64 * 1024 + 32)
-typedef struct UsbRedirPipeItem {
+typedef struct SpiceVmcPipeItem {
PipeItem base;
- /* packets which don't fit this will get split, this is not a problem */
+ /* writes which don't fit this will get split, this is not a problem */
uint8_t buf[BUF_SIZE];
uint32_t buf_used;
-} UsbRedirPipeItem;
+} SpiceVmcPipeItem;
-typedef struct UsbRedirState {
+typedef struct SpiceVmcState {
RedChannel channel; /* Must be the first item */
RedChannelClient *rcc;
SpiceCharDeviceState chardev_st;
SpiceCharDeviceInstance *chardev_sin;
- UsbRedirPipeItem *pipe_item;
+ SpiceVmcPipeItem *pipe_item;
uint8_t *rcv_buf;
uint32_t rcv_buf_size;
int rcv_buf_in_use;
-} UsbRedirState;
+} SpiceVmcState;
-static void usbredir_chardev_wakeup(SpiceCharDeviceInstance *sin)
+static void spicevmc_chardev_wakeup(SpiceCharDeviceInstance *sin)
{
- UsbRedirState *state;
+ SpiceVmcState *state;
SpiceCharDeviceInterface *sif;
int n;
- state = SPICE_CONTAINEROF(sin->st, UsbRedirState, chardev_st);
+ state = SPICE_CONTAINEROF(sin->st, SpiceVmcState, chardev_st);
sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
if (!state->rcc) {
@@ -64,7 +64,7 @@ static void usbredir_chardev_wakeup(SpiceCharDeviceInstance *sin)
do {
if (!state->pipe_item) {
- state->pipe_item = spice_malloc(sizeof(UsbRedirPipeItem));
+ state->pipe_item = spice_malloc(sizeof(SpiceVmcPipeItem));
red_channel_pipe_item_init(&state->channel,
&state->pipe_item->base, 0);
}
@@ -80,14 +80,14 @@ static void usbredir_chardev_wakeup(SpiceCharDeviceInstance *sin)
} while (n > 0);
}
-static int usbredir_red_channel_client_config_socket(RedChannelClient *rcc)
+static int spicevmc_red_channel_client_config_socket(RedChannelClient *rcc)
{
return TRUE;
}
-static void usbredir_red_channel_client_on_disconnect(RedChannelClient *rcc)
+static void spicevmc_red_channel_client_on_disconnect(RedChannelClient *rcc)
{
- UsbRedirState *state;
+ SpiceVmcState *state;
SpiceCharDeviceInstance *sin;
SpiceCharDeviceInterface *sif;
@@ -95,7 +95,7 @@ static void usbredir_red_channel_client_on_disconnect(RedChannelClient *rcc)
return;
}
- state = SPICE_CONTAINEROF(rcc->channel, UsbRedirState, channel);
+ state = SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel);
sin = state->chardev_sin;
sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
@@ -106,24 +106,24 @@ static void usbredir_red_channel_client_on_disconnect(RedChannelClient *rcc)
}
}
-static int usbredir_red_channel_client_handle_message(RedChannelClient *rcc,
+static int spicevmc_red_channel_client_handle_message(RedChannelClient *rcc,
SpiceDataHeader *header, uint8_t *msg)
{
- UsbRedirState *state;
+ SpiceVmcState *state;
SpiceCharDeviceInstance *sin;
SpiceCharDeviceInterface *sif;
- state = SPICE_CONTAINEROF(rcc->channel, UsbRedirState, channel);
+ state = SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel);
sin = state->chardev_sin;
sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
- if (header->type != SPICE_MSGC_USBREDIR_DATA) {
+ if (header->type != SPICE_MSGC_SPICEVMC_DATA) {
return red_channel_client_handle_message(rcc, header->size,
header->type, msg);
}
/*
- * qemu usbredir will consume everything we give it, no need for
+ * 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);
@@ -131,12 +131,12 @@ static int usbredir_red_channel_client_handle_message(RedChannelClient *rcc,
return TRUE;
}
-static uint8_t *usbredir_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
+static uint8_t *spicevmc_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
SpiceDataHeader *msg_header)
{
- UsbRedirState *state;
+ SpiceVmcState *state;
- state = SPICE_CONTAINEROF(rcc->channel, UsbRedirState, channel);
+ state = SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel);
assert(!state->rcv_buf_in_use);
@@ -150,50 +150,50 @@ static uint8_t *usbredir_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
return state->rcv_buf;
}
-static void usbredir_red_channel_release_msg_rcv_buf(RedChannelClient *rcc,
+static void spicevmc_red_channel_release_msg_rcv_buf(RedChannelClient *rcc,
SpiceDataHeader *msg_header, uint8_t *msg)
{
- UsbRedirState *state;
+ SpiceVmcState *state;
- state = SPICE_CONTAINEROF(rcc->channel, UsbRedirState, channel);
+ 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 usbredir_red_channel_hold_pipe_item(RedChannelClient *rcc,
+static void spicevmc_red_channel_hold_pipe_item(RedChannelClient *rcc,
PipeItem *item)
{
/* NOOP */
}
-static void usbredir_red_channel_send_item(RedChannelClient *rcc,
+static void spicevmc_red_channel_send_item(RedChannelClient *rcc,
PipeItem *item)
{
- UsbRedirPipeItem *i = SPICE_CONTAINEROF(item, UsbRedirPipeItem, base);
+ SpiceVmcPipeItem *i = SPICE_CONTAINEROF(item, SpiceVmcPipeItem, base);
SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
- red_channel_client_init_send_data(rcc, SPICE_MSG_USBREDIR_DATA, item);
+ 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 usbredir_red_channel_release_pipe_item(RedChannelClient *rcc,
+static void spicevmc_red_channel_release_pipe_item(RedChannelClient *rcc,
PipeItem *item, int item_pushed)
{
free(item);
}
-static void usbredir_connect(RedChannel *channel, RedClient *client,
+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;
- UsbRedirState *state;
+ SpiceVmcState *state;
SpiceCharDeviceInstance *sin;
SpiceCharDeviceInterface *sif;
- state = SPICE_CONTAINEROF(channel, UsbRedirState, channel);
+ state = SPICE_CONTAINEROF(channel, SpiceVmcState, channel);
sin = state->chardev_sin;
sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
@@ -218,55 +218,54 @@ static void usbredir_connect(RedChannel *channel, RedClient *client,
}
}
-static void usbredir_migrate(RedChannelClient *rcc)
+static void spicevmc_migrate(RedChannelClient *rcc)
{
/* NOOP */
}
-int usbredir_device_connect(SpiceCharDeviceInstance *sin)
+void spicevmc_device_connect(SpiceCharDeviceInstance *sin,
+ uint8_t channel_type)
{
- static int id = 0;
- UsbRedirState *state;
+ static uint8_t id[256] = { 0, };
+ SpiceVmcState *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;
+ 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 = (UsbRedirState*)red_channel_create(sizeof(UsbRedirState),
- core, SPICE_CHANNEL_USBREDIR, id++,
+ state = (SpiceVmcState*)red_channel_create(sizeof(SpiceVmcState),
+ core, channel_type, id[channel_type]++,
FALSE /* migration - TODO? */,
FALSE /* handle_acks */,
- usbredir_red_channel_client_handle_message,
+ spicevmc_red_channel_client_handle_message,
&channel_cbs);
red_channel_init_outgoing_messages_window(&state->channel);
- state->chardev_st.wakeup = usbredir_chardev_wakeup;
+ 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 = usbredir_connect;
- client_cbs.migrate = usbredir_migrate;
+ 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);
-
- return 0;
}
/* Must be called from RedClient handling thread. */
-void usbredir_device_disconnect(SpiceCharDeviceInstance *sin)
+void spicevmc_device_disconnect(SpiceCharDeviceInstance *sin)
{
- UsbRedirState *state;
+ SpiceVmcState *state;
- state = SPICE_CONTAINEROF(sin->st, UsbRedirState, chardev_st);
+ state = SPICE_CONTAINEROF(sin->st, SpiceVmcState, chardev_st);
reds_unregister_channel(&state->channel);