[Spice-devel] [PATCH spice-gtk] usbredir: Add support for filtering out devices from auto-redirection
Marc-André Lureau
marcandre.lureau at gmail.com
Sun Jan 15 11:08:14 PST 2012
ack
On Thu, Jan 12, 2012 at 3:32 PM, Hans de Goede <hdegoede at redhat.com> wrote:
> Note this patch adds a default filter filtering out HID devices, since
> redirecting ie a mouse plugged into a laptop is usually not what the user
> wants. Also sometimes usb keyboards/mice may experience a glitch causing
> them to temporarily drop of the bus. If this happens when the spice-client
> has focussed it used to redirect them to the vm when they re-appeared,
> not good!
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
> configure.ac | 2 +-
> gtk/spice-option.c | 9 ++++++
> gtk/usb-device-manager.c | 67 +++++++++++++++++++++++++++++++++++++++++++++-
> 3 files changed, 76 insertions(+), 2 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 5788532..766564c 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -330,7 +330,7 @@ if test "x$enable_usbredir" = "xno"; then
> else
> PKG_CHECK_MODULES(GUDEV, gudev-1.0)
> PKG_CHECK_MODULES(LIBUSB, libusb-1.0 >= 1.0.9)
> - PKG_CHECK_MODULES(LIBUSBREDIRHOST, libusbredirhost >= 0.3.2)
> + PKG_CHECK_MODULES(LIBUSBREDIRHOST, libusbredirhost >= 0.3.3)
> AC_DEFINE(USE_USBREDIR, [1], [Define if supporting usbredir proxying])
> AM_CONDITIONAL(WITH_USBREDIR, true)
> if test "x$enable_polkit" = "xno"; then
> diff --git a/gtk/spice-option.c b/gtk/spice-option.c
> index 9819543..394a07d 100644
> --- a/gtk/spice-option.c
> +++ b/gtk/spice-option.c
> @@ -24,6 +24,7 @@
> #include <glib/gi18n.h>
> #include "spice-session.h"
> #include "spice-util.h"
> +#include "usb-device-manager.h"
>
> static gchar *disable_effects = NULL;
> static gint color_depth = 0;
> @@ -31,6 +32,7 @@ static char *ca_file = NULL;
> static char *host_subject = NULL;
> static char *smartcard_db = NULL;
> static char *smartcard_certificates = NULL;
> +static char *usbredir_filter = NULL;
> static gboolean smartcard = FALSE;
> static gboolean disable_audio = FALSE;
> static gboolean disable_usbredir = FALSE;
> @@ -75,6 +77,8 @@ GOptionGroup* spice_get_option_group(void)
> N_("Path to the local certificate database to use for software smartcard certificates"), N_("<certificate-db>") },
> { "spice-disable-usbredir", '\0', 0, G_OPTION_ARG_NONE, &disable_usbredir,
> N_("Disable USB redirection support"), NULL },
> + { "spice-usbredir-filter", '\0', 0, G_OPTION_ARG_STRING, &usbredir_filter,
> + N_("Filter for excluding USB devices from auto redirection"), N_("<filter-string>") },
>
> { "spice-debug", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, option_debug,
> N_("Enable Spice-GTK debugging"), NULL },
> @@ -133,6 +137,11 @@ void spice_set_session_option(SpiceSession *session)
> if (smartcard_db)
> g_object_set(session, "smartcard-db", smartcard_db, NULL);
> }
> + if (usbredir_filter) {
> + SpiceUsbDeviceManager *m = spice_usb_device_manager_get(session, NULL);
> + if (m)
> + g_object_set(m, "auto-connect-filter", usbredir_filter, NULL);
> + }
> if (disable_usbredir)
> g_object_set(session, "enable-usbredir", FALSE, NULL);
> if (disable_audio)
> diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
> index fde353c..2a3b753 100644
> --- a/gtk/usb-device-manager.c
> +++ b/gtk/usb-device-manager.c
> @@ -33,9 +33,11 @@
> #include <sys/types.h>
> #include <sys/stat.h>
> #endif
> +#include <errno.h>
> #include <libusb.h>
> #include <gudev/gudev.h>
> #include "channel-usbredir-priv.h"
> +#include "usbredirhost.h"
> #endif
>
> #include "spice-session-priv.h"
> @@ -80,6 +82,7 @@ enum {
> PROP_0,
> PROP_SESSION,
> PROP_AUTO_CONNECT,
> + PROP_AUTO_CONNECT_FILTER,
> };
>
> enum
> @@ -93,6 +96,7 @@ enum
> struct _SpiceUsbDeviceManagerPrivate {
> SpiceSession *session;
> gboolean auto_connect;
> + gchar *auto_connect_filter;
> #ifdef USE_USBREDIR
> libusb_context *context;
> GUdevClient *udev;
> @@ -100,6 +104,8 @@ struct _SpiceUsbDeviceManagerPrivate {
> GThread *event_thread;
> gboolean event_thread_run;
> libusb_device **coldplug_list; /* Avoid needless reprobing during init */
> + struct usbredirfilter_rule *auto_conn_filter_rules;
> + int auto_conn_filter_rules_count;
> #endif
> GPtrArray *devices;
> GPtrArray *channels;
> @@ -257,6 +263,9 @@ static void spice_usb_device_manager_get_property(GObject *gobject,
> case PROP_AUTO_CONNECT:
> g_value_set_boolean(value, priv->auto_connect);
> break;
> + case PROP_AUTO_CONNECT_FILTER:
> + g_value_set_string(value, priv->auto_connect_filter);
> + break;
> default:
> G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
> break;
> @@ -278,6 +287,28 @@ static void spice_usb_device_manager_set_property(GObject *gobject,
> case PROP_AUTO_CONNECT:
> priv->auto_connect = g_value_get_boolean(value);
> break;
> + case PROP_AUTO_CONNECT_FILTER: {
> + const gchar *filter = g_value_get_string(value);
> +#ifdef USE_USBREDIR
> + struct usbredirfilter_rule *rules;
> + int r, count;
> +
> + r = usbredirfilter_string_to_rules(filter, ",", "|", &rules, &count);
> + if (r) {
> + if (r == -ENOMEM)
> + g_error("Failed to allocate memory for auto-connect-filter");
> + g_warning("Error parsing auto-connect-filter string, keeping old filter\n");
> + break;
> + }
> +
> + free(priv->auto_conn_filter_rules);
> + priv->auto_conn_filter_rules = rules;
> + priv->auto_conn_filter_rules_count = count;
> +#endif
> + g_free(priv->auto_connect_filter);
> + priv->auto_connect_filter = g_strdup(filter);
> + break;
> + }
> default:
> G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
> break;
> @@ -318,6 +349,36 @@ static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas
> g_object_class_install_property(gobject_class, PROP_AUTO_CONNECT, pspec);
>
> /**
> + * SpiceUsbDeviceManager:auto-connect-filter:
> + *
> + * Set a string specifying a filter to use to determine which USB devices
> + * to autoconnect when plugged in, a filter consists of one or more rules.
> + * Where each rule has the form of:
> + *
> + * @class, at vendor, at product, at version, at allow
> + *
> + * Use -1 for @class/@vendor/@product/@version to accept any value.
> + *
> + * And the rules are themselves are concatonated like this:
> + *
> + * @rule1|@rule2|@rule3
> + *
> + * The default setting filters out HID (class 0x03) USB devices from auto
> + * connect and auto connects anything else. Note the explicit allow rule at
> + * the end, this is necessary since by default all devices without a
> + * matching filter rule will not auto-connect.
> + *
> + * Filter strings in this format can be easily created with the RHEV-M
> + * USB filter editor tool.
> + */
> + pspec = g_param_spec_string("auto-connect-filter", "Auto Connect Filter ",
> + "Filter determining which USB devices to auto connect",
> + "0x03,-1,-1,-1,0|-1,-1,-1,-1,1",
> + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
> + g_object_class_install_property(gobject_class, PROP_AUTO_CONNECT_FILTER,
> + pspec);
> +
> + /**
> * SpiceUsbDeviceManager::device-added:
> * @manager: the #SpiceUsbDeviceManager that emitted the signal
> * @device: #SpiceUsbDevice boxed object corresponding to the added device
> @@ -555,7 +616,11 @@ static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager *self,
> g_ptr_array_add(priv->devices, device);
>
> if (priv->auto_connect) {
> - spice_usb_device_manager_connect_device_async(self,
> + if (usbredirhost_check_device_filter(
> + priv->auto_conn_filter_rules,
> + priv->auto_conn_filter_rules_count,
> + device, 0) == 0)
> + spice_usb_device_manager_connect_device_async(self,
> (SpiceUsbDevice *)device, NULL,
> spice_usb_device_manager_auto_connect_cb,
> libusb_ref_device(device));
> --
> 1.7.7.4
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
--
Marc-André Lureau
More information about the Spice-devel
mailing list