/** * fu_util_get_updates_internal: **/ static GPtrArray * fu_util_get_updates_internal (FuUtilPrivate *priv, GError **error) { GVariantIter *iter_device; GPtrArray *devices = NULL; FuDevice *dev; gchar *id; _cleanup_variant_iter_free_ GVariantIter *iter = NULL; g_dbus_proxy_call (priv->proxy, "GetUpdates", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, fu_util_get_devices_cb, priv); g_main_loop_run (priv->loop); if (priv->val == NULL) { g_propagate_error (error, priv->error); return NULL; } /* parse */ g_variant_get (priv->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); } return devices; }
/** * fu_provider_fake_coldplug: **/ static gboolean fu_provider_fake_coldplug (FuProvider *provider, GError **error) { g_autoptr(FuDevice) device = NULL; device = fu_device_new (); fu_device_set_id (device, "FakeDevice"); fu_device_set_guid (device, "00000000-0000-0000-0000-000000000000"); fu_provider_device_add (provider, device); return TRUE; }
static void fu_provider_chug_device_added_cb (GUsbContext *ctx, GUsbDevice *device, FuProviderChug *provider_chug) { FuProviderChugPrivate *priv = GET_PRIVATE (provider_chug); FuProviderChugItem *item; ChDeviceMode mode; g_autofree gchar *device_key = NULL; /* ignore */ mode = ch_device_get_mode (device); if (mode == CH_DEVICE_MODE_UNKNOWN) return; /* this is using DFU now */ if (mode == CH_DEVICE_MODE_BOOTLOADER_PLUS || mode == CH_DEVICE_MODE_FIRMWARE_PLUS) return; /* is already in database */ device_key = fu_provider_chug_get_device_key (device); item = g_hash_table_lookup (priv->devices, device_key); if (item == NULL) { item = g_new0 (FuProviderChugItem, 1); item->provider_chug = g_object_ref (provider_chug); item->usb_device = g_object_ref (device); item->device = fu_device_new (); fu_device_set_id (item->device, device_key); fu_device_set_equivalent_id (item->device, g_usb_device_get_platform_id (device)); fu_device_add_guid (item->device, ch_device_get_guid (device)); fu_device_add_flag (item->device, FU_DEVICE_FLAG_ALLOW_OFFLINE); fu_device_add_flag (item->device, FU_DEVICE_FLAG_ALLOW_ONLINE); /* try to get the serial number -- if opening failed then * poll until the device is not busy */ fu_provider_chug_get_firmware_version (item); if (!item->got_version && item->timeout_open_id == 0) { item->timeout_open_id = g_timeout_add_seconds (FU_PROVIDER_CHUG_POLL_REOPEN, fu_provider_chug_open_cb, item); } /* insert to hash */ g_hash_table_insert (priv->devices, g_strdup (device_key), item); } else { /* update the device */ g_object_unref (item->usb_device); item->usb_device = g_object_ref (device); } /* set the display name */ switch (mode) { case CH_DEVICE_MODE_BOOTLOADER: case CH_DEVICE_MODE_FIRMWARE: case CH_DEVICE_MODE_LEGACY: fu_device_set_name (item->device, "ColorHug"); break; case CH_DEVICE_MODE_BOOTLOADER2: case CH_DEVICE_MODE_FIRMWARE2: fu_device_set_name (item->device, "ColorHug2"); break; case CH_DEVICE_MODE_BOOTLOADER_PLUS: case CH_DEVICE_MODE_FIRMWARE_PLUS: fu_device_set_name (item->device, "ColorHug+"); break; case CH_DEVICE_MODE_BOOTLOADER_ALS: case CH_DEVICE_MODE_FIRMWARE_ALS: fu_device_set_name (item->device, "ColorHugALS"); break; default: fu_device_set_name (item->device, "ColorHug??"); break; } /* is the device in bootloader mode */ switch (mode) { case CH_DEVICE_MODE_BOOTLOADER: case CH_DEVICE_MODE_BOOTLOADER2: case CH_DEVICE_MODE_BOOTLOADER_PLUS: case CH_DEVICE_MODE_BOOTLOADER_ALS: item->is_bootloader = TRUE; break; default: item->is_bootloader = FALSE; break; } fu_provider_device_add (FU_PROVIDER (provider_chug), item->device); }
/** * fu_provider_udev_client_add: **/ static void fu_provider_udev_client_add (FuProviderUdev *provider_udev, GUdevDevice *device) { FuProviderUdevPrivate *priv = GET_PRIVATE (provider_udev); FuDevice *dev; const gchar *display_name; const gchar *guid; const gchar *product; const gchar *vendor; g_autofree gchar *guid_new = NULL; g_autofree gchar *id = NULL; g_autofree gchar *rom_fn = NULL; g_autofree gchar *version = NULL; g_auto(GStrv) split = NULL; /* interesting device? */ guid = g_udev_device_get_property (device, "FWUPD_GUID"); if (guid == NULL) return; /* get data */ g_debug ("adding udev device: %s", g_udev_device_get_sysfs_path (device)); if (0) { const gchar * const *keys; guint i; keys = g_udev_device_get_property_keys (device); for (i = 0; keys[i] != NULL; i++) g_debug ("KEY: %s=%s", keys[i], g_udev_device_get_property (device, keys[i])); keys = g_udev_device_get_sysfs_attr_keys (device); for (i = 0; keys[i] != NULL; i++) g_debug ("SYS: %s=%s", keys[i], g_udev_device_get_sysfs_attr (device, keys[i])); } /* is already in database */ id = fu_provider_udev_get_id (device); dev = g_hash_table_lookup (priv->devices, id); if (dev != NULL) { g_debug ("ignoring duplicate %s", id); return; } /* get the FW version from the BCD device revision */ product = g_udev_device_get_property (device, "PRODUCT"); if (product != NULL) { split = g_strsplit (product, "/", -1); if (g_strv_length (split) != 3) { g_warning ("env{PRODUCT} is invalid: %s", product); return; } version = g_strdup (split[2]); } /* get the FW version from the rom */ rom_fn = g_build_filename (g_udev_device_get_sysfs_path (device), "rom", NULL); if (g_file_test (rom_fn, G_FILE_TEST_EXISTS)) { g_autoptr(GError) error = NULL; g_autoptr(GFile) file = NULL; g_autoptr(FuRom) rom = NULL; file = g_file_new_for_path (rom_fn); rom = fu_rom_new (); if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, &error)) { g_warning ("Failed to parse ROM from %s: %s", rom_fn, error->message); } version = g_strdup (fu_rom_get_version (rom)); /* prefer the GUID from the firmware rather than the * hardware as the firmware may be more generic, which * also allows us to match the GUID when doing 'verify' * on a device with a different PID to the firmware */ guid_new = g_strdup (fu_rom_get_guid (rom)); } /* we failed */ if (version == NULL) return; /* no GUID from the ROM, so fix up the VID:PID */ if (guid_new == NULL) { if (!as_utils_guid_is_valid (guid)) { guid_new = as_utils_guid_from_string (guid); g_debug ("Fixing GUID %s->%s", guid, guid_new); } else { guid_new = g_strdup (guid); } } /* did we get enough data */ dev = fu_device_new (); fu_device_add_flag (dev, FU_DEVICE_FLAG_INTERNAL); fu_device_set_id (dev, id); fu_device_set_guid (dev, guid_new); display_name = g_udev_device_get_property (device, "FWUPD_MODEL"); if (display_name == NULL) display_name = g_udev_device_get_property (device, "ID_MODEL_FROM_DATABASE"); if (display_name != NULL) fu_device_set_display_name (dev, display_name); vendor = g_udev_device_get_property (device, "FWUPD_VENDOR"); if (vendor == NULL) vendor = g_udev_device_get_property (device, "ID_VENDOR_FROM_DATABASE"); if (vendor != NULL) fu_device_set_metadata (dev, FU_DEVICE_KEY_VENDOR, vendor); fu_device_set_metadata (dev, FU_DEVICE_KEY_VERSION, version); if (g_file_test (rom_fn, G_FILE_TEST_EXISTS)) fu_device_set_metadata (dev, "RomFilename", rom_fn); /* insert to hash */ g_hash_table_insert (priv->devices, g_strdup (id), dev); fu_provider_device_add (FU_PROVIDER (provider_udev), dev); }
/** * fu_provider_udev_client_add: **/ static void fu_provider_udev_client_add (FuProviderUdev *provider_udev, GUdevDevice *device) { FuProviderUdevPrivate *priv = GET_PRIVATE (provider_udev); FuDevice *dev; const gchar *display_name; const gchar *guid; const gchar *product; const gchar *vendor; g_autofree gchar *guid_new = NULL; g_autofree gchar *id = NULL; g_autofree gchar *rom_fn = NULL; g_autofree gchar *version = NULL; g_auto(GStrv) split = NULL; g_autoptr(AsProfile) profile = as_profile_new (); g_autoptr(AsProfileTask) ptask = NULL; /* interesting device? */ guid = g_udev_device_get_property (device, "FWUPD_GUID"); if (guid == NULL) return; /* get data */ ptask = as_profile_start (profile, "FuProviderUdev:client-add{%s}", guid); g_debug ("adding udev device: %s", g_udev_device_get_sysfs_path (device)); /* is already in database */ id = fu_provider_udev_get_id (device); dev = g_hash_table_lookup (priv->devices, id); if (dev != NULL) { g_debug ("ignoring duplicate %s", id); return; } /* get the FW version from the BCD device revision */ product = g_udev_device_get_property (device, "PRODUCT"); if (product != NULL) { split = g_strsplit (product, "/", -1); if (g_strv_length (split) != 3) { g_warning ("env{PRODUCT} is invalid: %s", product); return; } version = g_strdup (split[2]); } /* no GUID from the ROM, so fix up the VID:PID */ if (!as_utils_guid_is_valid (guid)) { guid_new = as_utils_guid_from_string (guid); g_debug ("fixing GUID %s->%s", guid, guid_new); } else { guid_new = g_strdup (guid); } /* did we get enough data */ dev = fu_device_new (); fu_device_add_flag (dev, FU_DEVICE_FLAG_INTERNAL); fu_device_set_id (dev, id); fu_device_set_guid (dev, guid_new); display_name = g_udev_device_get_property (device, "FWUPD_MODEL"); if (display_name == NULL) display_name = g_udev_device_get_property (device, "ID_MODEL_FROM_DATABASE"); if (display_name != NULL) fu_device_set_name (dev, display_name); vendor = g_udev_device_get_property (device, "FWUPD_VENDOR"); if (vendor == NULL) vendor = g_udev_device_get_property (device, "ID_VENDOR_FROM_DATABASE"); if (vendor != NULL) fu_device_set_vendor (dev, vendor); if (version != NULL) fu_device_set_version (dev, version); /* get the FW version from the rom when unlocked */ rom_fn = g_build_filename (g_udev_device_get_sysfs_path (device), "rom", NULL); if (g_file_test (rom_fn, G_FILE_TEST_EXISTS)) { fu_device_set_metadata (dev, "RomFilename", rom_fn); fu_device_add_flag (dev, FU_DEVICE_FLAG_LOCKED); } /* insert to hash */ g_hash_table_insert (priv->devices, g_strdup (id), dev); fu_provider_device_add (FU_PROVIDER (provider_udev), dev); }
static gboolean fu_provider_uefi_coldplug (FuProvider *provider, GError **error) { AsVersionParseFlag parse_flags; g_autofree gchar *display_name = NULL; fwup_resource *re; gint supported; g_autofree gchar *guid = NULL; g_autoptr(FuDevice) dev = NULL; g_autoptr(fwup_resource_iter) iter = NULL; /* supported = 0 : ESRT unspported supported = 1 : unlocked, ESRT supported supported = 2 : it is locked but can be unlocked to support ESRT supported = 3 : it is locked, has been marked to be unlocked on next boot calling unlock again is OK. */ supported = fwup_supported (); if (supported == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "UEFI firmware updating not supported"); return FALSE; } if (supported >= 2) { dev = fu_device_new (); fu_device_set_id (dev, "UEFI-dummy-dev0"); fu_device_add_guid (dev, "2d47f29b-83a2-4f31-a2e8-63474f4d4c2e"); fu_device_set_version (dev, "0"); fu_device_add_flag (dev, FU_DEVICE_FLAG_ALLOW_ONLINE); fu_device_add_flag (dev, FU_DEVICE_FLAG_LOCKED); fu_provider_device_add (provider, dev); return TRUE; } /* this can fail if we have no permissions */ if (fwup_resource_iter_create (&iter) < 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Cannot create fwup iter"); return FALSE; } /* set Display Name to the system for all capsules */ g_file_get_contents ("/sys/class/dmi/id/product_name", &display_name, NULL, NULL); if (display_name != NULL) g_strchomp (display_name); /* add each device */ guid = g_strdup ("00000000-0000-0000-0000-000000000000"); parse_flags = fu_provider_uefi_get_version_format (); while (fwup_resource_iter_next (iter, &re) > 0) { efi_guid_t *guid_raw; guint32 version_raw; guint64 hardware_instance = 0; /* FIXME */ g_autofree gchar *id = NULL; g_autofree gchar *version = NULL; g_autofree gchar *version_lowest = NULL; /* convert to strings */ fwup_get_guid (re, &guid_raw); if (efi_guid_to_str (guid_raw, &guid) < 0) { g_warning ("failed to convert guid to string"); continue; } fwup_get_fw_version(re, &version_raw); version = as_utils_version_from_uint32 (version_raw, parse_flags); id = g_strdup_printf ("UEFI-%s-dev%" G_GUINT64_FORMAT, guid, hardware_instance); dev = fu_device_new (); fu_device_set_id (dev, id); fu_device_add_guid (dev, guid); fu_device_set_version (dev, version); if (display_name != NULL) fu_device_set_name(dev, display_name); fwup_get_lowest_supported_fw_version (re, &version_raw); if (version_raw != 0) { version_lowest = as_utils_version_from_uint32 (version_raw, parse_flags); fu_device_set_version_lowest (dev, version_lowest); } fu_device_add_flag (dev, FU_DEVICE_FLAG_INTERNAL); fu_device_add_flag (dev, FU_DEVICE_FLAG_ALLOW_OFFLINE); fu_device_add_flag (dev, FU_DEVICE_FLAG_REQUIRE_AC); fu_provider_device_add (provider, dev); } return TRUE; }