mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-07 08:39:48 +00:00
Add FuUsbDevice helper object
This allows us to move a lot of duplicated functionality out of each plugin.
This commit is contained in:
parent
0415811740
commit
29a524fdfb
@ -43,6 +43,7 @@
|
|||||||
</partintro>
|
</partintro>
|
||||||
<xi:include href="xml/fu-plugin.xml"/>
|
<xi:include href="xml/fu-plugin.xml"/>
|
||||||
<xi:include href="xml/fu-device.xml"/>
|
<xi:include href="xml/fu-device.xml"/>
|
||||||
|
<xi:include href="xml/fu-usb-device.xml"/>
|
||||||
<xi:include href="xml/fu-device-locker.xml"/>
|
<xi:include href="xml/fu-device-locker.xml"/>
|
||||||
<xi:include href="xml/fu-common.xml"/>
|
<xi:include href="xml/fu-common.xml"/>
|
||||||
<xi:include href="xml/fu-quirks.xml"/>
|
<xi:include href="xml/fu-quirks.xml"/>
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FuAltosDeviceKind kind;
|
FuAltosDeviceKind kind;
|
||||||
GUsbDevice *usb_device;
|
|
||||||
guint32 serial[9];
|
guint32 serial[9];
|
||||||
gchar *guid;
|
gchar *guid;
|
||||||
gchar *tty;
|
gchar *tty;
|
||||||
@ -46,7 +45,7 @@ typedef struct
|
|||||||
gint tty_fd;
|
gint tty_fd;
|
||||||
} FuAltosDevicePrivate;
|
} FuAltosDevicePrivate;
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (FuAltosDevice, fu_altos_device, FU_TYPE_DEVICE)
|
G_DEFINE_TYPE_WITH_PRIVATE (FuAltosDevice, fu_altos_device, FU_TYPE_USB_DEVICE)
|
||||||
|
|
||||||
#define GET_PRIVATE(o) (fu_altos_device_get_instance_private (o))
|
#define GET_PRIVATE(o) (fu_altos_device_get_instance_private (o))
|
||||||
|
|
||||||
@ -103,8 +102,6 @@ fu_altos_device_finalize (GObject *object)
|
|||||||
g_free (priv->guid);
|
g_free (priv->guid);
|
||||||
g_free (priv->tty);
|
g_free (priv->tty);
|
||||||
g_free (priv->version);
|
g_free (priv->version);
|
||||||
if (priv->usb_device != NULL)
|
|
||||||
g_object_unref (priv->usb_device);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (fu_altos_device_parent_class)->finalize (object);
|
G_OBJECT_CLASS (fu_altos_device_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -132,6 +129,7 @@ static gboolean
|
|||||||
fu_altos_device_find_tty (FuAltosDevice *device, GError **error)
|
fu_altos_device_find_tty (FuAltosDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuAltosDevicePrivate *priv = GET_PRIVATE (device);
|
FuAltosDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
g_autoptr(GList) devices = NULL;
|
g_autoptr(GList) devices = NULL;
|
||||||
g_autoptr(GUdevClient) gudev_client = g_udev_client_new (NULL);
|
g_autoptr(GUdevClient) gudev_client = g_udev_client_new (NULL);
|
||||||
|
|
||||||
@ -155,10 +153,10 @@ fu_altos_device_find_tty (FuAltosDevice *device, GError **error)
|
|||||||
|
|
||||||
/* check correct device */
|
/* check correct device */
|
||||||
if (g_udev_device_get_sysfs_attr_as_int (dev, "busnum") !=
|
if (g_udev_device_get_sysfs_attr_as_int (dev, "busnum") !=
|
||||||
g_usb_device_get_bus (priv->usb_device))
|
g_usb_device_get_bus (usb_device))
|
||||||
continue;
|
continue;
|
||||||
if (g_udev_device_get_sysfs_attr_as_int (dev, "devnum") !=
|
if (g_udev_device_get_sysfs_attr_as_int (dev, "devnum") !=
|
||||||
g_usb_device_get_address (priv->usb_device))
|
g_usb_device_get_address (usb_device))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
@ -171,8 +169,8 @@ fu_altos_device_find_tty (FuAltosDevice *device, GError **error)
|
|||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
FWUPD_ERROR_NOT_SUPPORTED,
|
FWUPD_ERROR_NOT_SUPPORTED,
|
||||||
"failed to find tty for %u:%u",
|
"failed to find tty for %u:%u",
|
||||||
g_usb_device_get_bus (priv->usb_device),
|
g_usb_device_get_bus (usb_device),
|
||||||
g_usb_device_get_address (priv->usb_device));
|
g_usb_device_get_address (usb_device));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -722,6 +720,7 @@ gboolean
|
|||||||
fu_altos_device_probe (FuAltosDevice *device, GError **error)
|
fu_altos_device_probe (FuAltosDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuAltosDevicePrivate *priv = GET_PRIVATE (device);
|
FuAltosDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
|
|
||||||
/* bootloader uses tty */
|
/* bootloader uses tty */
|
||||||
if (priv->kind == FU_ALTOS_DEVICE_KIND_BOOTLOADER)
|
if (priv->kind == FU_ALTOS_DEVICE_KIND_BOOTLOADER)
|
||||||
@ -735,13 +734,13 @@ fu_altos_device_probe (FuAltosDevice *device, GError **error)
|
|||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
|
|
||||||
/* open */
|
/* open */
|
||||||
locker = fu_device_locker_new (priv->usb_device, error);
|
locker = fu_device_locker_new (usb_device, error);
|
||||||
if (locker == NULL)
|
if (locker == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* get string */
|
/* get string */
|
||||||
version_idx = g_usb_device_get_product_index (priv->usb_device);
|
version_idx = g_usb_device_get_product_index (usb_device);
|
||||||
version = g_usb_device_get_string_descriptor (priv->usb_device,
|
version = g_usb_device_get_string_descriptor (usb_device,
|
||||||
version_idx,
|
version_idx,
|
||||||
error);
|
error);
|
||||||
if (version == NULL)
|
if (version == NULL)
|
||||||
@ -766,23 +765,13 @@ static void
|
|||||||
fu_altos_device_init_real (FuAltosDevice *device)
|
fu_altos_device_init_real (FuAltosDevice *device)
|
||||||
{
|
{
|
||||||
FuAltosDevicePrivate *priv = GET_PRIVATE (device);
|
FuAltosDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
g_autofree gchar *devid1 = NULL;
|
|
||||||
g_autofree gchar *vendor_id = NULL;
|
|
||||||
|
|
||||||
/* allowed, but requires manual bootloader step */
|
/* allowed, but requires manual bootloader step */
|
||||||
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE);
|
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||||
|
|
||||||
/* set USB platform ID */
|
|
||||||
fu_device_set_platform_id (FU_DEVICE (device),
|
|
||||||
g_usb_device_get_platform_id (priv->usb_device));
|
|
||||||
|
|
||||||
/* set default vendor */
|
/* set default vendor */
|
||||||
fu_device_set_vendor (FU_DEVICE (device), "altusmetrum.org");
|
fu_device_set_vendor (FU_DEVICE (device), "altusmetrum.org");
|
||||||
|
|
||||||
/* set vendor ID */
|
|
||||||
vendor_id = g_strdup_printf ("USB:0x%04X", g_usb_device_get_vid (priv->usb_device));
|
|
||||||
fu_device_set_vendor_id (FU_DEVICE (device), vendor_id);
|
|
||||||
|
|
||||||
/* set name */
|
/* set name */
|
||||||
switch (priv->kind) {
|
switch (priv->kind) {
|
||||||
case FU_ALTOS_DEVICE_KIND_BOOTLOADER:
|
case FU_ALTOS_DEVICE_KIND_BOOTLOADER:
|
||||||
@ -800,13 +789,6 @@ fu_altos_device_init_real (FuAltosDevice *device)
|
|||||||
fu_device_set_summary (FU_DEVICE (device),
|
fu_device_set_summary (FU_DEVICE (device),
|
||||||
"A USB hardware random number generator");
|
"A USB hardware random number generator");
|
||||||
|
|
||||||
/* add USB\VID_0000&PID_0000 */
|
|
||||||
devid1 = g_strdup_printf ("USB\\VID_%04X&PID_%04X",
|
|
||||||
g_usb_device_get_vid (priv->usb_device),
|
|
||||||
g_usb_device_get_pid (priv->usb_device));
|
|
||||||
fu_device_add_guid (FU_DEVICE (device), devid1);
|
|
||||||
g_debug ("saving runtime GUID of %s", devid1);
|
|
||||||
|
|
||||||
/* only the bootloader can do the update */
|
/* only the bootloader can do the update */
|
||||||
if (priv->kind != FU_ALTOS_DEVICE_KIND_BOOTLOADER) {
|
if (priv->kind != FU_ALTOS_DEVICE_KIND_BOOTLOADER) {
|
||||||
fu_device_add_flag (FU_DEVICE (device),
|
fu_device_add_flag (FU_DEVICE (device),
|
||||||
@ -823,8 +805,6 @@ typedef struct {
|
|||||||
FuAltosDevice *
|
FuAltosDevice *
|
||||||
fu_altos_device_new (GUsbDevice *usb_device)
|
fu_altos_device_new (GUsbDevice *usb_device)
|
||||||
{
|
{
|
||||||
FuAltosDevice *device;
|
|
||||||
FuAltosDevicePrivate *priv;
|
|
||||||
const FuAltosDeviceVidPid vidpids[] = {
|
const FuAltosDeviceVidPid vidpids[] = {
|
||||||
{ 0xfffe, 0x000a, FU_ALTOS_DEVICE_KIND_BOOTLOADER },
|
{ 0xfffe, 0x000a, FU_ALTOS_DEVICE_KIND_BOOTLOADER },
|
||||||
{ 0x1d50, 0x60c6, FU_ALTOS_DEVICE_KIND_CHAOSKEY },
|
{ 0x1d50, 0x60c6, FU_ALTOS_DEVICE_KIND_CHAOSKEY },
|
||||||
@ -833,16 +813,18 @@ fu_altos_device_new (GUsbDevice *usb_device)
|
|||||||
|
|
||||||
/* set kind */
|
/* set kind */
|
||||||
for (guint j = 0; vidpids[j].vid != 0x0000; j++) {
|
for (guint j = 0; vidpids[j].vid != 0x0000; j++) {
|
||||||
if (g_usb_device_get_vid (usb_device) != vidpids[j].vid)
|
if (g_usb_device_get_vid (usb_device) == vidpids[j].vid &&
|
||||||
continue;
|
g_usb_device_get_pid (usb_device) == vidpids[j].pid) {
|
||||||
if (g_usb_device_get_pid (usb_device) != vidpids[j].pid)
|
FuAltosDevice *device;
|
||||||
continue;
|
FuAltosDevicePrivate *priv;
|
||||||
device = g_object_new (FU_TYPE_ALTOS_DEVICE, NULL);
|
device = g_object_new (FU_TYPE_ALTOS_DEVICE,
|
||||||
|
"usb-device", usb_device,
|
||||||
|
NULL);
|
||||||
priv = GET_PRIVATE (device);
|
priv = GET_PRIVATE (device);
|
||||||
priv->kind = vidpids[j].kind;
|
priv->kind = vidpids[j].kind;
|
||||||
priv->usb_device = g_object_ref (usb_device);
|
|
||||||
fu_altos_device_init_real (device);
|
fu_altos_device_init_real (device);
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -30,11 +30,11 @@
|
|||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define FU_TYPE_ALTOS_DEVICE (fu_altos_device_get_type ())
|
#define FU_TYPE_ALTOS_DEVICE (fu_altos_device_get_type ())
|
||||||
G_DECLARE_DERIVABLE_TYPE (FuAltosDevice, fu_altos_device, FU, ALTOS_DEVICE, FuDevice)
|
G_DECLARE_DERIVABLE_TYPE (FuAltosDevice, fu_altos_device, FU, ALTOS_DEVICE, FuUsbDevice)
|
||||||
|
|
||||||
struct _FuAltosDeviceClass
|
struct _FuAltosDeviceClass
|
||||||
{
|
{
|
||||||
FuDeviceClass parent_class;
|
FuUsbDeviceClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <appstream-glib.h>
|
|
||||||
|
|
||||||
#include "fu-plugin.h"
|
#include "fu-plugin.h"
|
||||||
#include "fu-plugin-vfuncs.h"
|
#include "fu-plugin-vfuncs.h"
|
||||||
|
|
||||||
@ -35,16 +33,8 @@ fu_plugin_altos_device_added (FuPlugin *plugin,
|
|||||||
{
|
{
|
||||||
const gchar *platform_id = NULL;
|
const gchar *platform_id = NULL;
|
||||||
g_autofree gchar *runtime_id = NULL;
|
g_autofree gchar *runtime_id = NULL;
|
||||||
g_autoptr(AsProfile) profile = as_profile_new ();
|
|
||||||
g_autoptr(AsProfileTask) ptask = NULL;
|
|
||||||
g_autoptr(FuAltosDevice) dev = NULL;
|
g_autoptr(FuAltosDevice) dev = NULL;
|
||||||
|
|
||||||
/* profile */
|
|
||||||
ptask = as_profile_start (profile, "FuPluginAltos:added{%04x:%04x}",
|
|
||||||
g_usb_device_get_vid (usb_device),
|
|
||||||
g_usb_device_get_pid (usb_device));
|
|
||||||
g_assert (ptask != NULL);
|
|
||||||
|
|
||||||
/* get kind */
|
/* get kind */
|
||||||
dev = fu_altos_device_new (usb_device);
|
dev = fu_altos_device_new (usb_device);
|
||||||
if (dev == NULL) {
|
if (dev == NULL) {
|
||||||
|
@ -30,14 +30,12 @@
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ChDeviceQueue *device_queue;
|
ChDeviceQueue *device_queue;
|
||||||
GUsbDevice *usb_device;
|
|
||||||
FuDeviceLocker *usb_device_locker;
|
|
||||||
gboolean is_bootloader;
|
gboolean is_bootloader;
|
||||||
GFileProgressCallback progress_cb;
|
GFileProgressCallback progress_cb;
|
||||||
gpointer progress_data;
|
gpointer progress_data;
|
||||||
} FuColorhugDevicePrivate;
|
} FuColorhugDevicePrivate;
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (FuColorhugDevice, fu_colorhug_device, FU_TYPE_DEVICE)
|
G_DEFINE_TYPE_WITH_PRIVATE (FuColorhugDevice, fu_colorhug_device, FU_TYPE_USB_DEVICE)
|
||||||
|
|
||||||
#define GET_PRIVATE(o) (fu_colorhug_device_get_instance_private (o))
|
#define GET_PRIVATE(o) (fu_colorhug_device_get_instance_private (o))
|
||||||
|
|
||||||
@ -48,10 +46,6 @@ fu_colorhug_device_finalize (GObject *object)
|
|||||||
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
|
||||||
g_object_unref (priv->device_queue);
|
g_object_unref (priv->device_queue);
|
||||||
if (priv->usb_device_locker != NULL)
|
|
||||||
g_object_unref (priv->usb_device_locker);
|
|
||||||
if (priv->usb_device != NULL)
|
|
||||||
g_object_unref (priv->usb_device);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (fu_colorhug_device_parent_class)->finalize (object);
|
G_OBJECT_CLASS (fu_colorhug_device_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -67,29 +61,6 @@ fu_colorhug_device_progress_cb (ChDeviceQueue *device_queue,
|
|||||||
priv->progress_cb (percentage, 100, priv->progress_data);
|
priv->progress_cb (percentage, 100, priv->progress_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
fu_colorhug_device_init (FuColorhugDevice *device)
|
|
||||||
{
|
|
||||||
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
|
||||||
priv->device_queue = ch_device_queue_new ();
|
|
||||||
g_signal_connect (priv->device_queue, "progress_changed",
|
|
||||||
G_CALLBACK (fu_colorhug_device_progress_cb), device);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fu_colorhug_device_class_init (FuColorhugDeviceClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
object_class->finalize = fu_colorhug_device_finalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
GUsbDevice *
|
|
||||||
fu_colorhug_device_get_usb_device (FuColorhugDevice *device)
|
|
||||||
{
|
|
||||||
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
|
||||||
return priv->usb_device;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
fu_colorhug_device_get_is_bootloader (FuColorhugDevice *device)
|
fu_colorhug_device_get_is_bootloader (FuColorhugDevice *device)
|
||||||
{
|
{
|
||||||
@ -101,6 +72,7 @@ gboolean
|
|||||||
fu_colorhug_device_detach (FuColorhugDevice *device, GError **error)
|
fu_colorhug_device_detach (FuColorhugDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
g_autoptr(GError) error_local = NULL;
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
|
||||||
/* set up progress callback */
|
/* set up progress callback */
|
||||||
@ -108,7 +80,7 @@ fu_colorhug_device_detach (FuColorhugDevice *device, GError **error)
|
|||||||
priv->progress_data = NULL;
|
priv->progress_data = NULL;
|
||||||
|
|
||||||
g_debug ("rebooting...");
|
g_debug ("rebooting...");
|
||||||
ch_device_queue_reset (priv->device_queue, priv->usb_device);
|
ch_device_queue_reset (priv->device_queue, usb_device);
|
||||||
if (!ch_device_queue_process (priv->device_queue,
|
if (!ch_device_queue_process (priv->device_queue,
|
||||||
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
||||||
NULL, &error_local)) {
|
NULL, &error_local)) {
|
||||||
@ -126,6 +98,7 @@ gboolean
|
|||||||
fu_colorhug_device_attach (FuColorhugDevice *device, GError **error)
|
fu_colorhug_device_attach (FuColorhugDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
g_autoptr(GError) error_local = NULL;
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
|
||||||
/* set up progress callback */
|
/* set up progress callback */
|
||||||
@ -133,7 +106,7 @@ fu_colorhug_device_attach (FuColorhugDevice *device, GError **error)
|
|||||||
priv->progress_data = NULL;
|
priv->progress_data = NULL;
|
||||||
|
|
||||||
g_debug ("rebooting...");
|
g_debug ("rebooting...");
|
||||||
ch_device_queue_boot_flash (priv->device_queue, priv->usb_device);
|
ch_device_queue_boot_flash (priv->device_queue, usb_device);
|
||||||
if (!ch_device_queue_process (priv->device_queue,
|
if (!ch_device_queue_process (priv->device_queue,
|
||||||
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
||||||
NULL, &error_local)) {
|
NULL, &error_local)) {
|
||||||
@ -151,6 +124,7 @@ gboolean
|
|||||||
fu_colorhug_device_set_flash_success (FuColorhugDevice *device, GError **error)
|
fu_colorhug_device_set_flash_success (FuColorhugDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
g_autoptr(GError) error_local = NULL;
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
|
||||||
/* set up progress callback */
|
/* set up progress callback */
|
||||||
@ -159,7 +133,7 @@ fu_colorhug_device_set_flash_success (FuColorhugDevice *device, GError **error)
|
|||||||
|
|
||||||
g_debug ("setting flash success");
|
g_debug ("setting flash success");
|
||||||
ch_device_queue_set_flash_success (priv->device_queue,
|
ch_device_queue_set_flash_success (priv->device_queue,
|
||||||
priv->usb_device,
|
usb_device,
|
||||||
0x01);
|
0x01);
|
||||||
if (!ch_device_queue_process (priv->device_queue,
|
if (!ch_device_queue_process (priv->device_queue,
|
||||||
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
||||||
@ -174,194 +148,17 @@ fu_colorhug_device_set_flash_success (FuColorhugDevice *device, GError **error)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
fu_colorhug_device_open (FuColorhugDevice *device, GError **error)
|
fu_colorhug_device_open (FuUsbDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
FuColorhugDevice *self = FU_COLORHUG_DEVICE (device);
|
||||||
|
FuColorhugDevicePrivate *priv = GET_PRIVATE (self);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (device);
|
||||||
|
ChDeviceMode mode;
|
||||||
guint8 idx;
|
guint8 idx;
|
||||||
gboolean got_version = FALSE;
|
gboolean got_version = FALSE;
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
|
||||||
|
|
||||||
/* set up progress callback */
|
/* add hardcoded bits */
|
||||||
priv->progress_cb = NULL;
|
|
||||||
priv->progress_data = NULL;
|
|
||||||
|
|
||||||
/* already open */
|
|
||||||
if (priv->usb_device_locker != NULL)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* open */
|
|
||||||
locker = fu_device_locker_new (priv->usb_device, error);
|
|
||||||
if (locker == NULL)
|
|
||||||
return FALSE;
|
|
||||||
if (!g_usb_device_set_configuration (priv->usb_device, CH_USB_CONFIG, error))
|
|
||||||
return FALSE;
|
|
||||||
if (!g_usb_device_claim_interface (priv->usb_device, CH_USB_INTERFACE,
|
|
||||||
G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
|
|
||||||
error)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get version from descriptors */
|
|
||||||
idx = g_usb_device_get_custom_index (priv->usb_device,
|
|
||||||
G_USB_DEVICE_CLASS_VENDOR_SPECIFIC,
|
|
||||||
'F', 'W', NULL);
|
|
||||||
if (idx != 0x00) {
|
|
||||||
g_autofree gchar *tmp = NULL;
|
|
||||||
tmp = g_usb_device_get_string_descriptor (priv->usb_device,
|
|
||||||
idx, NULL);
|
|
||||||
if (tmp != NULL) {
|
|
||||||
got_version = TRUE;
|
|
||||||
g_debug ("obtained fwver using extension '%s'", tmp);
|
|
||||||
fu_device_set_version (FU_DEVICE (device), tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* got things the old fashioned way */
|
|
||||||
if (!got_version) {
|
|
||||||
guint16 major;
|
|
||||||
guint16 micro;
|
|
||||||
guint16 minor;
|
|
||||||
g_autofree gchar *version = NULL;
|
|
||||||
g_autoptr(GError) error_local = NULL;
|
|
||||||
ch_device_queue_get_firmware_ver (priv->device_queue, priv->usb_device,
|
|
||||||
&major, &minor, µ);
|
|
||||||
if (!ch_device_queue_process (priv->device_queue,
|
|
||||||
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
|
||||||
NULL, &error_local)) {
|
|
||||||
g_warning ("failed to get firmware version: %s",
|
|
||||||
error_local->message);
|
|
||||||
}
|
|
||||||
got_version = TRUE;
|
|
||||||
version = g_strdup_printf ("%i.%i.%i", major, minor, micro);
|
|
||||||
g_debug ("obtained fwver using API '%s'", version);
|
|
||||||
fu_device_set_version (FU_DEVICE (device), version);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* success */
|
|
||||||
priv->usb_device_locker = g_steal_pointer (&locker);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
fu_colorhug_device_close (FuColorhugDevice *device, GError **error)
|
|
||||||
{
|
|
||||||
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
|
||||||
g_clear_object (&priv->usb_device_locker);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
fu_colorhug_device_verify_firmware (FuColorhugDevice *device,
|
|
||||||
GFileProgressCallback progress_cb,
|
|
||||||
gpointer progress_data,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
|
||||||
gsize len;
|
|
||||||
g_autoptr(GError) error_local = NULL;
|
|
||||||
g_autofree guint8 *data2 = NULL;
|
|
||||||
GChecksumType checksum_types[] = {
|
|
||||||
G_CHECKSUM_SHA1,
|
|
||||||
G_CHECKSUM_SHA256,
|
|
||||||
0 };
|
|
||||||
|
|
||||||
/* set up progress callback */
|
|
||||||
priv->progress_cb = progress_cb;
|
|
||||||
priv->progress_data = progress_data;
|
|
||||||
|
|
||||||
/* get the firmware from the device */
|
|
||||||
g_debug ("verifying firmware");
|
|
||||||
ch_device_queue_read_firmware (priv->device_queue, priv->usb_device,
|
|
||||||
&data2, &len);
|
|
||||||
if (!ch_device_queue_process (priv->device_queue,
|
|
||||||
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
|
||||||
NULL, &error_local)) {
|
|
||||||
g_set_error (error,
|
|
||||||
FWUPD_ERROR,
|
|
||||||
FWUPD_ERROR_WRITE,
|
|
||||||
"failed to dump firmware: %s",
|
|
||||||
error_local->message);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the checksum */
|
|
||||||
for (guint i = 0; checksum_types[i] != 0; i++) {
|
|
||||||
g_autofree gchar *hash = NULL;
|
|
||||||
hash = g_compute_checksum_for_data (checksum_types[i],
|
|
||||||
(guchar *) data2, len);
|
|
||||||
fu_device_add_checksum (device, hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
fu_colorhug_device_write_firmware (FuColorhugDevice *device, GBytes *fw,
|
|
||||||
GFileProgressCallback progress_cb,
|
|
||||||
gpointer progress_data,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
|
||||||
g_autoptr(GError) error_local = NULL;
|
|
||||||
|
|
||||||
/* set up progress callback */
|
|
||||||
priv->progress_cb = progress_cb;
|
|
||||||
priv->progress_data = progress_data;
|
|
||||||
|
|
||||||
g_debug ("writing firmware");
|
|
||||||
ch_device_queue_set_flash_success (priv->device_queue,
|
|
||||||
priv->usb_device,
|
|
||||||
0x00);
|
|
||||||
ch_device_queue_write_firmware (priv->device_queue, priv->usb_device,
|
|
||||||
g_bytes_get_data (fw, NULL),
|
|
||||||
g_bytes_get_size (fw));
|
|
||||||
if (!ch_device_queue_process (priv->device_queue,
|
|
||||||
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
|
||||||
NULL, &error_local)) {
|
|
||||||
g_set_error (error,
|
|
||||||
FWUPD_ERROR,
|
|
||||||
FWUPD_ERROR_WRITE,
|
|
||||||
"failed to write firmware: %s",
|
|
||||||
error_local->message);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* verify firmware */
|
|
||||||
g_debug ("verifying firmware");
|
|
||||||
ch_device_queue_verify_firmware (priv->device_queue, priv->usb_device,
|
|
||||||
g_bytes_get_data (fw, NULL),
|
|
||||||
g_bytes_get_size (fw));
|
|
||||||
if (!ch_device_queue_process (priv->device_queue,
|
|
||||||
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
|
||||||
NULL, &error_local)) {
|
|
||||||
g_set_error (error,
|
|
||||||
FWUPD_ERROR,
|
|
||||||
FWUPD_ERROR_WRITE,
|
|
||||||
"failed to verify firmware: %s",
|
|
||||||
error_local->message);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* success! */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
fu_colorhug_device_set_usb_device (FuColorhugDevice *device,
|
|
||||||
GUsbDevice *usb_device,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
|
||||||
ChDeviceMode mode;
|
|
||||||
|
|
||||||
g_set_object (&priv->usb_device, usb_device);
|
|
||||||
fu_device_set_platform_id (FU_DEVICE (device),
|
|
||||||
g_usb_device_get_platform_id (priv->usb_device));
|
|
||||||
fu_device_set_vendor (FU_DEVICE (device), "Hughski Limited");
|
|
||||||
fu_device_set_vendor_id (FU_DEVICE (device), "USB:0x273F");
|
|
||||||
fu_device_set_equivalent_id (FU_DEVICE (device),
|
|
||||||
g_usb_device_get_platform_id (usb_device));
|
|
||||||
fu_device_add_guid (FU_DEVICE (device), ch_device_get_guid (usb_device));
|
fu_device_add_guid (FU_DEVICE (device), ch_device_get_guid (usb_device));
|
||||||
fu_device_add_icon (FU_DEVICE (device), "colorimeter-colorhug");
|
fu_device_add_icon (FU_DEVICE (device), "colorimeter-colorhug");
|
||||||
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE);
|
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||||
@ -412,9 +209,175 @@ fu_colorhug_device_set_usb_device (FuColorhugDevice *device,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set up progress callback */
|
||||||
|
priv->progress_cb = NULL;
|
||||||
|
priv->progress_data = NULL;
|
||||||
|
|
||||||
|
/* open */
|
||||||
|
if (!g_usb_device_set_configuration (usb_device, CH_USB_CONFIG, error))
|
||||||
|
return FALSE;
|
||||||
|
if (!g_usb_device_claim_interface (usb_device, CH_USB_INTERFACE,
|
||||||
|
G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
|
||||||
|
error)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get version from descriptors */
|
||||||
|
idx = g_usb_device_get_custom_index (usb_device,
|
||||||
|
G_USB_DEVICE_CLASS_VENDOR_SPECIFIC,
|
||||||
|
'F', 'W', NULL);
|
||||||
|
if (idx != 0x00) {
|
||||||
|
g_autofree gchar *tmp = NULL;
|
||||||
|
tmp = g_usb_device_get_string_descriptor (usb_device,
|
||||||
|
idx, NULL);
|
||||||
|
if (tmp != NULL) {
|
||||||
|
got_version = TRUE;
|
||||||
|
g_debug ("obtained fwver using extension '%s'", tmp);
|
||||||
|
fu_device_set_version (FU_DEVICE (device), tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* got things the old fashioned way */
|
||||||
|
if (!got_version) {
|
||||||
|
guint16 major;
|
||||||
|
guint16 micro;
|
||||||
|
guint16 minor;
|
||||||
|
g_autofree gchar *version = NULL;
|
||||||
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
ch_device_queue_get_firmware_ver (priv->device_queue, usb_device,
|
||||||
|
&major, &minor, µ);
|
||||||
|
if (!ch_device_queue_process (priv->device_queue,
|
||||||
|
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
||||||
|
NULL, &error_local)) {
|
||||||
|
g_warning ("failed to get firmware version: %s",
|
||||||
|
error_local->message);
|
||||||
|
}
|
||||||
|
got_version = TRUE;
|
||||||
|
version = g_strdup_printf ("%i.%i.%i", major, minor, micro);
|
||||||
|
g_debug ("obtained fwver using API '%s'", version);
|
||||||
|
fu_device_set_version (FU_DEVICE (device), version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* success */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
fu_colorhug_device_verify_firmware (FuColorhugDevice *device,
|
||||||
|
GFileProgressCallback progress_cb,
|
||||||
|
gpointer progress_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
|
gsize len;
|
||||||
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
g_autofree guint8 *data2 = NULL;
|
||||||
|
GChecksumType checksum_types[] = {
|
||||||
|
G_CHECKSUM_SHA1,
|
||||||
|
G_CHECKSUM_SHA256,
|
||||||
|
0 };
|
||||||
|
|
||||||
|
/* set up progress callback */
|
||||||
|
priv->progress_cb = progress_cb;
|
||||||
|
priv->progress_data = progress_data;
|
||||||
|
|
||||||
|
/* get the firmware from the device */
|
||||||
|
g_debug ("verifying firmware");
|
||||||
|
ch_device_queue_read_firmware (priv->device_queue, usb_device,
|
||||||
|
&data2, &len);
|
||||||
|
if (!ch_device_queue_process (priv->device_queue,
|
||||||
|
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
||||||
|
NULL, &error_local)) {
|
||||||
|
g_set_error (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_WRITE,
|
||||||
|
"failed to dump firmware: %s",
|
||||||
|
error_local->message);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the checksum */
|
||||||
|
for (guint i = 0; checksum_types[i] != 0; i++) {
|
||||||
|
g_autofree gchar *hash = NULL;
|
||||||
|
hash = g_compute_checksum_for_data (checksum_types[i],
|
||||||
|
(guchar *) data2, len);
|
||||||
|
fu_device_add_checksum (device, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
fu_colorhug_device_write_firmware (FuColorhugDevice *device, GBytes *fw,
|
||||||
|
GFileProgressCallback progress_cb,
|
||||||
|
gpointer progress_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
|
||||||
|
/* set up progress callback */
|
||||||
|
priv->progress_cb = progress_cb;
|
||||||
|
priv->progress_data = progress_data;
|
||||||
|
|
||||||
|
g_debug ("writing firmware");
|
||||||
|
ch_device_queue_set_flash_success (priv->device_queue,
|
||||||
|
usb_device,
|
||||||
|
0x00);
|
||||||
|
ch_device_queue_write_firmware (priv->device_queue, usb_device,
|
||||||
|
g_bytes_get_data (fw, NULL),
|
||||||
|
g_bytes_get_size (fw));
|
||||||
|
if (!ch_device_queue_process (priv->device_queue,
|
||||||
|
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
||||||
|
NULL, &error_local)) {
|
||||||
|
g_set_error (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_WRITE,
|
||||||
|
"failed to write firmware: %s",
|
||||||
|
error_local->message);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verify firmware */
|
||||||
|
g_debug ("verifying firmware");
|
||||||
|
ch_device_queue_verify_firmware (priv->device_queue, usb_device,
|
||||||
|
g_bytes_get_data (fw, NULL),
|
||||||
|
g_bytes_get_size (fw));
|
||||||
|
if (!ch_device_queue_process (priv->device_queue,
|
||||||
|
CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
|
||||||
|
NULL, &error_local)) {
|
||||||
|
g_set_error (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_WRITE,
|
||||||
|
"failed to verify firmware: %s",
|
||||||
|
error_local->message);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* success! */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_colorhug_device_init (FuColorhugDevice *device)
|
||||||
|
{
|
||||||
|
FuColorhugDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
priv->device_queue = ch_device_queue_new ();
|
||||||
|
g_signal_connect (priv->device_queue, "progress_changed",
|
||||||
|
G_CALLBACK (fu_colorhug_device_progress_cb), device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_colorhug_device_class_init (FuColorhugDeviceClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
FuUsbDeviceClass *klass_usb_device = FU_USB_DEVICE_CLASS (klass);
|
||||||
|
object_class->finalize = fu_colorhug_device_finalize;
|
||||||
|
klass_usb_device->open = fu_colorhug_device_open;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fu_colorhug_device_new:
|
* fu_colorhug_device_new:
|
||||||
*
|
*
|
||||||
@ -427,9 +390,9 @@ fu_colorhug_device_set_usb_device (FuColorhugDevice *device,
|
|||||||
FuColorhugDevice *
|
FuColorhugDevice *
|
||||||
fu_colorhug_device_new (GUsbDevice *usb_device)
|
fu_colorhug_device_new (GUsbDevice *usb_device)
|
||||||
{
|
{
|
||||||
g_autoptr(FuColorhugDevice) device = NULL;
|
FuColorhugDevice *device = NULL;
|
||||||
device = g_object_new (FU_TYPE_COLORHUG_DEVICE, NULL);
|
device = g_object_new (FU_TYPE_COLORHUG_DEVICE,
|
||||||
if (!fu_colorhug_device_set_usb_device (device, usb_device, NULL))
|
"usb-device", usb_device,
|
||||||
return NULL;
|
NULL);
|
||||||
return g_steal_pointer (&device);
|
return device;
|
||||||
}
|
}
|
||||||
|
@ -30,23 +30,17 @@
|
|||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define FU_TYPE_COLORHUG_DEVICE (fu_colorhug_device_get_type ())
|
#define FU_TYPE_COLORHUG_DEVICE (fu_colorhug_device_get_type ())
|
||||||
G_DECLARE_DERIVABLE_TYPE (FuColorhugDevice, fu_colorhug_device, FU, COLORHUG_DEVICE, FuDevice)
|
G_DECLARE_DERIVABLE_TYPE (FuColorhugDevice, fu_colorhug_device, FU, COLORHUG_DEVICE, FuUsbDevice)
|
||||||
|
|
||||||
struct _FuColorhugDeviceClass
|
struct _FuColorhugDeviceClass
|
||||||
{
|
{
|
||||||
FuDeviceClass parent_class;
|
FuUsbDeviceClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
FuColorhugDevice *fu_colorhug_device_new (GUsbDevice *usb_device);
|
FuColorhugDevice *fu_colorhug_device_new (GUsbDevice *usb_device);
|
||||||
gboolean fu_colorhug_device_set_usb_device (FuColorhugDevice *device,
|
|
||||||
GUsbDevice *usb_device,
|
|
||||||
GError **error);
|
|
||||||
GUsbDevice *fu_colorhug_device_get_usb_device (FuColorhugDevice *device);
|
|
||||||
gboolean fu_colorhug_device_get_is_bootloader (FuColorhugDevice *device);
|
gboolean fu_colorhug_device_get_is_bootloader (FuColorhugDevice *device);
|
||||||
|
|
||||||
/* object methods */
|
/* object methods */
|
||||||
gboolean fu_colorhug_device_open (FuColorhugDevice *device,
|
|
||||||
GError **error);
|
|
||||||
gboolean fu_colorhug_device_close (FuColorhugDevice *device,
|
gboolean fu_colorhug_device_close (FuColorhugDevice *device,
|
||||||
GError **error);
|
GError **error);
|
||||||
gboolean fu_colorhug_device_detach (FuColorhugDevice *device,
|
gboolean fu_colorhug_device_detach (FuColorhugDevice *device,
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <appstream-glib.h>
|
|
||||||
#include <colord.h>
|
#include <colord.h>
|
||||||
#include <colorhug.h>
|
#include <colorhug.h>
|
||||||
|
|
||||||
@ -34,14 +33,12 @@ gboolean
|
|||||||
fu_plugin_update_detach (FuPlugin *plugin, FuDevice *device, GError **error)
|
fu_plugin_update_detach (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuColorhugDevice *colorhug_dev = FU_COLORHUG_DEVICE (device);
|
FuColorhugDevice *colorhug_dev = FU_COLORHUG_DEVICE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
g_autoptr(GUsbDevice) usb_device2 = NULL;
|
g_autoptr(GUsbDevice) usb_device2 = NULL;
|
||||||
|
|
||||||
/* open device */
|
/* open device */
|
||||||
locker = fu_device_locker_new_full (colorhug_dev,
|
locker = fu_device_locker_new (device, error);
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_open,
|
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_close,
|
|
||||||
error);
|
|
||||||
if (locker == NULL)
|
if (locker == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -59,7 +56,7 @@ fu_plugin_update_detach (FuPlugin *plugin, FuDevice *device, GError **error)
|
|||||||
/* wait for replug */
|
/* wait for replug */
|
||||||
g_clear_object (&locker);
|
g_clear_object (&locker);
|
||||||
usb_device2 = g_usb_context_wait_for_replug (fu_plugin_get_usb_context (plugin),
|
usb_device2 = g_usb_context_wait_for_replug (fu_plugin_get_usb_context (plugin),
|
||||||
fu_colorhug_device_get_usb_device (colorhug_dev),
|
usb_device,
|
||||||
10000, error);
|
10000, error);
|
||||||
if (usb_device2 == NULL) {
|
if (usb_device2 == NULL) {
|
||||||
g_prefix_error (error, "device did not come back: ");
|
g_prefix_error (error, "device did not come back: ");
|
||||||
@ -67,7 +64,7 @@ fu_plugin_update_detach (FuPlugin *plugin, FuDevice *device, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set the new device until we can use a new FuDevice */
|
/* set the new device until we can use a new FuDevice */
|
||||||
fu_colorhug_device_set_usb_device (colorhug_dev, usb_device2, NULL);
|
fu_usb_device_set_dev (FU_USB_DEVICE (colorhug_dev), usb_device2);
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -77,14 +74,12 @@ gboolean
|
|||||||
fu_plugin_update_attach (FuPlugin *plugin, FuDevice *device, GError **error)
|
fu_plugin_update_attach (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuColorhugDevice *colorhug_dev = FU_COLORHUG_DEVICE (device);
|
FuColorhugDevice *colorhug_dev = FU_COLORHUG_DEVICE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
g_autoptr(GUsbDevice) usb_device2 = NULL;
|
g_autoptr(GUsbDevice) usb_device2 = NULL;
|
||||||
|
|
||||||
/* open device */
|
/* open device */
|
||||||
locker = fu_device_locker_new_full (colorhug_dev,
|
locker = fu_device_locker_new (device, error);
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_open,
|
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_close,
|
|
||||||
error);
|
|
||||||
if (locker == NULL)
|
if (locker == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -102,7 +97,7 @@ fu_plugin_update_attach (FuPlugin *plugin, FuDevice *device, GError **error)
|
|||||||
/* wait for replug */
|
/* wait for replug */
|
||||||
g_clear_object (&locker);
|
g_clear_object (&locker);
|
||||||
usb_device2 = g_usb_context_wait_for_replug (fu_plugin_get_usb_context (plugin),
|
usb_device2 = g_usb_context_wait_for_replug (fu_plugin_get_usb_context (plugin),
|
||||||
fu_colorhug_device_get_usb_device (colorhug_dev),
|
usb_device,
|
||||||
10000, error);
|
10000, error);
|
||||||
if (usb_device2 == NULL) {
|
if (usb_device2 == NULL) {
|
||||||
g_prefix_error (error, "device did not come back: ");
|
g_prefix_error (error, "device did not come back: ");
|
||||||
@ -110,7 +105,7 @@ fu_plugin_update_attach (FuPlugin *plugin, FuDevice *device, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set the new device until we can use a new FuDevice */
|
/* set the new device until we can use a new FuDevice */
|
||||||
fu_colorhug_device_set_usb_device (colorhug_dev, usb_device2, NULL);
|
fu_usb_device_set_dev (FU_USB_DEVICE (colorhug_dev), usb_device2);
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -123,10 +118,7 @@ fu_plugin_update_reload (FuPlugin *plugin, FuDevice *device, GError **error)
|
|||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
|
|
||||||
/* also set flash success */
|
/* also set flash success */
|
||||||
locker = fu_device_locker_new_full (colorhug_dev,
|
locker = fu_device_locker_new (device, error);
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_open,
|
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_close,
|
|
||||||
error);
|
|
||||||
if (locker == NULL)
|
if (locker == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!fu_colorhug_device_set_flash_success (colorhug_dev, error))
|
if (!fu_colorhug_device_set_flash_success (colorhug_dev, error))
|
||||||
@ -149,11 +141,12 @@ fu_plugin_update (FuPlugin *plugin,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
FuColorhugDevice *colorhug_dev = FU_COLORHUG_DEVICE (device);
|
FuColorhugDevice *colorhug_dev = FU_COLORHUG_DEVICE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
g_autoptr(GError) error_local = NULL;
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
|
||||||
/* check this firmware is actually for this device */
|
/* check this firmware is actually for this device */
|
||||||
if (!ch_device_check_firmware (fu_colorhug_device_get_usb_device (colorhug_dev),
|
if (!ch_device_check_firmware (usb_device,
|
||||||
g_bytes_get_data (blob_fw, NULL),
|
g_bytes_get_data (blob_fw, NULL),
|
||||||
g_bytes_get_size (blob_fw),
|
g_bytes_get_size (blob_fw),
|
||||||
&error_local)) {
|
&error_local)) {
|
||||||
@ -166,10 +159,7 @@ fu_plugin_update (FuPlugin *plugin,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* write firmware */
|
/* write firmware */
|
||||||
locker = fu_device_locker_new_full (colorhug_dev,
|
locker = fu_device_locker_new (device, error);
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_open,
|
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_close,
|
|
||||||
error);
|
|
||||||
if (locker == NULL)
|
if (locker == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_WRITE);
|
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_WRITE);
|
||||||
@ -189,10 +179,7 @@ fu_plugin_verify (FuPlugin *plugin,
|
|||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
|
|
||||||
/* write firmware */
|
/* write firmware */
|
||||||
locker = fu_device_locker_new_full (colorhug_dev,
|
locker = fu_device_locker_new (device, error);
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_open,
|
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_close,
|
|
||||||
error);
|
|
||||||
if (locker == NULL)
|
if (locker == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_VERIFY);
|
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_VERIFY);
|
||||||
@ -208,10 +195,8 @@ fu_plugin_colorhug_device_added_cb (GUsbContext *ctx,
|
|||||||
FuPlugin *plugin)
|
FuPlugin *plugin)
|
||||||
{
|
{
|
||||||
ChDeviceMode mode;
|
ChDeviceMode mode;
|
||||||
g_autoptr(AsProfile) profile = as_profile_new ();
|
|
||||||
g_autoptr(AsProfileTask) ptask = NULL;
|
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
g_autoptr(FuColorhugDevice) dev = NULL;
|
g_autoptr(FuColorhugDevice) device = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
/* ignore */
|
/* ignore */
|
||||||
@ -224,32 +209,17 @@ fu_plugin_colorhug_device_added_cb (GUsbContext *ctx,
|
|||||||
mode == CH_DEVICE_MODE_FIRMWARE_PLUS)
|
mode == CH_DEVICE_MODE_FIRMWARE_PLUS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* profile */
|
|
||||||
ptask = as_profile_start (profile, "FuPluginColorhug:added{%04x:%04x}",
|
|
||||||
g_usb_device_get_vid (usb_device),
|
|
||||||
g_usb_device_get_pid (usb_device));
|
|
||||||
g_assert (ptask != NULL);
|
|
||||||
|
|
||||||
/* create the device */
|
|
||||||
dev = fu_colorhug_device_new (usb_device);
|
|
||||||
if (dev == NULL) {
|
|
||||||
g_warning ("invalid device type detected!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open the device */
|
/* open the device */
|
||||||
locker = fu_device_locker_new_full (dev,
|
device = fu_colorhug_device_new (usb_device);
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_open,
|
locker = fu_device_locker_new (device, &error);
|
||||||
(FuDeviceLockerFunc) fu_colorhug_device_close,
|
|
||||||
&error);
|
|
||||||
if (locker == NULL) {
|
if (locker == NULL) {
|
||||||
g_warning ("failed to open device: %s", error->message);
|
g_warning ("failed to open device: %s", error->message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* insert to hash */
|
/* insert to hash */
|
||||||
fu_plugin_device_add (plugin, FU_DEVICE (dev));
|
fu_plugin_device_add (plugin, FU_DEVICE (device));
|
||||||
fu_plugin_cache_add (plugin, g_usb_device_get_platform_id (usb_device), dev);
|
fu_plugin_cache_add (plugin, g_usb_device_get_platform_id (usb_device), device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -257,16 +227,16 @@ fu_plugin_colorhug_device_removed_cb (GUsbContext *ctx,
|
|||||||
GUsbDevice *usb_device,
|
GUsbDevice *usb_device,
|
||||||
FuPlugin *plugin)
|
FuPlugin *plugin)
|
||||||
{
|
{
|
||||||
FuDevice *dev;
|
FuDevice *device;
|
||||||
const gchar *platform_id = NULL;
|
const gchar *platform_id = NULL;
|
||||||
|
|
||||||
/* already in database */
|
/* already in database */
|
||||||
platform_id = g_usb_device_get_platform_id (usb_device);
|
platform_id = g_usb_device_get_platform_id (usb_device);
|
||||||
dev = fu_plugin_cache_lookup (plugin, platform_id);
|
device = fu_plugin_cache_lookup (plugin, platform_id);
|
||||||
if (dev == NULL)
|
if (device == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fu_plugin_device_remove (plugin, dev);
|
fu_plugin_device_remove (plugin, device);
|
||||||
fu_plugin_cache_remove (plugin, platform_id);
|
fu_plugin_cache_remove (plugin, platform_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
|
* Copyright (C) 2016-2017 Richard Hughes <richard@hughsie.com>
|
||||||
*
|
*
|
||||||
* Licensed under the GNU Lesser General Public License Version 2.1
|
* Licensed under the GNU Lesser General Public License Version 2.1
|
||||||
*
|
*
|
||||||
@ -30,12 +30,10 @@
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FuEbitdoDeviceKind kind;
|
FuEbitdoDeviceKind kind;
|
||||||
GUsbDevice *usb_device;
|
|
||||||
FuDeviceLocker *usb_device_locker;
|
|
||||||
guint32 serial[9];
|
guint32 serial[9];
|
||||||
} FuEbitdoDevicePrivate;
|
} FuEbitdoDevicePrivate;
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (FuEbitdoDevice, fu_ebitdo_device, FU_TYPE_DEVICE)
|
G_DEFINE_TYPE_WITH_PRIVATE (FuEbitdoDevice, fu_ebitdo_device, FU_TYPE_USB_DEVICE)
|
||||||
|
|
||||||
#define GET_PRIVATE(o) (fu_ebitdo_device_get_instance_private (o))
|
#define GET_PRIVATE(o) (fu_ebitdo_device_get_instance_private (o))
|
||||||
|
|
||||||
@ -103,32 +101,6 @@ fu_ebitdo_device_kind_to_string (FuEbitdoDeviceKind kind)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
fu_ebitdo_device_finalize (GObject *object)
|
|
||||||
{
|
|
||||||
FuEbitdoDevice *device = FU_EBITDO_DEVICE (object);
|
|
||||||
FuEbitdoDevicePrivate *priv = GET_PRIVATE (device);
|
|
||||||
|
|
||||||
if (priv->usb_device_locker != NULL)
|
|
||||||
g_object_unref (priv->usb_device_locker);
|
|
||||||
if (priv->usb_device != NULL)
|
|
||||||
g_object_unref (priv->usb_device);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (fu_ebitdo_device_parent_class)->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fu_ebitdo_device_init (FuEbitdoDevice *device)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fu_ebitdo_device_class_init (FuEbitdoDeviceClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
object_class->finalize = fu_ebitdo_device_finalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
FuEbitdoDeviceKind
|
FuEbitdoDeviceKind
|
||||||
fu_ebitdo_device_get_kind (FuEbitdoDevice *device)
|
fu_ebitdo_device_get_kind (FuEbitdoDevice *device)
|
||||||
{
|
{
|
||||||
@ -146,6 +118,7 @@ fu_ebitdo_device_send (FuEbitdoDevice *device,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
FuEbitdoDevicePrivate *priv = GET_PRIVATE (device);
|
FuEbitdoDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
guint8 packet[FU_EBITDO_USB_EP_SIZE];
|
guint8 packet[FU_EBITDO_USB_EP_SIZE];
|
||||||
gsize actual_length;
|
gsize actual_length;
|
||||||
guint8 ep_out = FU_EBITDO_USB_RUNTIME_EP_OUT;
|
guint8 ep_out = FU_EBITDO_USB_RUNTIME_EP_OUT;
|
||||||
@ -190,7 +163,7 @@ fu_ebitdo_device_send (FuEbitdoDevice *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get data from device */
|
/* get data from device */
|
||||||
if (!g_usb_device_interrupt_transfer (priv->usb_device,
|
if (!g_usb_device_interrupt_transfer (usb_device,
|
||||||
ep_out,
|
ep_out,
|
||||||
packet,
|
packet,
|
||||||
FU_EBITDO_USB_EP_SIZE,
|
FU_EBITDO_USB_EP_SIZE,
|
||||||
@ -216,6 +189,7 @@ fu_ebitdo_device_receive (FuEbitdoDevice *device,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
FuEbitdoDevicePrivate *priv = GET_PRIVATE (device);
|
FuEbitdoDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
guint8 packet[FU_EBITDO_USB_EP_SIZE];
|
guint8 packet[FU_EBITDO_USB_EP_SIZE];
|
||||||
gsize actual_length;
|
gsize actual_length;
|
||||||
guint8 ep_in = FU_EBITDO_USB_RUNTIME_EP_IN;
|
guint8 ep_in = FU_EBITDO_USB_RUNTIME_EP_IN;
|
||||||
@ -228,7 +202,7 @@ fu_ebitdo_device_receive (FuEbitdoDevice *device,
|
|||||||
|
|
||||||
/* get data from device */
|
/* get data from device */
|
||||||
memset (packet, 0x0, sizeof(packet));
|
memset (packet, 0x0, sizeof(packet));
|
||||||
if (!g_usb_device_interrupt_transfer (priv->usb_device,
|
if (!g_usb_device_interrupt_transfer (usb_device,
|
||||||
ep_in,
|
ep_in,
|
||||||
packet,
|
packet,
|
||||||
FU_EBITDO_USB_EP_SIZE,
|
FU_EBITDO_USB_EP_SIZE,
|
||||||
@ -342,7 +316,7 @@ fu_ebitdo_device_set_version (FuEbitdoDevice *device, guint32 version)
|
|||||||
static gboolean
|
static gboolean
|
||||||
fu_ebitdo_device_validate (FuEbitdoDevice *device, GError **error)
|
fu_ebitdo_device_validate (FuEbitdoDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuEbitdoDevicePrivate *priv = GET_PRIVATE (device);
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
guint8 idx;
|
guint8 idx;
|
||||||
g_autofree gchar *ven = NULL;
|
g_autofree gchar *ven = NULL;
|
||||||
const gchar *whitelist[] = {
|
const gchar *whitelist[] = {
|
||||||
@ -351,12 +325,12 @@ fu_ebitdo_device_validate (FuEbitdoDevice *device, GError **error)
|
|||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
/* this is a new, always valid, VID */
|
/* this is a new, always valid, VID */
|
||||||
if (g_usb_device_get_vid (priv->usb_device) == 0x2dc8)
|
if (g_usb_device_get_vid (usb_device) == 0x2dc8)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* verify the vendor prefix against a whitelist */
|
/* verify the vendor prefix against a whitelist */
|
||||||
idx = g_usb_device_get_manufacturer_index (priv->usb_device);
|
idx = g_usb_device_get_manufacturer_index (usb_device);
|
||||||
ven = g_usb_device_get_string_descriptor (priv->usb_device, idx, error);
|
ven = g_usb_device_get_string_descriptor (usb_device, idx, error);
|
||||||
if (ven == NULL) {
|
if (ven == NULL) {
|
||||||
g_prefix_error (error, "could not check vendor descriptor: ");
|
g_prefix_error (error, "could not check vendor descriptor: ");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -373,27 +347,21 @@ fu_ebitdo_device_validate (FuEbitdoDevice *device, GError **error)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
fu_ebitdo_device_open (FuEbitdoDevice *device, GError **error)
|
fu_ebitdo_device_open (FuUsbDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuEbitdoDevicePrivate *priv = GET_PRIVATE (device);
|
FuEbitdoDevice *self = FU_EBITDO_DEVICE (device);
|
||||||
|
FuEbitdoDevicePrivate *priv = GET_PRIVATE (self);
|
||||||
|
GUsbDevice *usb_device = fu_usb_device_get_dev (device);
|
||||||
gdouble tmp;
|
gdouble tmp;
|
||||||
guint32 version_tmp = 0;
|
guint32 version_tmp = 0;
|
||||||
guint32 serial_tmp[9];
|
guint32 serial_tmp[9];
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
|
||||||
|
|
||||||
/* already open */
|
|
||||||
if (priv->usb_device_locker != NULL)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* open, then ensure this is actually 8Bitdo hardware */
|
/* open, then ensure this is actually 8Bitdo hardware */
|
||||||
g_debug ("opening %s", fu_ebitdo_device_kind_to_string (priv->kind));
|
g_debug ("opening %s", fu_ebitdo_device_kind_to_string (priv->kind));
|
||||||
locker = fu_device_locker_new (priv->usb_device, error);
|
if (!fu_ebitdo_device_validate (self, error))
|
||||||
if (locker == NULL)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!fu_ebitdo_device_validate (device, error))
|
if (!g_usb_device_claim_interface (usb_device, 0, /* 0 = idx? */
|
||||||
return FALSE;
|
|
||||||
if (!g_usb_device_claim_interface (priv->usb_device, 0, /* 0 = idx? */
|
|
||||||
G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
|
G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
|
||||||
error)) {
|
error)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -401,7 +369,7 @@ fu_ebitdo_device_open (FuEbitdoDevice *device, GError **error)
|
|||||||
|
|
||||||
/* in firmware mode */
|
/* in firmware mode */
|
||||||
if (priv->kind != FU_EBITDO_DEVICE_KIND_BOOTLOADER) {
|
if (priv->kind != FU_EBITDO_DEVICE_KIND_BOOTLOADER) {
|
||||||
if (!fu_ebitdo_device_send (device,
|
if (!fu_ebitdo_device_send (self,
|
||||||
FU_EBITDO_PKT_TYPE_USER_CMD,
|
FU_EBITDO_PKT_TYPE_USER_CMD,
|
||||||
FU_EBITDO_PKT_CMD_GET_VERSION,
|
FU_EBITDO_PKT_CMD_GET_VERSION,
|
||||||
0,
|
0,
|
||||||
@ -409,19 +377,19 @@ fu_ebitdo_device_open (FuEbitdoDevice *device, GError **error)
|
|||||||
error)) {
|
error)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!fu_ebitdo_device_receive (device,
|
if (!fu_ebitdo_device_receive (self,
|
||||||
(guint8 *) &version_tmp,
|
(guint8 *) &version_tmp,
|
||||||
sizeof(version_tmp),
|
sizeof(version_tmp),
|
||||||
error)) {
|
error)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
tmp = (gdouble) GUINT32_FROM_LE (version_tmp);
|
tmp = (gdouble) GUINT32_FROM_LE (version_tmp);
|
||||||
fu_ebitdo_device_set_version (device, tmp);
|
fu_ebitdo_device_set_version (self, tmp);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get version */
|
/* get version */
|
||||||
if (!fu_ebitdo_device_send (device,
|
if (!fu_ebitdo_device_send (self,
|
||||||
FU_EBITDO_PKT_TYPE_USER_CMD,
|
FU_EBITDO_PKT_TYPE_USER_CMD,
|
||||||
FU_EBITDO_PKT_CMD_UPDATE_FIRMWARE_DATA,
|
FU_EBITDO_PKT_CMD_UPDATE_FIRMWARE_DATA,
|
||||||
FU_EBITDO_PKT_CMD_FW_GET_VERSION,
|
FU_EBITDO_PKT_CMD_FW_GET_VERSION,
|
||||||
@ -429,17 +397,17 @@ fu_ebitdo_device_open (FuEbitdoDevice *device, GError **error)
|
|||||||
error)) {
|
error)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!fu_ebitdo_device_receive (device,
|
if (!fu_ebitdo_device_receive (self,
|
||||||
(guint8 *) &version_tmp,
|
(guint8 *) &version_tmp,
|
||||||
sizeof(version_tmp),
|
sizeof(version_tmp),
|
||||||
error)) {
|
error)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
tmp = (gdouble) GUINT32_FROM_LE (version_tmp);
|
tmp = (gdouble) GUINT32_FROM_LE (version_tmp);
|
||||||
fu_ebitdo_device_set_version (device, tmp);
|
fu_ebitdo_device_set_version (self, tmp);
|
||||||
|
|
||||||
/* get verification ID */
|
/* get verification ID */
|
||||||
if (!fu_ebitdo_device_send (device,
|
if (!fu_ebitdo_device_send (self,
|
||||||
FU_EBITDO_PKT_TYPE_USER_CMD,
|
FU_EBITDO_PKT_TYPE_USER_CMD,
|
||||||
FU_EBITDO_PKT_CMD_GET_VERIFICATION_ID,
|
FU_EBITDO_PKT_CMD_GET_VERIFICATION_ID,
|
||||||
0x00, /* cmd */
|
0x00, /* cmd */
|
||||||
@ -448,7 +416,7 @@ fu_ebitdo_device_open (FuEbitdoDevice *device, GError **error)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
memset (serial_tmp, 0x00, sizeof (serial_tmp));
|
memset (serial_tmp, 0x00, sizeof (serial_tmp));
|
||||||
if (!fu_ebitdo_device_receive (device,
|
if (!fu_ebitdo_device_receive (self,
|
||||||
(guint8 *) &serial_tmp, sizeof(serial_tmp),
|
(guint8 *) &serial_tmp, sizeof(serial_tmp),
|
||||||
error)) {
|
error)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -457,15 +425,6 @@ fu_ebitdo_device_open (FuEbitdoDevice *device, GError **error)
|
|||||||
priv->serial[i] = GUINT32_FROM_LE (serial_tmp[i]);
|
priv->serial[i] = GUINT32_FROM_LE (serial_tmp[i]);
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
priv->usb_device_locker = g_steal_pointer (&locker);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
fu_ebitdo_device_close (FuEbitdoDevice *device, GError **error)
|
|
||||||
{
|
|
||||||
FuEbitdoDevicePrivate *priv = GET_PRIVATE (device);
|
|
||||||
g_clear_object (&priv->usb_device_locker);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,17 +605,11 @@ static void
|
|||||||
fu_ebitdo_device_init_real (FuEbitdoDevice *device)
|
fu_ebitdo_device_init_real (FuEbitdoDevice *device)
|
||||||
{
|
{
|
||||||
FuEbitdoDevicePrivate *priv = GET_PRIVATE (device);
|
FuEbitdoDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
g_autofree gchar *devid1 = NULL;
|
|
||||||
g_autofree gchar *name = NULL;
|
g_autofree gchar *name = NULL;
|
||||||
g_autofree gchar *vendor_id = NULL;
|
|
||||||
|
|
||||||
/* allowed, but requires manual bootloader step */
|
/* allowed, but requires manual bootloader step */
|
||||||
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE);
|
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||||
|
|
||||||
/* set USB platform ID */
|
|
||||||
fu_device_set_platform_id (FU_DEVICE (device),
|
|
||||||
g_usb_device_get_platform_id (priv->usb_device));
|
|
||||||
|
|
||||||
/* set name and vendor */
|
/* set name and vendor */
|
||||||
name = g_strdup_printf ("%s Gamepad",
|
name = g_strdup_printf ("%s Gamepad",
|
||||||
fu_ebitdo_device_kind_to_string (priv->kind));
|
fu_ebitdo_device_kind_to_string (priv->kind));
|
||||||
@ -665,20 +618,9 @@ fu_ebitdo_device_init_real (FuEbitdoDevice *device)
|
|||||||
"A redesigned classic game controller");
|
"A redesigned classic game controller");
|
||||||
fu_device_set_vendor (FU_DEVICE (device), "8Bitdo");
|
fu_device_set_vendor (FU_DEVICE (device), "8Bitdo");
|
||||||
|
|
||||||
/* set vendor ID */
|
|
||||||
vendor_id = g_strdup_printf ("USB:0x%04X", g_usb_device_get_vid (priv->usb_device));
|
|
||||||
fu_device_set_vendor_id (FU_DEVICE (device), vendor_id);
|
|
||||||
|
|
||||||
/* add a hardcoded icon name */
|
/* add a hardcoded icon name */
|
||||||
fu_device_add_icon (FU_DEVICE (device), "input-gaming");
|
fu_device_add_icon (FU_DEVICE (device), "input-gaming");
|
||||||
|
|
||||||
/* add USB\VID_0000&PID_0000 */
|
|
||||||
devid1 = g_strdup_printf ("USB\\VID_%04X&PID_%04X",
|
|
||||||
g_usb_device_get_vid (priv->usb_device),
|
|
||||||
g_usb_device_get_pid (priv->usb_device));
|
|
||||||
fu_device_add_guid (FU_DEVICE (device), devid1);
|
|
||||||
g_debug ("saving runtime GUID of %s", devid1);
|
|
||||||
|
|
||||||
/* only the bootloader can do the update */
|
/* only the bootloader can do the update */
|
||||||
if (priv->kind != FU_EBITDO_DEVICE_KIND_BOOTLOADER) {
|
if (priv->kind != FU_EBITDO_DEVICE_KIND_BOOTLOADER) {
|
||||||
fu_device_add_flag (FU_DEVICE (device),
|
fu_device_add_flag (FU_DEVICE (device),
|
||||||
@ -692,12 +634,9 @@ typedef struct {
|
|||||||
FuEbitdoDeviceKind kind;
|
FuEbitdoDeviceKind kind;
|
||||||
} FuEbitdoVidPid;
|
} FuEbitdoVidPid;
|
||||||
|
|
||||||
gboolean
|
FuEbitdoDeviceKind
|
||||||
fu_ebitdo_device_set_usb_device (FuEbitdoDevice *device,
|
fu_ebitdo_device_kind_from_dev (GUsbDevice *usb_device)
|
||||||
GUsbDevice *usb_device,
|
|
||||||
GError **error)
|
|
||||||
{
|
{
|
||||||
FuEbitdoDevicePrivate *priv = GET_PRIVATE (device);
|
|
||||||
const FuEbitdoVidPid vidpids[] = {
|
const FuEbitdoVidPid vidpids[] = {
|
||||||
/* legacy VIDs */
|
/* legacy VIDs */
|
||||||
{ 0x0483, 0x5750, FU_EBITDO_DEVICE_KIND_BOOTLOADER },
|
{ 0x0483, 0x5750, FU_EBITDO_DEVICE_KIND_BOOTLOADER },
|
||||||
@ -722,22 +661,23 @@ fu_ebitdo_device_set_usb_device (FuEbitdoDevice *device,
|
|||||||
|
|
||||||
/* find correct kind */
|
/* find correct kind */
|
||||||
for (guint j = 0; vidpids[j].vid != 0x0000; j++) {
|
for (guint j = 0; vidpids[j].vid != 0x0000; j++) {
|
||||||
if (g_usb_device_get_vid (usb_device) != vidpids[j].vid)
|
if (g_usb_device_get_vid (usb_device) == vidpids[j].vid &&
|
||||||
continue;
|
g_usb_device_get_pid (usb_device) == vidpids[j].pid)
|
||||||
if (g_usb_device_get_pid (usb_device) != vidpids[j].pid)
|
return vidpids[j].kind;
|
||||||
continue;
|
}
|
||||||
priv->kind = vidpids[j].kind;
|
return FU_EBITDO_DEVICE_KIND_UNKNOWN;
|
||||||
g_set_object (&priv->usb_device, usb_device);
|
|
||||||
fu_ebitdo_device_init_real (device);
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unsupported */
|
static void
|
||||||
g_set_error_literal (error,
|
fu_ebitdo_device_init (FuEbitdoDevice *device)
|
||||||
G_IO_ERROR,
|
{
|
||||||
G_IO_ERROR_NOT_SUPPORTED,
|
}
|
||||||
"not a supported 8Bitdo game-pad");
|
|
||||||
return FALSE;
|
static void
|
||||||
|
fu_ebitdo_device_class_init (FuEbitdoDeviceClass *klass)
|
||||||
|
{
|
||||||
|
FuUsbDeviceClass *klass_usb_device = FU_USB_DEVICE_CLASS (klass);
|
||||||
|
klass_usb_device->open = fu_ebitdo_device_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -750,11 +690,15 @@ fu_ebitdo_device_set_usb_device (FuEbitdoDevice *device,
|
|||||||
* Since: 0.1.0
|
* Since: 0.1.0
|
||||||
**/
|
**/
|
||||||
FuEbitdoDevice *
|
FuEbitdoDevice *
|
||||||
fu_ebitdo_device_new (GUsbDevice *usb_device)
|
fu_ebitdo_device_new (FuEbitdoDeviceKind kind, GUsbDevice *usb_device)
|
||||||
{
|
{
|
||||||
g_autoptr(FuEbitdoDevice) device = NULL;
|
FuEbitdoDevice *device;
|
||||||
device = g_object_new (FU_TYPE_EBITDO_DEVICE, NULL);
|
FuEbitdoDevicePrivate *priv;
|
||||||
if (!fu_ebitdo_device_set_usb_device (device, usb_device, NULL))
|
device = g_object_new (FU_TYPE_EBITDO_DEVICE,
|
||||||
return NULL;
|
"usb-device", usb_device,
|
||||||
return g_steal_pointer (&device);
|
NULL);
|
||||||
|
priv = GET_PRIVATE (device);
|
||||||
|
priv->kind = kind;
|
||||||
|
fu_ebitdo_device_init_real (device);
|
||||||
|
return FU_EBITDO_DEVICE (device);
|
||||||
}
|
}
|
||||||
|
@ -30,11 +30,11 @@
|
|||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define FU_TYPE_EBITDO_DEVICE (fu_ebitdo_device_get_type ())
|
#define FU_TYPE_EBITDO_DEVICE (fu_ebitdo_device_get_type ())
|
||||||
G_DECLARE_DERIVABLE_TYPE (FuEbitdoDevice, fu_ebitdo_device, FU, EBITDO_DEVICE, FuDevice)
|
G_DECLARE_DERIVABLE_TYPE (FuEbitdoDevice, fu_ebitdo_device, FU, EBITDO_DEVICE, FuUsbDevice)
|
||||||
|
|
||||||
struct _FuEbitdoDeviceClass
|
struct _FuEbitdoDeviceClass
|
||||||
{
|
{
|
||||||
FuDeviceClass parent_class;
|
FuUsbDeviceClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -51,13 +51,12 @@ typedef enum {
|
|||||||
FU_EBITDO_DEVICE_KIND_LAST
|
FU_EBITDO_DEVICE_KIND_LAST
|
||||||
} FuEbitdoDeviceKind;
|
} FuEbitdoDeviceKind;
|
||||||
|
|
||||||
FuEbitdoDevice *fu_ebitdo_device_new (GUsbDevice *usb_device);
|
FuEbitdoDevice *fu_ebitdo_device_new (FuEbitdoDeviceKind kind,
|
||||||
gboolean fu_ebitdo_device_set_usb_device (FuEbitdoDevice *device,
|
GUsbDevice *usb_device);
|
||||||
GUsbDevice *usb_device,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
/* helpers */
|
/* helpers */
|
||||||
FuEbitdoDeviceKind fu_ebitdo_device_kind_from_string (const gchar *kind);
|
FuEbitdoDeviceKind fu_ebitdo_device_kind_from_string (const gchar *kind);
|
||||||
|
FuEbitdoDeviceKind fu_ebitdo_device_kind_from_dev (GUsbDevice *usb_device);
|
||||||
const gchar *fu_ebitdo_device_kind_to_string (FuEbitdoDeviceKind kind);
|
const gchar *fu_ebitdo_device_kind_to_string (FuEbitdoDeviceKind kind);
|
||||||
|
|
||||||
/* getters */
|
/* getters */
|
||||||
@ -65,10 +64,6 @@ FuEbitdoDeviceKind fu_ebitdo_device_get_kind (FuEbitdoDevice *device);
|
|||||||
const guint32 *fu_ebitdo_device_get_serial (FuEbitdoDevice *device);
|
const guint32 *fu_ebitdo_device_get_serial (FuEbitdoDevice *device);
|
||||||
|
|
||||||
/* object methods */
|
/* object methods */
|
||||||
gboolean fu_ebitdo_device_open (FuEbitdoDevice *device,
|
|
||||||
GError **error);
|
|
||||||
gboolean fu_ebitdo_device_close (FuEbitdoDevice *device,
|
|
||||||
GError **error);
|
|
||||||
gboolean fu_ebitdo_device_write_firmware (FuEbitdoDevice *device,
|
gboolean fu_ebitdo_device_write_firmware (FuEbitdoDevice *device,
|
||||||
GBytes *fw,
|
GBytes *fw,
|
||||||
GFileProgressCallback progress_cb,
|
GFileProgressCallback progress_cb,
|
||||||
|
@ -65,10 +65,11 @@ main (int argc, char **argv)
|
|||||||
g_usb_context_enumerate (usb_ctx);
|
g_usb_context_enumerate (usb_ctx);
|
||||||
devices = g_usb_context_get_devices (usb_ctx);
|
devices = g_usb_context_get_devices (usb_ctx);
|
||||||
for (guint i = 0; i < devices->len; i++) {
|
for (guint i = 0; i < devices->len; i++) {
|
||||||
GUsbDevice *usb_dev_tmp = g_ptr_array_index (devices, i);
|
GUsbDevice *usb_device = g_ptr_array_index (devices, i);
|
||||||
g_autoptr(FuEbitdoDevice) dev_tmp = fu_ebitdo_device_new (usb_dev_tmp);
|
FuEbitdoDeviceKind ebitdo_kind;
|
||||||
if (dev_tmp != NULL) {
|
ebitdo_kind = fu_ebitdo_device_kind_from_dev (usb_device);
|
||||||
dev = g_object_ref (dev_tmp);
|
if (ebitdo_kind != FU_EBITDO_DEVICE_KIND_UNKNOWN) {
|
||||||
|
dev = fu_ebitdo_device_new (ebitdo_kind, usb_device);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,10 +81,7 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* open device */
|
/* open device */
|
||||||
locker = fu_device_locker_new_full (dev,
|
locker = fu_device_locker_new (dev, &error);
|
||||||
(FuDeviceLockerFunc) fu_ebitdo_device_open,
|
|
||||||
(FuDeviceLockerFunc) fu_ebitdo_device_close,
|
|
||||||
&error);
|
|
||||||
if (locker == NULL) {
|
if (locker == NULL) {
|
||||||
g_print ("Failed to open USB device: %s\n", error->message);
|
g_print ("Failed to open USB device: %s\n", error->message);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <appstream-glib.h>
|
|
||||||
|
|
||||||
#include "fu-ebitdo-device.h"
|
#include "fu-ebitdo-device.h"
|
||||||
|
|
||||||
#include "fu-plugin.h"
|
#include "fu-plugin.h"
|
||||||
@ -36,35 +34,19 @@ fu_plugin_ebitdo_device_added (FuPlugin *plugin,
|
|||||||
FuEbitdoDeviceKind ebitdo_kind;
|
FuEbitdoDeviceKind ebitdo_kind;
|
||||||
const gchar *platform_id = NULL;
|
const gchar *platform_id = NULL;
|
||||||
g_autofree gchar *runtime_id = NULL;
|
g_autofree gchar *runtime_id = NULL;
|
||||||
g_autoptr(AsProfile) profile = as_profile_new ();
|
|
||||||
g_autoptr(AsProfileTask) ptask = NULL;
|
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
g_autoptr(FuEbitdoDevice) dev = NULL;
|
g_autoptr(FuEbitdoDevice) dev = NULL;
|
||||||
|
|
||||||
/* ignore hubs */
|
/* ignore wrong hardware */
|
||||||
ptask = as_profile_start (profile, "FuPluginEbitdo:added{%04x:%04x}",
|
ebitdo_kind = fu_ebitdo_device_kind_from_dev (usb_device);
|
||||||
g_usb_device_get_vid (usb_device),
|
if (ebitdo_kind == FU_EBITDO_DEVICE_KIND_UNKNOWN)
|
||||||
g_usb_device_get_pid (usb_device));
|
return TRUE;
|
||||||
g_assert (ptask != NULL);
|
|
||||||
|
|
||||||
/* create the device */
|
|
||||||
dev = fu_ebitdo_device_new (usb_device);
|
|
||||||
if (dev == NULL) {
|
|
||||||
g_set_error_literal (error,
|
|
||||||
FWUPD_ERROR,
|
|
||||||
FWUPD_ERROR_NOT_SUPPORTED,
|
|
||||||
"invalid 8Bitdo device type detected");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open the device */
|
/* open the device */
|
||||||
locker = fu_device_locker_new_full (dev,
|
dev = fu_ebitdo_device_new (ebitdo_kind, usb_device);
|
||||||
(FuDeviceLockerFunc) fu_ebitdo_device_open,
|
locker = fu_device_locker_new (dev, error);
|
||||||
(FuDeviceLockerFunc) fu_ebitdo_device_close,
|
|
||||||
error);
|
|
||||||
if (locker == NULL)
|
if (locker == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
ebitdo_kind = fu_ebitdo_device_get_kind (dev);
|
|
||||||
|
|
||||||
/* only the bootloader can do the update */
|
/* only the bootloader can do the update */
|
||||||
platform_id = g_usb_device_get_platform_id (usb_device);
|
platform_id = g_usb_device_get_platform_id (usb_device);
|
||||||
@ -108,18 +90,12 @@ fu_plugin_update (FuPlugin *plugin,
|
|||||||
FwupdInstallFlags flags,
|
FwupdInstallFlags flags,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GUsbContext *usb_ctx = fu_plugin_get_usb_context (plugin);
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (dev));
|
||||||
FuEbitdoDevice *ebitdo_dev = FU_EBITDO_DEVICE (dev);
|
FuEbitdoDevice *ebitdo_dev = FU_EBITDO_DEVICE (dev);
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
g_autoptr(GUsbDevice) usb_device = NULL;
|
|
||||||
g_autoptr(GUsbDevice) usb_device2 = NULL;
|
g_autoptr(GUsbDevice) usb_device2 = NULL;
|
||||||
|
|
||||||
/* get version */
|
/* get version */
|
||||||
usb_device = g_usb_context_find_by_platform_id (usb_ctx,
|
|
||||||
fu_device_get_platform_id (dev),
|
|
||||||
error);
|
|
||||||
if (usb_device == NULL)
|
|
||||||
return FALSE;
|
|
||||||
if (fu_ebitdo_device_get_kind (ebitdo_dev) != FU_EBITDO_DEVICE_KIND_BOOTLOADER) {
|
if (fu_ebitdo_device_get_kind (ebitdo_dev) != FU_EBITDO_DEVICE_KIND_BOOTLOADER) {
|
||||||
g_set_error_literal (error,
|
g_set_error_literal (error,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
@ -129,10 +105,7 @@ fu_plugin_update (FuPlugin *plugin,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* write the firmware */
|
/* write the firmware */
|
||||||
locker = fu_device_locker_new_full (ebitdo_dev,
|
locker = fu_device_locker_new (ebitdo_dev, error);
|
||||||
(FuDeviceLockerFunc) fu_ebitdo_device_open,
|
|
||||||
(FuDeviceLockerFunc) fu_ebitdo_device_close,
|
|
||||||
error);
|
|
||||||
if (locker == NULL)
|
if (locker == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_WRITE);
|
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_WRITE);
|
||||||
@ -155,10 +128,7 @@ fu_plugin_update (FuPlugin *plugin,
|
|||||||
g_prefix_error (error, "device did not come back: ");
|
g_prefix_error (error, "device did not come back: ");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!fu_ebitdo_device_set_usb_device (ebitdo_dev, usb_device2, error)) {
|
fu_usb_device_set_dev (FU_USB_DEVICE (ebitdo_dev), usb_device2);
|
||||||
g_prefix_error (error, "wrong device came back: ");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -171,10 +141,7 @@ fu_plugin_update_reload (FuPlugin *plugin, FuDevice *dev, GError **error)
|
|||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
|
|
||||||
/* get the new version number */
|
/* get the new version number */
|
||||||
locker = fu_device_locker_new_full (ebitdo_dev,
|
locker = fu_device_locker_new (ebitdo_dev, error);
|
||||||
(FuDeviceLockerFunc) fu_ebitdo_device_open,
|
|
||||||
(FuDeviceLockerFunc) fu_ebitdo_device_close,
|
|
||||||
error);
|
|
||||||
if (locker == NULL) {
|
if (locker == NULL) {
|
||||||
g_prefix_error (error, "failed to re-open device: ");
|
g_prefix_error (error, "failed to re-open device: ");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
|
* Copyright (C) 2016-2017 Richard Hughes <richard@hughsie.com>
|
||||||
*
|
*
|
||||||
* Licensed under the GNU Lesser General Public License Version 2.1
|
* Licensed under the GNU Lesser General Public License Version 2.1
|
||||||
*
|
*
|
||||||
@ -27,15 +27,7 @@
|
|||||||
#include "fu-nitrokey-common.h"
|
#include "fu-nitrokey-common.h"
|
||||||
#include "fu-nitrokey-device.h"
|
#include "fu-nitrokey-device.h"
|
||||||
|
|
||||||
typedef struct
|
G_DEFINE_TYPE (FuNitrokeyDevice, fu_nitrokey_device, FU_TYPE_USB_DEVICE)
|
||||||
{
|
|
||||||
GUsbDevice *usb_device;
|
|
||||||
FuDeviceLocker *usb_device_locker;
|
|
||||||
} FuNitrokeyDevicePrivate;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (FuNitrokeyDevice, fu_nitrokey_device, FU_TYPE_DEVICE)
|
|
||||||
|
|
||||||
#define GET_PRIVATE(o) (fu_nitrokey_device_get_instance_private (o))
|
|
||||||
|
|
||||||
#define NITROKEY_TRANSACTION_TIMEOUT 100 /* ms */
|
#define NITROKEY_TRANSACTION_TIMEOUT 100 /* ms */
|
||||||
#define NITROKEY_NR_RETRIES 5
|
#define NITROKEY_NR_RETRIES 5
|
||||||
@ -87,33 +79,6 @@ typedef struct __attribute__((packed)) {
|
|||||||
guint8 StickKeysNotInitiated;
|
guint8 StickKeysNotInitiated;
|
||||||
} NitrokeyGetDeviceStatusPayload;
|
} NitrokeyGetDeviceStatusPayload;
|
||||||
|
|
||||||
static void
|
|
||||||
fu_nitrokey_device_finalize (GObject *object)
|
|
||||||
{
|
|
||||||
FuNitrokeyDevice *device = FU_NITROKEY_DEVICE (object);
|
|
||||||
FuNitrokeyDevicePrivate *priv = GET_PRIVATE (device);
|
|
||||||
|
|
||||||
if (priv->usb_device_locker != NULL)
|
|
||||||
g_object_unref (priv->usb_device_locker);
|
|
||||||
if (priv->usb_device != NULL)
|
|
||||||
g_object_unref (priv->usb_device);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (fu_nitrokey_device_parent_class)->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fu_nitrokey_device_init (FuNitrokeyDevice *device)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fu_nitrokey_device_class_init (FuNitrokeyDeviceClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
object_class->finalize = fu_nitrokey_device_finalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_dump_to_console (const gchar *title, const guint8 *buf, gsize buf_sz)
|
_dump_to_console (const gchar *title, const guint8 *buf, gsize buf_sz)
|
||||||
{
|
{
|
||||||
@ -258,29 +223,18 @@ nitrokey_execute_cmd_full (GUsbDevice *usb_device, guint8 command,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
fu_nitrokey_device_open (FuNitrokeyDevice *device, GError **error)
|
fu_nitrokey_device_open (FuUsbDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuNitrokeyDevicePrivate *priv = GET_PRIVATE (device);
|
GUsbDevice *usb_device = fu_usb_device_get_dev (device);
|
||||||
g_autofree gchar *vendor_id = NULL;
|
|
||||||
NitrokeyGetDeviceStatusPayload payload;
|
NitrokeyGetDeviceStatusPayload payload;
|
||||||
const gchar *platform_id = NULL;
|
|
||||||
guint8 buf_reply[NITROKEY_REPLY_DATA_LENGTH];
|
guint8 buf_reply[NITROKEY_REPLY_DATA_LENGTH];
|
||||||
g_autofree gchar *devid1 = NULL;
|
|
||||||
g_autofree gchar *platform_id_fixed = NULL;
|
g_autofree gchar *platform_id_fixed = NULL;
|
||||||
g_autofree gchar *version = NULL;
|
g_autofree gchar *version = NULL;
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
|
||||||
g_autoptr(GError) error_local = NULL;
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
|
||||||
/* already open */
|
/* claim interface */
|
||||||
if (priv->usb_device_locker != NULL)
|
if (!g_usb_device_claim_interface (usb_device, 0x02, /* idx */
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* open, then ensure this is actually 8Bitdo hardware */
|
|
||||||
locker = fu_device_locker_new (priv->usb_device, error);
|
|
||||||
if (locker == NULL)
|
|
||||||
return FALSE;
|
|
||||||
if (!g_usb_device_claim_interface (priv->usb_device, 0x02, /* idx */
|
|
||||||
G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
|
G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
|
||||||
error)) {
|
error)) {
|
||||||
g_prefix_error (error, "failed to do claim nitrokey: ");
|
g_prefix_error (error, "failed to do claim nitrokey: ");
|
||||||
@ -288,7 +242,7 @@ fu_nitrokey_device_open (FuNitrokeyDevice *device, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get firmware version */
|
/* get firmware version */
|
||||||
if (!nitrokey_execute_cmd_full (priv->usb_device,
|
if (!nitrokey_execute_cmd_full (usb_device,
|
||||||
NITROKEY_CMD_GET_DEVICE_STATUS,
|
NITROKEY_CMD_GET_DEVICE_STATUS,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
buf_reply, sizeof(buf_reply),
|
buf_reply, sizeof(buf_reply),
|
||||||
@ -299,12 +253,6 @@ fu_nitrokey_device_open (FuNitrokeyDevice *device, GError **error)
|
|||||||
_dump_to_console ("payload", buf_reply, sizeof(buf_reply));
|
_dump_to_console ("payload", buf_reply, sizeof(buf_reply));
|
||||||
memcpy (&payload, buf_reply, sizeof(buf_reply));
|
memcpy (&payload, buf_reply, sizeof(buf_reply));
|
||||||
|
|
||||||
/* we use a modified version of the platform ID so we can have multiple
|
|
||||||
* FuDeviceItems for the same device -- when we can have the same device
|
|
||||||
* handled by multiple plugins this won't be required... */
|
|
||||||
platform_id = g_usb_device_get_platform_id (priv->usb_device);
|
|
||||||
platform_id_fixed = g_strdup_printf ("%s_workaround", platform_id);
|
|
||||||
fu_device_set_platform_id (FU_DEVICE (device), platform_id_fixed);
|
|
||||||
fu_device_set_name (FU_DEVICE (device), "Nitrokey Storage");
|
fu_device_set_name (FU_DEVICE (device), "Nitrokey Storage");
|
||||||
fu_device_set_vendor (FU_DEVICE (device), "Nitrokey");
|
fu_device_set_vendor (FU_DEVICE (device), "Nitrokey");
|
||||||
fu_device_set_summary (FU_DEVICE (device), "A secure memory stick");
|
fu_device_set_summary (FU_DEVICE (device), "A secure memory stick");
|
||||||
@ -312,54 +260,48 @@ fu_nitrokey_device_open (FuNitrokeyDevice *device, GError **error)
|
|||||||
version = g_strdup_printf ("%u.%u", payload.VersionMinor, payload.VersionMajor);
|
version = g_strdup_printf ("%u.%u", payload.VersionMinor, payload.VersionMajor);
|
||||||
fu_device_set_version (FU_DEVICE (device), version);
|
fu_device_set_version (FU_DEVICE (device), version);
|
||||||
|
|
||||||
/* set vendor ID */
|
|
||||||
vendor_id = g_strdup_printf ("USB:0x%04X", g_usb_device_get_vid (priv->usb_device));
|
|
||||||
fu_device_set_vendor_id (FU_DEVICE (device), vendor_id);
|
|
||||||
|
|
||||||
/* use the USB VID:PID hash */
|
|
||||||
devid1 = g_strdup_printf ("USB\\VID_%04X&PID_%04X",
|
|
||||||
g_usb_device_get_vid (priv->usb_device),
|
|
||||||
g_usb_device_get_pid (priv->usb_device));
|
|
||||||
fu_device_add_guid (FU_DEVICE (device), devid1);
|
|
||||||
|
|
||||||
/* allowed, but requires manual bootloader step */
|
/* allowed, but requires manual bootloader step */
|
||||||
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE);
|
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||||
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER);
|
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER);
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
priv->usb_device_locker = g_steal_pointer (&locker);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
fu_nitrokey_device_close (FuNitrokeyDevice *device, GError **error)
|
fu_nitrokey_device_close (FuUsbDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuNitrokeyDevicePrivate *priv = GET_PRIVATE (device);
|
GUsbDevice *usb_device = fu_usb_device_get_dev (device);
|
||||||
g_autoptr(GError) error_local = NULL;
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
|
||||||
/* reconnect kernel driver */
|
/* reconnect kernel driver */
|
||||||
if (!g_usb_device_release_interface (priv->usb_device, 0x02,
|
if (!g_usb_device_release_interface (usb_device, 0x02,
|
||||||
G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
|
G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
|
||||||
&error_local)) {
|
&error_local)) {
|
||||||
g_warning ("failed to release interface: %s", error_local->message);
|
g_warning ("failed to release interface: %s", error_local->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_clear_object (&priv->usb_device_locker);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fu_nitrokey_device_set_usb_device (FuNitrokeyDevice *device, GUsbDevice *usb_device)
|
fu_nitrokey_device_init (FuNitrokeyDevice *device)
|
||||||
{
|
{
|
||||||
FuNitrokeyDevicePrivate *priv = GET_PRIVATE (device);
|
}
|
||||||
g_set_object (&priv->usb_device, usb_device);
|
|
||||||
|
static void
|
||||||
|
fu_nitrokey_device_class_init (FuNitrokeyDeviceClass *klass)
|
||||||
|
{
|
||||||
|
FuUsbDeviceClass *klass_usb_device = FU_USB_DEVICE_CLASS (klass);
|
||||||
|
klass_usb_device->open = fu_nitrokey_device_open;
|
||||||
|
klass_usb_device->close = fu_nitrokey_device_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
FuNitrokeyDevice *
|
FuNitrokeyDevice *
|
||||||
fu_nitrokey_device_new (GUsbDevice *usb_device)
|
fu_nitrokey_device_new (GUsbDevice *usb_device)
|
||||||
{
|
{
|
||||||
g_autoptr(FuNitrokeyDevice) device = NULL;
|
FuNitrokeyDevice *device;
|
||||||
device = g_object_new (FU_TYPE_NITROKEY_DEVICE, NULL);
|
device = g_object_new (FU_TYPE_NITROKEY_DEVICE,
|
||||||
fu_nitrokey_device_set_usb_device (device, usb_device);
|
"usb-device", usb_device,
|
||||||
return g_steal_pointer (&device);
|
NULL);
|
||||||
|
return FU_NITROKEY_DEVICE (device);
|
||||||
}
|
}
|
||||||
|
@ -30,20 +30,15 @@
|
|||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define FU_TYPE_NITROKEY_DEVICE (fu_nitrokey_device_get_type ())
|
#define FU_TYPE_NITROKEY_DEVICE (fu_nitrokey_device_get_type ())
|
||||||
G_DECLARE_DERIVABLE_TYPE (FuNitrokeyDevice, fu_nitrokey_device, FU, NITROKEY_DEVICE, FuDevice)
|
G_DECLARE_DERIVABLE_TYPE (FuNitrokeyDevice, fu_nitrokey_device, FU, NITROKEY_DEVICE, FuUsbDevice)
|
||||||
|
|
||||||
struct _FuNitrokeyDeviceClass
|
struct _FuNitrokeyDeviceClass
|
||||||
{
|
{
|
||||||
FuDeviceClass parent_class;
|
FuUsbDeviceClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
FuNitrokeyDevice *fu_nitrokey_device_new (GUsbDevice *usb_device);
|
FuNitrokeyDevice *fu_nitrokey_device_new (GUsbDevice *usb_device);
|
||||||
|
|
||||||
gboolean fu_nitrokey_device_open (FuNitrokeyDevice *device,
|
|
||||||
GError **error);
|
|
||||||
gboolean fu_nitrokey_device_close (FuNitrokeyDevice *device,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __FU_NITROKEY_DEVICE_H */
|
#endif /* __FU_NITROKEY_DEVICE_H */
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <appstream-glib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "fu-plugin.h"
|
#include "fu-plugin.h"
|
||||||
@ -36,8 +35,6 @@ fu_plugin_nitrokey_device_added_cb (GUsbContext *ctx,
|
|||||||
FuPlugin *plugin)
|
FuPlugin *plugin)
|
||||||
{
|
{
|
||||||
const gchar *platform_id = NULL;
|
const gchar *platform_id = NULL;
|
||||||
g_autoptr(AsProfile) profile = as_profile_new ();
|
|
||||||
g_autoptr(AsProfileTask) ptask = NULL;
|
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
g_autoptr(FuNitrokeyDevice) dev = NULL;
|
g_autoptr(FuNitrokeyDevice) dev = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
@ -48,12 +45,6 @@ fu_plugin_nitrokey_device_added_cb (GUsbContext *ctx,
|
|||||||
if (g_usb_device_get_pid (usb_device) != 0x4109)
|
if (g_usb_device_get_pid (usb_device) != 0x4109)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* profile */
|
|
||||||
ptask = as_profile_start (profile, "FuPluginNitrokey:added{%04x:%04x}",
|
|
||||||
g_usb_device_get_vid (usb_device),
|
|
||||||
g_usb_device_get_pid (usb_device));
|
|
||||||
g_assert (ptask != NULL);
|
|
||||||
|
|
||||||
/* is already in database */
|
/* is already in database */
|
||||||
platform_id = g_usb_device_get_platform_id (usb_device);
|
platform_id = g_usb_device_get_platform_id (usb_device);
|
||||||
dev = fu_plugin_cache_lookup (plugin, platform_id);
|
dev = fu_plugin_cache_lookup (plugin, platform_id);
|
||||||
@ -64,10 +55,7 @@ fu_plugin_nitrokey_device_added_cb (GUsbContext *ctx,
|
|||||||
|
|
||||||
/* open the device */
|
/* open the device */
|
||||||
dev = fu_nitrokey_device_new (usb_device);
|
dev = fu_nitrokey_device_new (usb_device);
|
||||||
locker = fu_device_locker_new_full (dev,
|
locker = fu_device_locker_new (dev, &error);
|
||||||
(FuDeviceLockerFunc) fu_nitrokey_device_open,
|
|
||||||
(FuDeviceLockerFunc) fu_nitrokey_device_close,
|
|
||||||
&error);
|
|
||||||
if (locker == NULL) {
|
if (locker == NULL) {
|
||||||
g_warning ("failed to open device: %s", error->message);
|
g_warning ("failed to open device: %s", error->message);
|
||||||
return;
|
return;
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <appstream-glib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "fu-plugin.h"
|
#include "fu-plugin.h"
|
||||||
@ -39,10 +38,7 @@ fu_plugin_steelseries_device_added_cb (GUsbContext *ctx,
|
|||||||
gboolean ret;
|
gboolean ret;
|
||||||
gsize actual_len = 0;
|
gsize actual_len = 0;
|
||||||
guint8 data[32];
|
guint8 data[32];
|
||||||
g_autofree gchar *devid1 = NULL;
|
|
||||||
g_autofree gchar *version = NULL;
|
g_autofree gchar *version = NULL;
|
||||||
g_autoptr(AsProfile) profile = as_profile_new ();
|
|
||||||
g_autoptr(AsProfileTask) ptask = NULL;
|
|
||||||
g_autoptr(FuDevice) dev = NULL;
|
g_autoptr(FuDevice) dev = NULL;
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
g_autoptr(GError) error_local = NULL;
|
g_autoptr(GError) error_local = NULL;
|
||||||
@ -53,12 +49,6 @@ fu_plugin_steelseries_device_added_cb (GUsbContext *ctx,
|
|||||||
if (g_usb_device_get_pid (usb_device) != 0x1702)
|
if (g_usb_device_get_pid (usb_device) != 0x1702)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* profile */
|
|
||||||
ptask = as_profile_start (profile, "FuPluginSteelseries:added{%04x:%04x}",
|
|
||||||
g_usb_device_get_vid (usb_device),
|
|
||||||
g_usb_device_get_pid (usb_device));
|
|
||||||
g_assert (ptask != NULL);
|
|
||||||
|
|
||||||
/* is already in database */
|
/* is already in database */
|
||||||
platform_id = g_usb_device_get_platform_id (usb_device);
|
platform_id = g_usb_device_get_platform_id (usb_device);
|
||||||
dev = fu_plugin_cache_lookup (plugin, platform_id);
|
dev = fu_plugin_cache_lookup (plugin, platform_id);
|
||||||
@ -122,8 +112,7 @@ fu_plugin_steelseries_device_added_cb (GUsbContext *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* insert to hash if valid */
|
/* insert to hash if valid */
|
||||||
dev = fu_device_new ();
|
dev = fu_usb_device_new (usb_device);
|
||||||
fu_device_set_id (dev, platform_id);
|
|
||||||
fu_device_set_name (dev, "SteelSeries Rival 100");
|
fu_device_set_name (dev, "SteelSeries Rival 100");
|
||||||
fu_device_set_vendor (dev, "SteelSeries");
|
fu_device_set_vendor (dev, "SteelSeries");
|
||||||
fu_device_set_summary (dev, "An optical gaming mouse");
|
fu_device_set_summary (dev, "An optical gaming mouse");
|
||||||
@ -132,12 +121,6 @@ fu_plugin_steelseries_device_added_cb (GUsbContext *ctx,
|
|||||||
data[0], data[1], data[2]);
|
data[0], data[1], data[2]);
|
||||||
fu_device_set_version (dev, version);
|
fu_device_set_version (dev, version);
|
||||||
|
|
||||||
/* use the USB VID:PID hash */
|
|
||||||
devid1 = g_strdup_printf ("USB\\VID_%04X&PID_%04X",
|
|
||||||
g_usb_device_get_vid (usb_device),
|
|
||||||
g_usb_device_get_pid (usb_device));
|
|
||||||
fu_device_add_guid (dev, devid1);
|
|
||||||
|
|
||||||
/* we're done here */
|
/* we're done here */
|
||||||
if (!g_usb_device_release_interface (usb_device, iface_idx,
|
if (!g_usb_device_release_interface (usb_device, iface_idx,
|
||||||
G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
|
G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
|
* Copyright (C) 2016-2017 Richard Hughes <richard@hughsie.com>
|
||||||
*
|
*
|
||||||
* Licensed under the GNU General Public License Version 2
|
* Licensed under the GNU General Public License Version 2
|
||||||
*
|
*
|
||||||
@ -21,23 +21,9 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <appstream-glib.h>
|
|
||||||
|
|
||||||
#include "fu-plugin.h"
|
#include "fu-plugin.h"
|
||||||
#include "fu-plugin-vfuncs.h"
|
#include "fu-plugin-vfuncs.h"
|
||||||
|
|
||||||
static gchar *
|
|
||||||
_bcd_version_from_uint16 (guint16 val)
|
|
||||||
{
|
|
||||||
#if AS_CHECK_VERSION(0,7,3)
|
|
||||||
return as_utils_version_from_uint16 (val, AS_VERSION_PARSE_FLAG_USE_BCD);
|
|
||||||
#else
|
|
||||||
guint maj = ((val >> 12) & 0x0f) * 10 + ((val >> 8) & 0x0f);
|
|
||||||
guint min = ((val >> 4) & 0x0f) * 10 + (val & 0x0f);
|
|
||||||
return g_strdup_printf ("%u.%u", maj, min);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fu_plugin_usb_device_added_cb (GUsbContext *ctx,
|
fu_plugin_usb_device_added_cb (GUsbContext *ctx,
|
||||||
GUsbDevice *device,
|
GUsbDevice *device,
|
||||||
@ -45,13 +31,7 @@ fu_plugin_usb_device_added_cb (GUsbContext *ctx,
|
|||||||
{
|
{
|
||||||
const gchar *platform_id = NULL;
|
const gchar *platform_id = NULL;
|
||||||
guint8 idx = 0x00;
|
guint8 idx = 0x00;
|
||||||
g_autofree gchar *devid1 = NULL;
|
|
||||||
g_autofree gchar *devid2 = NULL;
|
|
||||||
g_autofree gchar *product = NULL;
|
g_autofree gchar *product = NULL;
|
||||||
g_autofree gchar *vendor_id = NULL;
|
|
||||||
g_autofree gchar *version = NULL;
|
|
||||||
g_autoptr(AsProfile) profile = as_profile_new ();
|
|
||||||
g_autoptr(AsProfileTask) ptask = NULL;
|
|
||||||
g_autoptr(FuDevice) dev = NULL;
|
g_autoptr(FuDevice) dev = NULL;
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
@ -59,10 +39,6 @@ fu_plugin_usb_device_added_cb (GUsbContext *ctx,
|
|||||||
/* ignore hubs */
|
/* ignore hubs */
|
||||||
if (g_usb_device_get_device_class (device) == G_USB_DEVICE_CLASS_HUB)
|
if (g_usb_device_get_device_class (device) == G_USB_DEVICE_CLASS_HUB)
|
||||||
return;
|
return;
|
||||||
ptask = as_profile_start (profile, "FuPluginUsb:added{%04x:%04x}",
|
|
||||||
g_usb_device_get_vid (device),
|
|
||||||
g_usb_device_get_pid (device));
|
|
||||||
g_assert (ptask != NULL);
|
|
||||||
|
|
||||||
/* is already in database */
|
/* is already in database */
|
||||||
platform_id = g_usb_device_get_platform_id (device);
|
platform_id = g_usb_device_get_platform_id (device);
|
||||||
@ -80,38 +56,17 @@ fu_plugin_usb_device_added_cb (GUsbContext *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* insert to hash if valid */
|
/* insert to hash if valid */
|
||||||
dev = fu_device_new ();
|
dev = fu_usb_device_new (device);
|
||||||
fu_device_set_id (dev, platform_id);
|
|
||||||
|
|
||||||
/* get product */
|
|
||||||
idx = g_usb_device_get_product_index (device);
|
|
||||||
if (idx != 0x00) {
|
|
||||||
g_autoptr(AsProfileTask) ptask2 = NULL;
|
|
||||||
ptask2 = as_profile_start_literal (profile, "FuPluginUsb:get-string-desc");
|
|
||||||
g_assert (ptask2 != NULL);
|
|
||||||
product = g_usb_device_get_string_descriptor (device, idx, NULL);
|
|
||||||
}
|
|
||||||
if (product == NULL) {
|
|
||||||
g_debug ("no product string descriptor");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fu_device_set_name (dev, product);
|
|
||||||
|
|
||||||
/* get version number, falling back to the USB device release */
|
/* get version number, falling back to the USB device release */
|
||||||
idx = g_usb_device_get_custom_index (device,
|
idx = g_usb_device_get_custom_index (device,
|
||||||
G_USB_DEVICE_CLASS_VENDOR_SPECIFIC,
|
G_USB_DEVICE_CLASS_VENDOR_SPECIFIC,
|
||||||
'F', 'W', NULL);
|
'F', 'W', NULL);
|
||||||
if (idx != 0x00)
|
if (idx != 0x00) {
|
||||||
|
g_autofree gchar *version = NULL;
|
||||||
version = g_usb_device_get_string_descriptor (device, idx, NULL);
|
version = g_usb_device_get_string_descriptor (device, idx, NULL);
|
||||||
if (version == NULL) {
|
|
||||||
guint16 release = g_usb_device_get_release (device);
|
|
||||||
version = _bcd_version_from_uint16 (release);
|
|
||||||
}
|
|
||||||
fu_device_set_version (dev, version);
|
fu_device_set_version (dev, version);
|
||||||
|
}
|
||||||
/* set vendor ID */
|
|
||||||
vendor_id = g_strdup_printf ("USB:0x%04X", g_usb_device_get_vid (device));
|
|
||||||
fu_device_set_vendor_id (dev, vendor_id);
|
|
||||||
|
|
||||||
/* get GUID from the descriptor if set */
|
/* get GUID from the descriptor if set */
|
||||||
idx = g_usb_device_get_custom_index (device,
|
idx = g_usb_device_get_custom_index (device,
|
||||||
@ -123,17 +78,6 @@ fu_plugin_usb_device_added_cb (GUsbContext *ctx,
|
|||||||
fu_device_add_guid (dev, guid);
|
fu_device_add_guid (dev, guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* also fall back to the USB VID:PID hash */
|
|
||||||
devid1 = g_strdup_printf ("USB\\VID_%04X&PID_%04X",
|
|
||||||
g_usb_device_get_vid (device),
|
|
||||||
g_usb_device_get_pid (device));
|
|
||||||
fu_device_add_guid (dev, devid1);
|
|
||||||
devid2 = g_strdup_printf ("USB\\VID_%04X&PID_%04X&REV_%04X",
|
|
||||||
g_usb_device_get_vid (device),
|
|
||||||
g_usb_device_get_pid (device),
|
|
||||||
g_usb_device_get_release (device));
|
|
||||||
fu_device_add_guid (dev, devid2);
|
|
||||||
|
|
||||||
/* use a small delay for hotplugging so that other, better, plugins
|
/* use a small delay for hotplugging so that other, better, plugins
|
||||||
* can claim this interface and add the FuDevice */
|
* can claim this interface and add the FuDevice */
|
||||||
fu_plugin_device_add_delay (plugin, dev);
|
fu_plugin_device_add_delay (plugin, dev);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <gusb.h>
|
#include <gusb.h>
|
||||||
|
|
||||||
#include "fu-device-locker.h"
|
#include "fu-device-locker.h"
|
||||||
|
#include "fu-usb-device.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:fu-device-locker
|
* SECTION:fu-device-locker
|
||||||
@ -86,8 +87,10 @@ fu_device_locker_init (FuDeviceLocker *self)
|
|||||||
* manually closed using g_clear_object().
|
* manually closed using g_clear_object().
|
||||||
*
|
*
|
||||||
* The functions used for opening and closing the device are set automatically.
|
* The functions used for opening and closing the device are set automatically.
|
||||||
* If the @device is not a type or supertype of @GUsbDevice then this function
|
* If the @device is not a type or supertype of #GUsbDevice or #FuUsbDevice
|
||||||
* will not work. For custom objects please use fu_device_locker_new_full().
|
* then this function will not work.
|
||||||
|
*
|
||||||
|
* For custom objects please use fu_device_locker_new_full().
|
||||||
*
|
*
|
||||||
* NOTE: If the @open_func failed then the @close_func will not be called.
|
* NOTE: If the @open_func failed then the @close_func will not be called.
|
||||||
*
|
*
|
||||||
@ -108,6 +111,14 @@ fu_device_locker_new (gpointer device, GError **error)
|
|||||||
(FuDeviceLockerFunc) g_usb_device_close,
|
(FuDeviceLockerFunc) g_usb_device_close,
|
||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FuUsbDevice */
|
||||||
|
if (FU_IS_USB_DEVICE (device)) {
|
||||||
|
return fu_device_locker_new_full (device,
|
||||||
|
(FuDeviceLockerFunc) fu_usb_device_open,
|
||||||
|
(FuDeviceLockerFunc) fu_usb_device_close,
|
||||||
|
error);
|
||||||
|
}
|
||||||
g_set_error_literal (error,
|
g_set_error_literal (error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_NOT_SUPPORTED,
|
G_IO_ERROR_NOT_SUPPORTED,
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "fu-device-locker.h"
|
#include "fu-device-locker.h"
|
||||||
#include "fu-quirks.h"
|
#include "fu-quirks.h"
|
||||||
#include "fu-hwids.h"
|
#include "fu-hwids.h"
|
||||||
|
#include "fu-usb-device.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
319
src/fu-usb-device.c
Normal file
319
src/fu-usb-device.c
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <appstream-glib.h>
|
||||||
|
|
||||||
|
#include "fu-usb-device.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:fu-device
|
||||||
|
* @short_description: a USB device
|
||||||
|
*
|
||||||
|
* An object that represents a USB device.
|
||||||
|
*
|
||||||
|
* See also: #FuDevice
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GUsbDevice *usb_device;
|
||||||
|
FuDeviceLocker *usb_device_locker;
|
||||||
|
} FuUsbDevicePrivate;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (FuUsbDevice, fu_usb_device, FU_TYPE_DEVICE)
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
PROP_USB_DEVICE,
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GET_PRIVATE(o) (fu_usb_device_get_instance_private (o))
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_usb_device_get_property (GObject *object, guint prop_id,
|
||||||
|
GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
FuUsbDevice *device = FU_USB_DEVICE (object);
|
||||||
|
FuUsbDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_USB_DEVICE:
|
||||||
|
g_value_set_object (value, priv->usb_device);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_usb_device_set_property (GObject *object, guint prop_id,
|
||||||
|
const GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
FuUsbDevice *device = FU_USB_DEVICE (object);
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_USB_DEVICE:
|
||||||
|
fu_usb_device_set_dev (device, g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_usb_device_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
FuUsbDevice *device = FU_USB_DEVICE (object);
|
||||||
|
FuUsbDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
|
||||||
|
if (priv->usb_device_locker != NULL)
|
||||||
|
g_object_unref (priv->usb_device_locker);
|
||||||
|
if (priv->usb_device != NULL)
|
||||||
|
g_object_unref (priv->usb_device);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (fu_usb_device_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_usb_device_init (FuUsbDevice *device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_usb_device_class_init (FuUsbDeviceClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
object_class->finalize = fu_usb_device_finalize;
|
||||||
|
object_class->get_property = fu_usb_device_get_property;
|
||||||
|
object_class->set_property = fu_usb_device_set_property;
|
||||||
|
|
||||||
|
pspec = g_param_spec_object ("usb-device", NULL, NULL,
|
||||||
|
G_USB_TYPE_DEVICE,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT |
|
||||||
|
G_PARAM_STATIC_NAME);
|
||||||
|
g_object_class_install_property (object_class, PROP_USB_DEVICE, pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fu_usb_device_open:
|
||||||
|
* @device: A #FuUsbDevice
|
||||||
|
* @error: A #GError, or %NULL
|
||||||
|
*
|
||||||
|
* Opens a USB device, optionally running a object-specific vfunc.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE for success
|
||||||
|
*
|
||||||
|
* Since: 1.0.2
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
fu_usb_device_open (FuUsbDevice *device, GError **error)
|
||||||
|
{
|
||||||
|
FuUsbDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
FuUsbDeviceClass *klass = FU_USB_DEVICE_GET_CLASS (device);
|
||||||
|
guint idx;
|
||||||
|
g_autoptr(AsProfile) profile = as_profile_new ();
|
||||||
|
g_autoptr(AsProfileTask) ptask = NULL;
|
||||||
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (FU_IS_USB_DEVICE (device), FALSE);
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||||
|
|
||||||
|
/* already open */
|
||||||
|
if (priv->usb_device_locker != NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* profile */
|
||||||
|
ptask = as_profile_start (profile, "%s:added{%04x:%04x}",
|
||||||
|
fu_device_get_plugin (FU_DEVICE (device)),
|
||||||
|
g_usb_device_get_vid (priv->usb_device),
|
||||||
|
g_usb_device_get_pid (priv->usb_device));
|
||||||
|
g_assert (ptask != NULL);
|
||||||
|
|
||||||
|
/* open */
|
||||||
|
locker = fu_device_locker_new (priv->usb_device, error);
|
||||||
|
if (locker == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* get vendor */
|
||||||
|
idx = g_usb_device_get_manufacturer_index (priv->usb_device);
|
||||||
|
if (idx != 0xff) {
|
||||||
|
g_autofree gchar *tmp = NULL;
|
||||||
|
tmp = g_usb_device_get_string_descriptor (priv->usb_device,
|
||||||
|
idx, error);
|
||||||
|
if (tmp == NULL)
|
||||||
|
return FALSE;
|
||||||
|
fu_device_set_vendor (FU_DEVICE (device), tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get product */
|
||||||
|
idx = g_usb_device_get_product_index (priv->usb_device);
|
||||||
|
if (idx != 0xff) {
|
||||||
|
g_autofree gchar *tmp = NULL;
|
||||||
|
tmp = g_usb_device_get_string_descriptor (priv->usb_device,
|
||||||
|
idx, error);
|
||||||
|
if (tmp == NULL)
|
||||||
|
return FALSE;
|
||||||
|
fu_device_set_name (FU_DEVICE (device), tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* subclassed */
|
||||||
|
if (klass->open != NULL) {
|
||||||
|
if (!klass->open (device, error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
priv->usb_device_locker = g_steal_pointer (&locker);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fu_usb_device_open:
|
||||||
|
* @device: A #FuUsbDevice
|
||||||
|
* @error: A #GError, or %NULL
|
||||||
|
*
|
||||||
|
* Closes a USB device, optionally running a object-specific vfunc.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE for success
|
||||||
|
*
|
||||||
|
* Since: 1.0.2
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
fu_usb_device_close (FuUsbDevice *device, GError **error)
|
||||||
|
{
|
||||||
|
FuUsbDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
FuUsbDeviceClass *klass = FU_USB_DEVICE_GET_CLASS (device);
|
||||||
|
|
||||||
|
g_return_val_if_fail (FU_IS_USB_DEVICE (device), FALSE);
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||||
|
|
||||||
|
/* subclassed */
|
||||||
|
if (klass->close != NULL) {
|
||||||
|
if (!klass->close (device, error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object (&priv->usb_device_locker);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
_bcd_version_from_uint16 (guint16 val)
|
||||||
|
{
|
||||||
|
#if AS_CHECK_VERSION(0,7,3)
|
||||||
|
return as_utils_version_from_uint16 (val, AS_VERSION_PARSE_FLAG_USE_BCD);
|
||||||
|
#else
|
||||||
|
guint maj = ((val >> 12) & 0x0f) * 10 + ((val >> 8) & 0x0f);
|
||||||
|
guint min = ((val >> 4) & 0x0f) * 10 + (val & 0x0f);
|
||||||
|
return g_strdup_printf ("%u.%u", maj, min);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fu_usb_device_set_dev:
|
||||||
|
* @device: A #FuUsbDevice
|
||||||
|
* @usb_device: A #GUsbDevice, or %NULL
|
||||||
|
*
|
||||||
|
* Sets the #GUsbDevice to use.
|
||||||
|
*
|
||||||
|
* Since: 1.0.2
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
fu_usb_device_set_dev (FuUsbDevice *device, GUsbDevice *usb_device)
|
||||||
|
{
|
||||||
|
FuUsbDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
guint16 release = g_usb_device_get_release (usb_device);
|
||||||
|
g_autofree gchar *devid1 = NULL;
|
||||||
|
g_autofree gchar *devid2 = NULL;
|
||||||
|
g_autofree gchar *vendor_id = NULL;
|
||||||
|
|
||||||
|
g_return_if_fail (FU_IS_USB_DEVICE (device));
|
||||||
|
|
||||||
|
/* allow replacement */
|
||||||
|
g_set_object (&priv->usb_device, usb_device);
|
||||||
|
if (usb_device == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* add both device IDs */
|
||||||
|
devid1 = g_strdup_printf ("USB\\VID_%04X&PID_%04X",
|
||||||
|
g_usb_device_get_vid (usb_device),
|
||||||
|
g_usb_device_get_pid (usb_device));
|
||||||
|
fu_device_add_guid (FU_DEVICE (device), devid1);
|
||||||
|
devid2 = g_strdup_printf ("USB\\VID_%04X&PID_%04X&REV_%04X",
|
||||||
|
g_usb_device_get_vid (usb_device),
|
||||||
|
g_usb_device_get_pid (usb_device),
|
||||||
|
release);
|
||||||
|
fu_device_add_guid (FU_DEVICE (device), devid2);
|
||||||
|
|
||||||
|
/* set vendor ID */
|
||||||
|
vendor_id = g_strdup_printf ("USB:0x%04X", g_usb_device_get_vid (usb_device));
|
||||||
|
fu_device_set_vendor_id (FU_DEVICE (device), vendor_id);
|
||||||
|
|
||||||
|
/* set the version if the release has been set */
|
||||||
|
if (release != 0x0) {
|
||||||
|
g_autofree gchar *version = _bcd_version_from_uint16 (release);
|
||||||
|
fu_device_set_version (FU_DEVICE (device), version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set USB platform ID automatically */
|
||||||
|
fu_device_set_platform_id (FU_DEVICE (device),
|
||||||
|
g_usb_device_get_platform_id (usb_device));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fu_usb_device_get_dev:
|
||||||
|
* @device: A #FuUsbDevice
|
||||||
|
*
|
||||||
|
* Gets the #GUsbDevice.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): a #GUsbDevice, or %NULL
|
||||||
|
*
|
||||||
|
* Since: 1.0.2
|
||||||
|
**/
|
||||||
|
GUsbDevice *
|
||||||
|
fu_usb_device_get_dev (FuUsbDevice *device)
|
||||||
|
{
|
||||||
|
FuUsbDevicePrivate *priv = GET_PRIVATE (device);
|
||||||
|
g_return_val_if_fail (FU_IS_USB_DEVICE (device), NULL);
|
||||||
|
return priv->usb_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fu_usb_device_new:
|
||||||
|
*
|
||||||
|
* Creates a new #FuUsbDevice.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): a #FuUsbDevice
|
||||||
|
*
|
||||||
|
* Since: 1.0.2
|
||||||
|
**/
|
||||||
|
FuDevice *
|
||||||
|
fu_usb_device_new (GUsbDevice *usb_device)
|
||||||
|
{
|
||||||
|
FuUsbDevice *device = g_object_new (FU_TYPE_USB_DEVICE, NULL);
|
||||||
|
fu_usb_device_set_dev (device, usb_device);
|
||||||
|
return FU_DEVICE (device);
|
||||||
|
}
|
56
src/fu-usb-device.h
Normal file
56
src/fu-usb-device.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FU_USB_DEVICE_H
|
||||||
|
#define __FU_USB_DEVICE_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gusb.h>
|
||||||
|
|
||||||
|
#include "fu-plugin.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define FU_TYPE_USB_DEVICE (fu_usb_device_get_type ())
|
||||||
|
G_DECLARE_DERIVABLE_TYPE (FuUsbDevice, fu_usb_device, FU, USB_DEVICE, FuDevice)
|
||||||
|
|
||||||
|
struct _FuUsbDeviceClass
|
||||||
|
{
|
||||||
|
FuDeviceClass parent_class;
|
||||||
|
gboolean (*open) (FuUsbDevice *device,
|
||||||
|
GError **error);
|
||||||
|
gboolean (*close) (FuUsbDevice *device,
|
||||||
|
GError **error);
|
||||||
|
gpointer __reserved[29];
|
||||||
|
};
|
||||||
|
|
||||||
|
FuDevice *fu_usb_device_new (GUsbDevice *usb_device);
|
||||||
|
GUsbDevice *fu_usb_device_get_dev (FuUsbDevice *device);
|
||||||
|
void fu_usb_device_set_dev (FuUsbDevice *device,
|
||||||
|
GUsbDevice *usb_device);
|
||||||
|
gboolean fu_usb_device_open (FuUsbDevice *device,
|
||||||
|
GError **error);
|
||||||
|
gboolean fu_usb_device_close (FuUsbDevice *device,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __FU_USB_DEVICE_H */
|
@ -31,6 +31,7 @@ libfwupdprivate = static_library(
|
|||||||
'fu-quirks.c',
|
'fu-quirks.c',
|
||||||
'fu-smbios.c',
|
'fu-smbios.c',
|
||||||
'fu-test.c',
|
'fu-test.c',
|
||||||
|
'fu-usb-device.c',
|
||||||
],
|
],
|
||||||
include_directories : [
|
include_directories : [
|
||||||
include_directories('..'),
|
include_directories('..'),
|
||||||
@ -133,6 +134,7 @@ executable(
|
|||||||
'fu-plugin.c',
|
'fu-plugin.c',
|
||||||
'fu-quirks.c',
|
'fu-quirks.c',
|
||||||
'fu-smbios.c',
|
'fu-smbios.c',
|
||||||
|
'fu-usb-device.c',
|
||||||
],
|
],
|
||||||
include_directories : [
|
include_directories : [
|
||||||
include_directories('..'),
|
include_directories('..'),
|
||||||
@ -195,6 +197,7 @@ if get_option('enable-tests')
|
|||||||
'fu-quirks.c',
|
'fu-quirks.c',
|
||||||
'fu-smbios.c',
|
'fu-smbios.c',
|
||||||
'fu-test.c',
|
'fu-test.c',
|
||||||
|
'fu-usb-device.c',
|
||||||
],
|
],
|
||||||
include_directories : [
|
include_directories : [
|
||||||
include_directories('..'),
|
include_directories('..'),
|
||||||
@ -248,6 +251,7 @@ if get_option('enable-introspection')
|
|||||||
'fu-plugin.h',
|
'fu-plugin.h',
|
||||||
'fu-quirks.c',
|
'fu-quirks.c',
|
||||||
'fu-quirks.h',
|
'fu-quirks.h',
|
||||||
|
'fu-usb-device.c',
|
||||||
],
|
],
|
||||||
nsversion : '1.0',
|
nsversion : '1.0',
|
||||||
namespace : 'Fu',
|
namespace : 'Fu',
|
||||||
|
Loading…
Reference in New Issue
Block a user