Пример #1
0
static void
ch_assemble_firmware_cb (GObject *source, GAsyncResult *res, gpointer user_data)
{
    ChAssemblePrivate *priv = (ChAssemblePrivate *) user_data;
    g_autoptr(GError) error = NULL;

    /* get result */
    if (!ch_device_queue_process_finish (priv->device_queue, res, &error)) {
        g_warning ("Failed to flash firmware: %s", error->message);
        return;
    }

    ch_assemble_set_label (priv, _("Booting firmware..."));
    ch_assemble_set_color (priv, 0.5f, 0.5f, 0.5f);
    ch_device_queue_boot_flash (priv->device_queue, priv->device);
    ch_device_queue_process_async (priv->device_queue,
                                   CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
                                   NULL,
                                   ch_assemble_boot_flash_cb,
                                   priv);
}
Пример #2
0
int
main (int argc, char *argv[])
{
	gboolean ret;
	GError *error = NULL;
	GMainLoop *loop = NULL;
	GUsbContext *ctx;
	GUsbDevice *device = NULL;
	int retval = 0;
	GUsbDeviceList *list = NULL;
	ChDeviceQueue *device_queue;

	/* setup usb */
	g_type_init ();
	ctx = g_usb_context_new (&error);
	if (ctx == NULL) {
		g_warning ("Cannot connect to USB : %s", error->message);
		g_error_free (error);
		retval = 1;
		goto out;
	}
	list = g_usb_device_list_new (ctx);
	device_queue = ch_device_queue_new ();

	ret = connect_device (list, &device, &error);
	if (!ret) {
		g_warning ("Cannot connect to device : %s", error->message);
		g_error_free (error);
		retval = 1;
		goto out;
	}

	/* reset device so it boots back into bootloader mode */
	g_warning ("Switching to bootloader mode\n");
	ch_device_queue_reset (device_queue, device);
	ret = ch_device_queue_process (device_queue,
				       CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
				       NULL,
				       &error);
	if (!ret) {
		g_warning ("Failed to reboot : %s", error->message);
		g_error_free (error);
		retval = 1;
		goto out;
	}

	/* wait for device to re-appear */
	loop = g_main_loop_new (NULL, FALSE);
	g_timeout_add (5000, quit_loop_cb, loop);
	g_main_loop_run (loop);
	g_object_unref (device);
	ret = connect_device (list, &device, &error);
	if (!ret) {
		g_warning ("Cannot connect to device : %s", error->message);
		g_error_free (error);
		retval = 1;
		goto out;
	}

	/* boot into firmware mode */
	g_warning ("Switching to firmware mode\n");
	ch_device_queue_boot_flash (device_queue, device);
	ret = ch_device_queue_process (device_queue,
				       CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
				       NULL,
				       &error);
	if (!ret) {
		g_warning ("Failed to boot into firmware mode : %s", error->message);
		g_error_free (error);
		retval = 1;
		goto out;
	}

	/* wait for device to re-appear */
	g_timeout_add (5000, quit_loop_cb, loop);
	g_main_loop_run (loop);
	g_object_unref (device);
	ret = connect_device (list, &device, &error);
	if (!ret) {
		g_warning ("Cannot connect to device : %s", error->message);
		g_error_free (error);
		retval = 1;
		goto out;
	}

	/* turn on LEDs */
	g_warning ("Turning on LEDs\n");
	ch_device_queue_set_leds (device_queue, device, 3, 0, 0, 0);
	ret = ch_device_queue_process (device_queue,
				       CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
				       NULL,
				       &error);
	if (!ret) {
		g_warning ("Failed to turn on LEDs : %s", error->message);
		g_error_free (error);
		retval = 1;
		goto out;
	}

	/* success */
	g_warning ("ALL OKAY\n");
out:
	if (loop != NULL)
		g_main_loop_unref (loop);
	if (ctx != NULL)
		g_object_unref (ctx);
	if (device_queue != NULL)
		g_object_unref (device_queue);
	if (device != NULL)
		g_object_unref (device);
	if (list != NULL)
		g_object_unref (list);
	return retval;
}
Пример #3
0
static gboolean
fu_provider_chug_update (FuProvider *provider,
			 FuDevice *device,
			 GBytes *blob_fw,
			 FwupdInstallFlags flags,
			 GError **error)
{
	FuProviderChug *provider_chug = FU_PROVIDER_CHUG (provider);
	FuProviderChugPrivate *priv = GET_PRIVATE (provider_chug);
	FuProviderChugItem *item;
	g_autoptr(GError) error_local = NULL;

	/* find item */
	item = g_hash_table_lookup (priv->devices,
				    fu_device_get_id (device));
	if (item == NULL) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_NOT_FOUND,
			     "cannot find: %s",
			     fu_device_get_id (device));
		return FALSE;
	}

	/* this file is so small, just slurp it all in one go */
	item->fw_bin = g_bytes_ref (blob_fw);

	/* check this firmware is actually for this device */
	if (!ch_device_check_firmware (item->usb_device,
				       g_bytes_get_data (item->fw_bin, NULL),
				       g_bytes_get_size (item->fw_bin),
				       &error_local)) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_NOT_SUPPORTED,
			     "firmware is not suitable: %s",
			     error_local->message);
		return FALSE;
	}

	/* switch to bootloader mode */
	if (!item->is_bootloader) {
		g_debug ("ColorHug: Switching to bootloader mode");
		if (!fu_provider_chug_open (item, error))
			return FALSE;
		ch_device_queue_reset (priv->device_queue, item->usb_device);
		fu_provider_set_status (provider, FWUPD_STATUS_DEVICE_RESTART);
		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 reset device: %s",
				     error_local->message);
			g_usb_device_close (item->usb_device, NULL);
			return FALSE;
		}

		/* this device has just gone away, no error possible */
		g_usb_device_close (item->usb_device, NULL);

		/* wait for reconnection */
		g_debug ("ColorHug: Waiting for bootloader");
		if (!fu_provider_chug_wait_for_connect (provider_chug, item, error))
			return FALSE;
	}

	/* open the device, which is now in bootloader mode */
	if (!fu_provider_chug_open (item, error))
		return FALSE;

	/* write firmware */
	g_debug ("ColorHug: Writing firmware");
	ch_device_queue_write_firmware (priv->device_queue, item->usb_device,
					g_bytes_get_data (item->fw_bin, NULL),
					g_bytes_get_size (item->fw_bin));
	fu_provider_set_status (provider, FWUPD_STATUS_DEVICE_WRITE);
	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);
		g_usb_device_close (item->usb_device, NULL);
		return FALSE;
	}

	/* verify firmware */
	g_debug ("ColorHug: Veifying firmware");
	ch_device_queue_verify_firmware (priv->device_queue, item->usb_device,
					 g_bytes_get_data (item->fw_bin, NULL),
					 g_bytes_get_size (item->fw_bin));
	fu_provider_set_status (provider, FWUPD_STATUS_DEVICE_VERIFY);
	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);
		g_usb_device_close (item->usb_device, NULL);
		return FALSE;
	}

	/* boot into the new firmware */
	g_debug ("ColorHug: Booting new firmware");
	ch_device_queue_boot_flash (priv->device_queue, item->usb_device);
	fu_provider_set_status (provider, FWUPD_STATUS_DEVICE_RESTART);
	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 boot flash: %s",
			     error_local->message);
		g_usb_device_close (item->usb_device, NULL);
		return FALSE;
	}

	/* this device has just gone away, no error possible */
	g_usb_device_close (item->usb_device, NULL);

	/* wait for firmware mode */
	if (!fu_provider_chug_wait_for_connect (provider_chug, item, error))
		return FALSE;
	if (!fu_provider_chug_open (item, error))
		return FALSE;

	/* set flash success */
	g_debug ("ColorHug: Setting flash success");
	ch_device_queue_set_flash_success (priv->device_queue, item->usb_device, 1);
	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 set flash success: %s",
			     error_local->message);
		g_usb_device_close (item->usb_device, NULL);
		return FALSE;
	}

	/* close, orderly */
	if (!g_usb_device_close (item->usb_device, &error_local)) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_WRITE,
			     "failed to close device: %s",
			     error_local->message);
		g_usb_device_close (item->usb_device, NULL);
		return FALSE;
	}

	/* get the new firmware version */
	g_debug ("ColorHug: Getting new firmware version");
	item->got_version = FALSE;
	fu_provider_chug_get_firmware_version (item);

	if (item->got_version)
		g_debug ("ColorHug: DONE!");

	return TRUE;
}