diff --git a/src/Makefile.am b/src/Makefile.am index 2649c0351..dbaf1728c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,6 +21,8 @@ AM_CPPFLAGS = \ bin_PROGRAMS = fwupdmgr fwupdmgr_SOURCES = \ + fu-device.c \ + fu-device.h \ fu-util.c fwupdmgr_LDADD = \ diff --git a/src/fu-common.h b/src/fu-common.h index 9f327981a..3bc2f2663 100644 --- a/src/fu-common.h +++ b/src/fu-common.h @@ -29,4 +29,7 @@ #define FU_ERROR 1 #define FU_ERROR_INTERNAL 0 +#define FU_DEVICE_KEY_VERSION "Version" +#define FU_DEVICE_KEY_PROVIDER "Provider" + #endif /* __FU_COMMON_H */ diff --git a/src/fu-device.c b/src/fu-device.c index a5e5feb9d..86d2abace 100644 --- a/src/fu-device.c +++ b/src/fu-device.c @@ -40,6 +40,7 @@ static void fu_device_finalize (GObject *object); struct _FuDevicePrivate { gchar *id; + GHashTable *metadata; }; enum { @@ -76,6 +77,75 @@ fu_device_set_id (FuDevice *device, const gchar *id) device->priv->id = g_strdup (id); } +/** + * fu_device_get_metadata: + **/ +const gchar * +fu_device_get_metadata (FuDevice *device, const gchar *key) +{ + g_return_val_if_fail (FU_IS_DEVICE (device), NULL); + g_return_val_if_fail (key != NULL, NULL); + return g_hash_table_lookup (device->priv->metadata, key); +} + +/** + * fu_device_get_id: + **/ +void +fu_device_set_metadata (FuDevice *device, const gchar *key, const gchar *value) +{ + g_return_if_fail (FU_IS_DEVICE (device)); + g_return_if_fail (key != NULL); + g_return_if_fail (value != NULL); + g_hash_table_insert (device->priv->metadata, g_strdup (key), g_strdup (value)); +} + +/** + * fu_device_to_variant: + **/ +GVariant * +fu_device_to_variant (FuDevice *device) +{ + GList *l; + GVariantBuilder builder; + const gchar *key; + const gchar *value; + _cleanup_list_free_ GList *keys = NULL; + + /* create an array with all the metadata in */ + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + keys = g_hash_table_get_keys (device->priv->metadata); + for (l = keys; l != NULL; l = l->next) { + key = l->data; + value = g_hash_table_lookup (device->priv->metadata, key); + g_variant_builder_add (&builder, "{sv}", + key, g_variant_new_string (value)); + } + return g_variant_new ("{sa{sv}}", device->priv->id, &builder); +} + +/** + * fu_device_set_metadata_from_iter: + **/ +void +fu_device_set_metadata_from_iter (FuDevice *device, GVariantIter *iter) +{ + GVariant *variant; + const gchar *key; + const gchar *type; + + while (g_variant_iter_next (iter, "{&sv}", &key, &variant)) { + type = g_variant_get_type_string (variant); + if (g_strcmp0 (type, "s") == 0) { + fu_device_set_metadata (device, key, + g_variant_get_string (variant, NULL)); + } else { + fu_device_set_metadata (device, key, "???"); + } + g_variant_unref (variant); + } +} + /** * fu_device_get_property: **/ @@ -145,6 +215,8 @@ static void fu_device_init (FuDevice *device) { device->priv = FU_DEVICE_GET_PRIVATE (device); + device->priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_free); } /** @@ -157,6 +229,7 @@ fu_device_finalize (GObject *object) FuDevicePrivate *priv = device->priv; g_free (priv->id); + g_hash_table_unref (priv->metadata); G_OBJECT_CLASS (fu_device_parent_class)->finalize (object); } diff --git a/src/fu-device.h b/src/fu-device.h index ccd1468c6..ca85513c2 100644 --- a/src/fu-device.h +++ b/src/fu-device.h @@ -53,9 +53,17 @@ GType fu_device_get_type (void); FuDevice *fu_device_new (void); /* accessors */ +GVariant *fu_device_to_variant (FuDevice *device); const gchar *fu_device_get_id (FuDevice *device); void fu_device_set_id (FuDevice *device, const gchar *id); +const gchar *fu_device_get_metadata (FuDevice *device, + const gchar *key); +void fu_device_set_metadata (FuDevice *device, + const gchar *key, + const gchar *value); +void fu_device_set_metadata_from_iter (FuDevice *device, + GVariantIter *iter); G_END_DECLS diff --git a/src/fu-main.c b/src/fu-main.c index 7770ce5da..f2ac67ac9 100644 --- a/src/fu-main.c +++ b/src/fu-main.c @@ -50,21 +50,23 @@ typedef struct { } FuDeviceItem; /** - * fu_main_get_device_list_as_strv: + * fu_device_to_variants: **/ -static gchar ** -fu_main_get_device_list_as_strv (FuMainPrivate *priv) +static GVariant * +fu_device_to_variants (FuMainPrivate *priv) { - gchar **val; + GVariantBuilder builder; guint i; - FuDevice *dev_tmp; - val = g_new0 (gchar *, priv->devices->len + 1); + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); for (i = 0; i < priv->devices->len; i++) { - dev_tmp = g_ptr_array_index (priv->devices, i); - val[i] = g_strdup (fu_device_get_id (dev_tmp)); + GVariant *tmp; + FuDeviceItem *item; + item = g_ptr_array_index (priv->devices, i); + tmp = fu_device_to_variant (item->device); + g_variant_builder_add_value (&builder, tmp); } - return val; + return g_variant_new ("(a{sa{sv}})", &builder); } /** @@ -163,8 +165,9 @@ fu_main_check_authorization_cb (GObject *source, GAsyncResult *res, gpointer use /* run the correct provider that added this */ if (!fu_provider_update (item->provider, item->device, + helper->fd, helper->flags, - helper->fd, &error)) { + &error)) { g_dbus_method_invocation_return_gerror (helper->invocation, error); fu_main_helper_free (helper); @@ -192,8 +195,7 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender, if (g_strcmp0 (method_name, "GetDevices") == 0) { _cleanup_strv_free_ gchar **devices = NULL; g_debug ("Called %s()", method_name); - devices = fu_main_get_device_list_as_strv (priv); - val = g_variant_new ("(^as)", devices); + val = fu_device_to_variants (priv); g_dbus_method_invocation_return_value (invocation, val); return; } @@ -234,6 +236,7 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender, if (g_strcmp0 (prop_key, "offline") == 0 && g_variant_get_boolean (prop_value) == TRUE) flags |= FU_PROVIDER_UPDATE_FLAG_OFFLINE; + g_variant_unref (prop_value); } /* get the fd */ diff --git a/src/fu-provider-uefi.c b/src/fu-provider-uefi.c index 129414749..afb7aed89 100644 --- a/src/fu-provider-uefi.c +++ b/src/fu-provider-uefi.c @@ -31,40 +31,8 @@ static void fu_provider_uefi_finalize (GObject *object); -#define FU_PROVIDER_UEFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), FU_TYPE_PROVIDER_UEFI, FuProviderUefiPrivate)) - -/** - * FuProviderUefiPrivate: - **/ -struct _FuProviderUefiPrivate -{ - GPtrArray *array_devices; -}; - G_DEFINE_TYPE (FuProviderUefi, fu_provider_uefi, FU_TYPE_PROVIDER) -/** - * fu_provider_uefi_get_by_id: - **/ -static FuDevice * -fu_provider_uefi_get_by_id (FuProviderUefi *provider_uefi, - const gchar *device_id) -{ - FuProviderUefiPrivate *priv = provider_uefi->priv; - FuDevice *device = NULL; - FuDevice *device_tmp; - guint i; - - for (i = 0; i < priv->array_devices->len; i++) { - device_tmp = g_ptr_array_index (priv->array_devices, i); - if (g_strcmp0 (fu_device_get_id (device_tmp), device_id) == 0) { - device = g_object_ref (device_tmp); - break; - } - } - return device; -} - /** * fu_provider_uefi_update: **/ @@ -75,8 +43,6 @@ fu_provider_uefi_update (FuProvider *provider, FuProviderFlags flags, GError **error) { -// FuProviderUefi *provider_uefi = FU_PROVIDER_UEFI (provider); - /* this only makes sense offline */ if ((flags & FU_PROVIDER_UPDATE_FLAG_OFFLINE) == 0) { g_set_error_literal (error, @@ -97,13 +63,14 @@ fu_provider_uefi_update (FuProvider *provider, static gboolean fu_provider_uefi_coldplug (FuProvider *provider, GError **error) { -// FuProviderUefi *provider_uefi = FU_PROVIDER_UEFI (provider); _cleanup_object_unref_ FuDevice *dev = NULL; //FIXME g_debug ("Adding fake UEFI device"); dev = fu_device_new (); fu_device_set_id (dev, "UEFI-819b858e-c52c-402f-80e1-5b311b6c1959-dev1"); + fu_device_set_metadata (dev, FU_DEVICE_KEY_PROVIDER, "UEFI"); + fu_device_set_metadata (dev, FU_DEVICE_KEY_VERSION, "12345"); fu_provider_emit_added (provider, dev); return TRUE; } @@ -120,8 +87,6 @@ fu_provider_uefi_class_init (FuProviderUefiClass *klass) provider_class->coldplug = fu_provider_uefi_coldplug; provider_class->update = fu_provider_uefi_update; object_class->finalize = fu_provider_uefi_finalize; - - g_type_class_add_private (klass, sizeof (FuProviderUefiPrivate)); } /** @@ -130,8 +95,6 @@ fu_provider_uefi_class_init (FuProviderUefiClass *klass) static void fu_provider_uefi_init (FuProviderUefi *provider_uefi) { - provider_uefi->priv = FU_PROVIDER_UEFI_GET_PRIVATE (provider_uefi); - provider_uefi->priv->array_devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); } /** @@ -140,11 +103,6 @@ fu_provider_uefi_init (FuProviderUefi *provider_uefi) static void fu_provider_uefi_finalize (GObject *object) { - FuProviderUefi *provider_uefi = FU_PROVIDER_UEFI (object); - FuProviderUefiPrivate *priv = provider_uefi->priv; - - g_ptr_array_unref (priv->array_devices); - G_OBJECT_CLASS (fu_provider_uefi_parent_class)->finalize (object); } diff --git a/src/fu-util.c b/src/fu-util.c index 4b505828c..931074b22 100644 --- a/src/fu-util.c +++ b/src/fu-util.c @@ -194,11 +194,14 @@ fu_util_run (FuUtilPrivate *priv, const gchar *command, gchar **values, GError * static gboolean fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error) { + GVariantIter *iter_device; + FuDevice *dev; + gchar *id; + _cleanup_ptrarray_unref_ GPtrArray *devices = NULL; _cleanup_object_unref_ GDBusConnection *conn = NULL; _cleanup_object_unref_ GDBusProxy *proxy = NULL; + _cleanup_variant_iter_free_ GVariantIter *iter = NULL; _cleanup_variant_unref_ GVariant *val = NULL; - const gchar **ids = NULL; - guint i; conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); if (conn == NULL) @@ -222,12 +225,39 @@ fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error) error); if (val == NULL) return FALSE; - g_variant_get (val, "(^a&s)", &ids); - g_assert (ids != NULL); - if (ids[0] == NULL) + + /* parse */ + g_variant_get (val, "(a{sa{sv}})", &iter); + devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + while (g_variant_iter_next (iter, "{&sa{sv}}", &id, &iter_device)) { + dev = fu_device_new (); + fu_device_set_id (dev, id); + fu_device_set_metadata_from_iter (dev, iter_device); + g_ptr_array_add (devices, dev); + g_variant_iter_free (iter_device); + } + + /* print */ + if (devices->len == 0) { g_print ("No hardware detected with firmware update capaility\n"); - for (i = 0; ids[i] != NULL; i++) - g_print ("%i: %s\n", i, ids[i]); + } else { + guint i; + guint j; + const gchar *value; + const gchar *keys[] = { + FU_DEVICE_KEY_PROVIDER, + FU_DEVICE_KEY_VERSION, + NULL }; + for (i = 0; i < devices->len; i++) { + dev = g_ptr_array_index (devices, i); + g_print ("Device: %s\n", fu_device_get_id (dev)); + for (j = 0; keys[j] != NULL; j++) { + value = fu_device_get_metadata (dev, keys[j]); + if (value != NULL) + g_print (" %s:\t%s\n", keys[j], value); + } + } + } return TRUE; } diff --git a/src/org.freedesktop.fwupd.xml b/src/org.freedesktop.fwupd.xml index f4dd3a627..829f10a0e 100644 --- a/src/org.freedesktop.fwupd.xml +++ b/src/org.freedesktop.fwupd.xml @@ -31,10 +31,10 @@ - + - An array of IDs. + An array of devices, with any properties set on each.