static void ch_assemble_flash_firmware (ChAssemblePrivate *priv) { gsize len; g_autoptr(GError) error = NULL; g_autofree gchar *fn = NULL; g_autofree guint8 *data = NULL; /* set to false */ ch_device_queue_set_flash_success (priv->device_queue, priv->device, 0); switch (ch_device_get_mode (priv->device)) { case CH_DEVICE_MODE_BOOTLOADER: case CH_DEVICE_MODE_BOOTLOADER2: case CH_DEVICE_MODE_BOOTLOADER_ALS: /* read firmware */ ch_assemble_set_color (priv, 0.25f, 0.25f, 0.25f); ch_assemble_set_label (priv, _("Loading firmware...")); fn = g_strdup_printf ("./firmware/%s/firmware.bin", _ch_device_get_download_id (priv->device)); if (!g_file_get_contents (fn, (gchar **) &data, &len, &error)) { g_warning ("Failed to open firmware file %s: %s", fn, error->message); return; } /* write to device */ ch_assemble_set_color (priv, 0.5f, 0.5f, 0.5f); ch_assemble_set_label (priv, _("Writing firmware...")); ch_device_queue_write_firmware (priv->device_queue, priv->device, data, len); break; default: break; } ch_device_queue_process_async (priv->device_queue, CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE, NULL, ch_assemble_firmware_cb, priv); }
static void ch_assemble_got_device_fw (ChAssemblePrivate *priv) { g_autoptr(GError) error = NULL; /* open device */ if (!ch_device_open (priv->device, &error)) { g_warning ("Failed to open: %s", error->message); /* TRANSLATORS: permissions error perhaps? */ ch_assemble_set_label (priv, _("Failed to open device")); ch_assemble_set_color (priv, 0, 0, 0); return; } ch_assemble_set_label (priv, _("Setting flash success...")); ch_assemble_set_color (priv, 0.5f, 0.5f, 0.5f); ch_device_queue_set_flash_success (priv->device_queue, priv->device, 1); ch_device_queue_process_async (priv->device_queue, CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE, NULL, ch_assemble_set_serial_cb, priv); }
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; }