summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2015-11-08 20:33:16 +0000
committerRichard Hughes <richard@hughsie.com>2015-11-08 20:33:16 +0000
commitd01f88d16addbc1bec3f7372e8c90f4fc849cb77 (patch)
treeb02b5d1f430baf4a36ebdbfd32c9fb84285f8a75
parent19e69a86ef611f5481541a85ab21925b114b69dd (diff)
downloadgusb-wip/hughsie/dfu.tar.gz
-rw-r--r--gusb/Makefile.am3
-rw-r--r--gusb/gusb-autocleanups.h1
-rw-r--r--gusb/gusb-device.c106
-rw-r--r--gusb/gusb-device.h11
-rw-r--r--gusb/gusb-interface-private.h34
-rw-r--r--gusb/gusb-interface.c247
-rw-r--r--gusb/gusb-interface.h68
-rw-r--r--gusb/gusb.h1
8 files changed, 439 insertions, 32 deletions
diff --git a/gusb/Makefile.am b/gusb/Makefile.am
index 5c45ac5..4307b7c 100644
--- a/gusb/Makefile.am
+++ b/gusb/Makefile.am
@@ -27,6 +27,8 @@ libgusbbase_include_HEADERS = \
gusb-device.h \
gusb-device-private.h \
gusb-device-list.h \
+ gusb-interface.h \
+ gusb-interface-private.h \
gusb-source.h \
gusb-util.h
@@ -34,6 +36,7 @@ libgusb_la_SOURCES = \
gusb-context.c \
gusb-device.c \
gusb-device-list.c \
+ gusb-interface.c \
gusb-source.c \
gusb-util.c
diff --git a/gusb/gusb-autocleanups.h b/gusb/gusb-autocleanups.h
index 0adf613..ce7dc45 100644
--- a/gusb/gusb-autocleanups.h
+++ b/gusb/gusb-autocleanups.h
@@ -29,6 +29,7 @@
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUsbContext, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUsbDevice, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUsbInterface, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUsbDeviceList, g_object_unref)
#endif
diff --git a/gusb/gusb-device.c b/gusb/gusb-device.c
index 1ef6572..11a5d98 100644
--- a/gusb/gusb-device.c
+++ b/gusb/gusb-device.c
@@ -38,6 +38,7 @@
#include "gusb-util.h"
#include "gusb-device.h"
#include "gusb-device-private.h"
+#include "gusb-interface-private.h"
/**
* GUsbDevicePrivate:
@@ -490,11 +491,11 @@ g_usb_device_get_custom_index (GUsbDevice *device,
*
* Gets the interface number from the vendor class interface descriptor.
*
- * Return value: an interface number, or 0xff for failure
+ * Return value: (transfer full): a #GUsbInterface or %NULL for not found
*
- * Since: 0.2.5
+ * Since: 0.2.8
**/
-guint8
+GUsbInterface *
g_usb_device_get_interface (GUsbDevice *device,
guint8 class_id,
guint8 subclass_id,
@@ -503,7 +504,7 @@ g_usb_device_get_interface (GUsbDevice *device,
{
const struct libusb_interface_descriptor *ifp;
gint rc;
- guint8 iface_num = 0xff;
+ GUsbInterface *interface = NULL;
guint i;
struct libusb_config_descriptor *config;
@@ -520,12 +521,12 @@ g_usb_device_get_interface (GUsbDevice *device,
continue;
if (ifp->bInterfaceProtocol != protocol_id)
continue;
- iface_num = ifp->bInterfaceNumber;
+ interface = _g_usb_interface_new (ifp);
break;
}
/* nothing matched */
- if (iface_num == 0xff) {
+ if (interface == NULL) {
g_set_error (error,
G_USB_DEVICE_ERROR,
G_USB_DEVICE_ERROR_NOT_SUPPORTED,
@@ -535,53 +536,48 @@ g_usb_device_get_interface (GUsbDevice *device,
}
libusb_free_config_descriptor (config);
- return iface_num;
+ return interface;
}
/**
- * g_usb_device_get_interface:
+ * g_usb_device_get_interfaces:
* @device: a #GUsbDevice
- * @iface: an interface number
* @error: a #GError, or %NULL
*
- * Gets any extra data from the interface.
+ * Gets all the interfaces exported by the device.
*
- * Return value: (transfer full): a #GBytes, or %NULL for failure
+ * Return value: (transfer container): an array of #GUsbInterface or %NULL for error
*
- * Since: 0.2.5
+ * Since: 0.2.8
**/
-GBytes *
-g_usb_device_get_interface_data (GUsbDevice *device, guint8 iface, GError **error)
+GPtrArray *
+g_usb_device_get_interfaces (GUsbDevice *device, GError **error)
{
const struct libusb_interface_descriptor *ifp;
gint rc;
guint i;
- GBytes *bytes = NULL;
+ guint j;
struct libusb_config_descriptor *config;
+ GPtrArray *array = NULL;
rc = libusb_get_active_config_descriptor (device->priv->device, &config);
if (!g_usb_device_libusb_error_to_gerror (device, rc, error))
return NULL;
- /* find the right data */
+ /* get all interfaces */
+ array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
for (i = 0; i < config->bNumInterfaces; i++) {
- ifp = &config->interface[i].altsetting[0];
- if (iface == ifp->bInterfaceNumber) {
- bytes = g_bytes_new (config->extra, config->extra_length);
- break;
+ GUsbInterface *interface = NULL;
+ for (j = 0; j < (guint) config->interface[i].num_altsetting; j++) {
+ ifp = &config->interface[i].altsetting[j];
+ interface = _g_usb_interface_new (ifp);
+ g_ptr_array_add (array, interface);
}
- }
-
- /* nothing matched */
- if (bytes == NULL) {
- g_set_error (error,
- G_USB_DEVICE_ERROR,
- G_USB_DEVICE_ERROR_NOT_SUPPORTED,
- "no interface 0x%02x", iface);
+ break;
}
libusb_free_config_descriptor (config);
- return bytes;
+ return array;
}
/**
@@ -807,6 +803,40 @@ g_usb_device_release_interface (GUsbDevice *device,
}
/**
+ * g_usb_device_set_interface_alt:
+ * @device: a #GUsbDevice
+ * @interface: bInterfaceNumber of the interface you wish to release
+ * @alt: alternative setting number
+ * @error: a #GError, or %NULL
+ *
+ * Sets an alternate setting on an interface.
+ *
+ * Return value: %TRUE on success
+ *
+ * Since: 0.2.8
+ **/
+gboolean
+g_usb_device_set_interface_alt (GUsbDevice *device,
+ gint interface,
+ gint alt,
+ GError **error)
+{
+ gint rc;
+
+ g_return_val_if_fail (G_USB_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ if (device->priv->handle == NULL)
+ return g_usb_device_not_open_error (device, error);
+
+ rc = libusb_set_interface_alt_setting (device->priv->handle, interface, alt);
+ if (rc != LIBUSB_SUCCESS)
+ return g_usb_device_libusb_error_to_gerror (device, rc, error);
+
+ return TRUE;
+}
+
+/**
* g_usb_device_get_string_descriptor:
* @desc_index: the index for the string descriptor to retreive
* @error: a #GError, or %NULL
@@ -1657,6 +1687,24 @@ g_usb_device_get_pid (GUsbDevice *device)
}
/**
+ * g_usb_device_get_version_bcd:
+ * @device: a #GUsbDevice
+ *
+ * Gets the BCD firmware version number for the device.
+ *
+ * Return value: a version number in BCD format.
+ *
+ * Since: 0.2.8
+ **/
+guint16
+g_usb_device_get_version_bcd (GUsbDevice *device)
+{
+ g_return_val_if_fail (G_USB_IS_DEVICE (device), 0);
+
+ return device->priv->desc.bcdDevice;
+}
+
+/**
* g_usb_device_get_vid_as_str:
* @device: a #GUsbDevice
*
diff --git a/gusb/gusb-device.h b/gusb/gusb-device.h
index 9b6ef79..4579b64 100644
--- a/gusb/gusb-device.h
+++ b/gusb/gusb-device.h
@@ -26,6 +26,7 @@
#include <gio/gio.h>
#include <gusb/gusb-util.h>
+#include <gusb/gusb-interface.h>
G_BEGIN_DECLS
@@ -159,6 +160,7 @@ guint8 g_usb_device_get_port_number (GUsbDevice *device);
guint16 g_usb_device_get_vid (GUsbDevice *device);
guint16 g_usb_device_get_pid (GUsbDevice *device);
+guint16 g_usb_device_get_version_bcd (GUsbDevice *device);
const gchar *g_usb_device_get_vid_as_str (GUsbDevice *device);
const gchar *g_usb_device_get_pid_as_str (GUsbDevice *device);
guint8 g_usb_device_get_device_class (GUsbDevice *device);
@@ -174,13 +176,12 @@ guint8 g_usb_device_get_custom_index (GUsbDevice *device,
guint8 protocol_id,
GError **error);
-guint8 g_usb_device_get_interface (GUsbDevice *device,
+GUsbInterface *g_usb_device_get_interface (GUsbDevice *device,
guint8 class_id,
guint8 subclass_id,
guint8 protocol_id,
GError **error);
-GBytes *g_usb_device_get_interface_data (GUsbDevice *device,
- guint8 iface,
+GPtrArray *g_usb_device_get_interfaces (GUsbDevice *device,
GError **error);
gboolean g_usb_device_open (GUsbDevice *device,
@@ -205,6 +206,10 @@ gboolean g_usb_device_release_interface (GUsbDevice *device,
gint interface,
GUsbDeviceClaimInterfaceFlags flags,
GError **error);
+gboolean g_usb_device_set_interface_alt (GUsbDevice *device,
+ gint interface,
+ gint alt,
+ GError **error);
gchar *g_usb_device_get_string_descriptor (GUsbDevice *device,
guint8 desc_index,
diff --git a/gusb/gusb-interface-private.h b/gusb/gusb-interface-private.h
new file mode 100644
index 0000000..386cc1f
--- /dev/null
+++ b/gusb/gusb-interface-private.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * 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/>.
+ */
+
+#ifndef __GUSB_INTERFACE_PRIVATE_H__
+#define __GUSB_INTERFACE_PRIVATE_H__
+
+#include <libusb-1.0/libusb.h>
+
+#include <gusb/gusb-interface.h>
+
+G_BEGIN_DECLS
+
+GUsbInterface *_g_usb_interface_new (const struct libusb_interface_descriptor *iface);
+
+G_END_DECLS
+
+#endif /* __GUSB_INTERFACE_PRIVATE_H__ */
diff --git a/gusb/gusb-interface.c b/gusb/gusb-interface.c
new file mode 100644
index 0000000..8f8daa9
--- /dev/null
+++ b/gusb/gusb-interface.c
@@ -0,0 +1,247 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * 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/>.
+ */
+
+/**
+ * SECTION:gusb-interface
+ * @short_description: GLib interface integration for libusb
+ *
+ * This object is a thin glib wrapper around a libusb_interface_descriptor
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gusb-interface.h"
+#include "gusb-interface-private.h"
+
+/**
+ * GUsbInterfacePrivate:
+ *
+ * Private #GUsbInterface data
+ **/
+struct _GUsbInterfacePrivate
+{
+ struct libusb_interface_descriptor iface;
+ GBytes *extra;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GUsbInterface, g_usb_interface, G_TYPE_OBJECT)
+
+static void
+g_usb_interface_finalize (GObject *object)
+{
+ GUsbInterface *interface = G_USB_INTERFACE (object);
+ GUsbInterfacePrivate *priv = interface->priv;
+
+ g_bytes_unref (priv->extra);
+
+ G_OBJECT_CLASS (g_usb_interface_parent_class)->finalize (object);
+}
+
+static void
+g_usb_interface_class_init (GUsbInterfaceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = g_usb_interface_finalize;
+}
+
+static void
+g_usb_interface_init (GUsbInterface *interface)
+{
+ interface->priv = g_usb_interface_get_instance_private (interface);
+}
+
+/**
+ * _g_usb_interface_new:
+ *
+ * Return value: a new #GUsbInterface object.
+ *
+ * Since: 0.2.8
+ **/
+GUsbInterface *
+_g_usb_interface_new (const struct libusb_interface_descriptor *iface)
+{
+ GUsbInterface *interface;
+ interface = g_object_new (G_USB_TYPE_INTERFACE, NULL);
+
+ /* copy the data */
+ memcpy (&interface->priv->iface,
+ iface,
+ sizeof (struct libusb_interface_descriptor));
+ interface->priv->extra = g_bytes_new (iface->extra, iface->extra_length);
+
+ return G_USB_INTERFACE (interface);
+}
+
+/**
+ * g_usb_interface_get_length:
+ * @interface: a #GUsbInterface
+ *
+ * Gets the USB bus number for the interface.
+ *
+ * Return value: The 8-bit bus number
+ *
+ * Since: 0.2.8
+ **/
+guint8
+g_usb_interface_get_length (GUsbInterface *interface)
+{
+ g_return_val_if_fail (G_USB_IS_INTERFACE (interface), 0);
+ return interface->priv->iface.bLength;
+}
+
+/**
+ * g_usb_interface_get_kind:
+ * @interface: a #GUsbInterface
+ *
+ * Gets the type of interface.
+ *
+ * Return value: The 8-bit address
+ *
+ * Since: 0.2.8
+ **/
+guint8
+g_usb_interface_get_kind (GUsbInterface *interface)
+{
+ g_return_val_if_fail (G_USB_IS_INTERFACE (interface), 0);
+ return interface->priv->iface.bDescriptorType;
+}
+
+/**
+ * g_usb_interface_get_number:
+ * @interface: a #GUsbInterface
+ *
+ * Gets the interface number.
+ *
+ * Return value: The interface ID
+ *
+ * Since: 0.2.8
+ **/
+guint8
+g_usb_interface_get_number (GUsbInterface *interface)
+{
+ g_return_val_if_fail (G_USB_IS_INTERFACE (interface), 0);
+ return interface->priv->iface.bInterfaceNumber;
+}
+
+/**
+ * g_usb_interface_get_alternate:
+ * @interface: a #GUsbInterface
+ *
+ * Gets the alternate setting for the interface.
+ *
+ * Return value: alt setting, typically zero.
+ *
+ * Since: 0.2.8
+ **/
+guint8
+g_usb_interface_get_alternate (GUsbInterface *interface)
+{
+ g_return_val_if_fail (G_USB_IS_INTERFACE (interface), 0);
+ return interface->priv->iface.bAlternateSetting;
+}
+
+/**
+ * g_usb_interface_get_class:
+ * @interface: a #GUsbInterface
+ *
+ * Gets the interface class, typically a #GUsbInterfaceClassCode.
+ *
+ * Return value: a interface class number, e.g. 0x09 is a USB hub.
+ *
+ * Since: 0.2.8
+ **/
+guint8
+g_usb_interface_get_class (GUsbInterface *interface)
+{
+ g_return_val_if_fail (G_USB_IS_INTERFACE (interface), 0);
+ return interface->priv->iface.bInterfaceClass;
+}
+
+/**
+ * g_usb_interface_get_subclass:
+ * @interface: a #GUsbInterface
+ *
+ * Gets the interface subclass qualified by the class number.
+ * See g_usb_interface_get_class().
+ *
+ * Return value: a interface subclass number.
+ *
+ * Since: 0.2.8
+ **/
+guint8
+g_usb_interface_get_subclass (GUsbInterface *interface)
+{
+ g_return_val_if_fail (G_USB_IS_INTERFACE (interface), 0);
+ return interface->priv->iface.bInterfaceSubClass;
+}
+
+/**
+ * g_usb_interface_get_protocol:
+ * @interface: a #GUsbInterface
+ *
+ * Gets the interface protocol qualified by the class and subclass numbers.
+ * See g_usb_interface_get_class() and g_usb_interface_get_subclass().
+ *
+ * Return value: a interface protocol number.
+ *
+ * Since: 0.2.8
+ **/
+guint8
+g_usb_interface_get_protocol (GUsbInterface *interface)
+{
+ g_return_val_if_fail (G_USB_IS_INTERFACE (interface), 0);
+ return interface->priv->iface.bInterfaceProtocol;
+}
+
+/**
+ * g_usb_interface_get_index:
+ * @interface: a #GUsbInterface
+ *
+ * Gets the index for the string descriptor.
+ *
+ * Return value: a string descriptor index.
+ *
+ * Since: 0.2.8
+ **/
+guint8
+g_usb_interface_get_index (GUsbInterface *interface)
+{
+ g_return_val_if_fail (G_USB_IS_INTERFACE (interface), 0);
+ return interface->priv->iface.iInterface;
+}
+
+/**
+ * g_usb_interface_get_extra:
+ * @interface: a #GUsbInterface
+ *
+ * Gets any extra data from the interface.
+ *
+ * Return value: (transfer none): a #GBytes, or %NULL for failure
+ *
+ * Since: 0.2.8
+ **/
+GBytes *
+g_usb_interface_get_extra (GUsbInterface *interface)
+{
+ g_return_val_if_fail (G_USB_IS_INTERFACE (interface), NULL);
+ return interface->priv->extra;
+}
diff --git a/gusb/gusb-interface.h b/gusb/gusb-interface.h
new file mode 100644
index 0000000..816373b
--- /dev/null
+++ b/gusb/gusb-interface.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * 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/>.
+ */
+
+#ifndef __GUSB_INTERFACE_H__
+#define __GUSB_INTERFACE_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define G_USB_TYPE_INTERFACE (g_usb_interface_get_type ())
+#define G_USB_INTERFACE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_USB_TYPE_INTERFACE, GUsbInterface))
+#define G_USB_IS_INTERFACE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_USB_TYPE_INTERFACE))
+
+typedef struct _GUsbInterfacePrivate GUsbInterfacePrivate;
+typedef struct _GUsbInterface GUsbInterface;
+typedef struct _GUsbInterfaceClass GUsbInterfaceClass;
+
+struct _GUsbInterface
+{
+ GObject parent;
+ GUsbInterfacePrivate *priv;
+};
+
+struct _GUsbInterfaceClass
+{
+ GObjectClass parent_class;
+ /*< private >*/
+ /*
+ * If adding fields to this struct, remove corresponding
+ * amount of padding to avoid changing overall struct size
+ */
+ gpointer _gusb_reserved[31];
+};
+
+GType g_usb_interface_get_type (void);
+
+guint8 g_usb_interface_get_length (GUsbInterface *interface);
+guint8 g_usb_interface_get_kind (GUsbInterface *interface);
+guint8 g_usb_interface_get_number (GUsbInterface *interface);
+guint8 g_usb_interface_get_alternate (GUsbInterface *interface);
+guint8 g_usb_interface_get_class (GUsbInterface *interface);
+guint8 g_usb_interface_get_subclass (GUsbInterface *interface);
+guint8 g_usb_interface_get_protocol (GUsbInterface *interface);
+guint8 g_usb_interface_get_index (GUsbInterface *interface);
+GBytes *g_usb_interface_get_extra (GUsbInterface *interface);
+
+G_END_DECLS
+
+#endif /* __GUSB_INTERFACE_H__ */
diff --git a/gusb/gusb.h b/gusb/gusb.h
index 50a9cd0..56d08e1 100644
--- a/gusb/gusb.h
+++ b/gusb/gusb.h
@@ -26,6 +26,7 @@
#include <gusb/gusb-autocleanups.h>
#include <gusb/gusb-context.h>
+#include <gusb/gusb-interface.h>
#include <gusb/gusb-source.h>
#include <gusb/gusb-device.h>
#include <gusb/gusb-device-list.h>