Example #1
0
/* now with kind and usb_device set */
static void
fu_altos_device_init_real (FuAltosDevice *self)
{
	/* allowed, but requires manual bootloader step */
	fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);

	/* set default vendor */
	fu_device_set_vendor (FU_DEVICE (self), "altusmetrum.org");

	/* set name */
	switch (self->kind) {
	case FU_ALTOS_DEVICE_KIND_BOOTLOADER:
		fu_device_set_name (FU_DEVICE (self), "Altos [bootloader]");
		break;
	case FU_ALTOS_DEVICE_KIND_CHAOSKEY:
		fu_device_set_name (FU_DEVICE (self), "Altos ChaosKey");
		break;
	default:
		g_assert_not_reached ();
		break;
	}

	/* set one line summary */
	fu_device_set_summary (FU_DEVICE (self),
			       "A USB hardware random number generator");

	/* only the bootloader can do the update */
	if (self->kind != FU_ALTOS_DEVICE_KIND_BOOTLOADER) {
		fu_device_add_flag (FU_DEVICE (self),
				    FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER);
	}
}
Example #2
0
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_add_guid (device, "00000000-0000-0000-0000-000000000000");
	fu_device_set_name (device, "Integrated_Webcam(TM)");
	fu_provider_device_add (provider, device);
	return TRUE;
}
Example #3
0
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);
}
Example #4
0
static gboolean
fu_usb_device_open (FuDevice *device, GError **error)
{
	FuUsbDevice *self = FU_USB_DEVICE (device);
	FuUsbDevicePrivate *priv = GET_PRIVATE (self);
	FuUsbDeviceClass *klass = FU_USB_DEVICE_GET_CLASS (device);
	guint idx;
	g_autoptr(FuDeviceLocker) locker = NULL;

	g_return_val_if_fail (FU_IS_USB_DEVICE (self), FALSE);
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

	/* 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;

	/* get vendor */
	if (fu_device_get_vendor (device) == NULL) {
		idx = g_usb_device_get_manufacturer_index (priv->usb_device);
		if (idx != 0x00) {
			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 (device, tmp);
		}
	}

	/* get product */
	if (fu_device_get_name (device) == NULL) {
		idx = g_usb_device_get_product_index (priv->usb_device);
		if (idx != 0x00) {
			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 (device, tmp);
		}
	}

	/* get serial number */
	if (fu_device_get_serial (device) == NULL) {
		idx = g_usb_device_get_serial_number_index (priv->usb_device);
		if (idx != 0x00) {
			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_serial (device, tmp);
		}
	}

	/* get version number, falling back to the USB device release */
	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);
		fu_device_set_version (device, tmp);
	}

	/* get GUID from the descriptor if set */
	idx = g_usb_device_get_custom_index (priv->usb_device,
					     G_USB_DEVICE_CLASS_VENDOR_SPECIFIC,
					     'G', 'U', NULL);
	if (idx != 0x00) {
		g_autofree gchar *tmp = NULL;
		tmp = g_usb_device_get_string_descriptor (priv->usb_device, idx, NULL);
		fu_device_add_guid (device, tmp);
	}

	/* subclassed */
	if (klass->open != NULL) {
		if (!klass->open (self, error))
			return FALSE;
	}

	/* success */
	priv->usb_device_locker = g_steal_pointer (&locker);
	return TRUE;
}
Example #5
0
/**
 * 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);
}
Example #6
0
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;
}