blob: 41b993b91cc38972902bb73943f699050349dc1d [file] [log] [blame]
/*
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#define G_LOG_DOMAIN "FuBackend"
#include "config.h"
#include <gusb.h>
#include "fu-usb-device.h"
#include "fu-usb-backend.h"
struct _FuUsbBackend {
FuBackend parent_instance;
GUsbContext *usb_ctx;
};
G_DEFINE_TYPE (FuUsbBackend, fu_usb_backend, FU_TYPE_BACKEND)
static void
fu_usb_backend_device_added_cb (GUsbContext *ctx,
GUsbDevice *usb_device,
FuBackend *backend)
{
g_autoptr(FuUsbDevice) device = fu_usb_device_new (usb_device);
/* success */
fu_backend_device_added (backend, FU_DEVICE (device));
}
static void
fu_usb_backend_device_removed_cb (GUsbContext *ctx,
GUsbDevice *usb_device,
FuBackend *backend)
{
FuUsbBackend *self = FU_USB_BACKEND (backend);
FuDevice *device_tmp;
/* find the device we enumerated */
device_tmp = fu_backend_lookup_by_id (FU_BACKEND (self),
g_usb_device_get_platform_id (usb_device));
if (device_tmp != NULL)
fu_backend_device_removed (backend, device_tmp);
}
static gboolean
fu_usb_backend_setup (FuBackend *backend, GError **error)
{
FuUsbBackend *self = FU_USB_BACKEND (backend);
self->usb_ctx = g_usb_context_new (error);
if (self->usb_ctx == NULL) {
g_prefix_error (error, "failed to get USB context: ");
return FALSE;
}
g_signal_connect (self->usb_ctx, "device-added",
G_CALLBACK (fu_usb_backend_device_added_cb),
self);
g_signal_connect (self->usb_ctx, "device-removed",
G_CALLBACK (fu_usb_backend_device_removed_cb),
self);
return TRUE;
}
static gboolean
fu_usb_backend_coldplug (FuBackend *backend, GError **error)
{
FuUsbBackend *self = FU_USB_BACKEND (backend);
g_usb_context_enumerate (self->usb_ctx);
return TRUE;
}
static void
fu_usb_backend_finalize (GObject *object)
{
FuUsbBackend *self = FU_USB_BACKEND (object);
if (self->usb_ctx != NULL)
g_object_unref (self->usb_ctx);
G_OBJECT_CLASS (fu_usb_backend_parent_class)->finalize (object);
}
static void
fu_usb_backend_init (FuUsbBackend *self)
{
}
static void
fu_usb_backend_class_init (FuUsbBackendClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
FuBackendClass *klass_backend = FU_BACKEND_CLASS (klass);
object_class->finalize = fu_usb_backend_finalize;
klass_backend->setup = fu_usb_backend_setup;
klass_backend->coldplug = fu_usb_backend_coldplug;
}
FuBackend *
fu_usb_backend_new (void)
{
return FU_BACKEND (g_object_new (FU_TYPE_USB_BACKEND, "name", "usb", NULL));
}