Beispiel #1
0
/**
 * dfu_image_to_string:
 * @image: a #DfuImage
 *
 * Returns a string representaiton of the object.
 *
 * Return value: NULL terminated string, or %NULL for invalid
 **/
gchar *
dfu_image_to_string (DfuImage *image)
{
	DfuImagePrivate *priv = GET_PRIVATE (image);
	GString *str;

	g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);

	str = g_string_new ("");
	g_string_append_printf (str, "alt_setting: 0x%02x\n", priv->alt_setting);
	if (priv->name[0] != '\0')
		g_string_append_printf (str, "name:        %s\n", priv->name);
	g_string_append_printf (str, "elements:    0x%02x\n",
				priv->elements->len);

	/* add elements */
	for (guint i = 0; i < priv->elements->len; i++) {
		DfuElement *element = g_ptr_array_index (priv->elements, i);
		g_autofree gchar *tmp = NULL;
		tmp = dfu_element_to_string (element);
		g_string_append_printf (str, "== ELEMENT %u ==\n", i);
		g_string_append_printf (str, "%s\n", tmp);
	}

	g_string_truncate (str, str->len - 1);
	return g_string_free (str, FALSE);
}
Beispiel #2
0
/**
 * dfu_image_get_elements:
 * @image: a #DfuImage
 *
 * Gets the element data.
 *
 * Return value: (transfer none) (element-type DfuElement): element data
 **/
GPtrArray *
dfu_image_get_elements (DfuImage *image)
{
	DfuImagePrivate *priv = GET_PRIVATE (image);
	g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
	return priv->elements;
}
Beispiel #3
0
/**
 * dfu_image_set_alt_setting:
 * @image: a #DfuImage
 * @alt_setting: vendor ID, or 0xffff for unset
 *
 * Sets the vendor ID.
 **/
void
dfu_image_set_alt_setting (DfuImage *image, guint8 alt_setting)
{
	DfuImagePrivate *priv = GET_PRIVATE (image);
	g_return_if_fail (DFU_IS_IMAGE (image));
	priv->alt_setting = alt_setting;
}
Beispiel #4
0
/**
 * dfu_image_get_name:
 * @image: a #DfuImage
 *
 * Gets the target name.
 *
 * Return value: a string, or %NULL for unset
 **/
const gchar *
dfu_image_get_name (DfuImage *image)
{
	DfuImagePrivate *priv = GET_PRIVATE (image);
	g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
	return priv->name;
}
Beispiel #5
0
/**
 * dfu_image_get_alt_setting:
 * @image: a #DfuImage
 *
 * Gets the alternate setting.
 *
 * Return value: integer, or 0x00 for unset
 **/
guint8
dfu_image_get_alt_setting (DfuImage *image)
{
	DfuImagePrivate *priv = GET_PRIVATE (image);
	g_return_val_if_fail (DFU_IS_IMAGE (image), 0xff);
	return priv->alt_setting;
}
Beispiel #6
0
/**
 * dfu_image_add_element:
 * @image: a #DfuImage
 * @element: a #DfuElement
 *
 * Adds an element to the image.
 **/
void
dfu_image_add_element (DfuImage *image, DfuElement *element)
{
	DfuImagePrivate *priv = GET_PRIVATE (image);
	g_return_if_fail (DFU_IS_IMAGE (image));
	g_return_if_fail (DFU_IS_ELEMENT (element));
	g_ptr_array_add (priv->elements, g_object_ref (element));
}
Beispiel #7
0
/**
 * dfu_image_get_element_default:
 * @image: a #DfuImage
 *
 * Gets the default element.
 *
 * Return value: (transfer none): element data, or %NULL for invalid
 **/
DfuElement *
dfu_image_get_element_default (DfuImage *image)
{
	DfuImagePrivate *priv = GET_PRIVATE (image);
	g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
	if (priv->elements->len == 0)
		return NULL;
	return g_ptr_array_index (priv->elements, 0);
}
Beispiel #8
0
/**
 * dfu_image_get_element:
 * @image: a #DfuImage
 * @idx: an array index
 *
 * Gets the element.
 *
 * Return value: (transfer none): element data, or %NULL for invalid
 **/
DfuElement *
dfu_image_get_element (DfuImage *image, guint8 idx)
{
	DfuImagePrivate *priv = GET_PRIVATE (image);
	g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
	if (idx >= priv->elements->len)
		return NULL;
	return g_ptr_array_index (priv->elements, idx);
}
Beispiel #9
0
/**
 * dfu_image_get_size:
 * @image: a #DfuImage
 *
 * Gets the size of all the elements in the image.
 *
 * This only returns actual data that would be sent to the device and
 * does not include any padding.
 *
 * Return value: a integer value, or 0 if there are no elements.
 **/
guint32
dfu_image_get_size (DfuImage *image)
{
	DfuImagePrivate *priv = GET_PRIVATE (image);
	guint32 length = 0;
	g_return_val_if_fail (DFU_IS_IMAGE (image), 0);
	for (guint i = 0; i < priv->elements->len; i++) {
		DfuElement *element = g_ptr_array_index (priv->elements, i);
		length += (guint32) g_bytes_get_size (dfu_element_get_contents (element));
	}
	return length;
}
Beispiel #10
0
/**
 * dfu_image_set_name:
 * @image: a #DfuImage
 * @name: a target string, or %NULL
 *
 * Sets the target name.
 **/
void
dfu_image_set_name (DfuImage *image, const gchar *name)
{
	guint16 sz;
	DfuImagePrivate *priv = GET_PRIVATE (image);
	g_return_if_fail (DFU_IS_IMAGE (image));

	/* this is a hard limit in DfuSe */
	memset (priv->name, 0x00, 0xff);
	if (name != NULL) {
		sz = MIN ((guint16) strlen (name), 0xff - 1);
		memcpy (priv->name, name, sz);
	}

	/* copy junk data in self tests for 1:1 copies */
	if (name != NULL && G_UNLIKELY (g_getenv ("DFU_SELF_TEST_IMAGE_MEMCPY_NAME") != NULL))
		memcpy (priv->name, name, 0xff);
}
Beispiel #11
0
/**
 * dfu_target_download:
 * @target: a #DfuTarget
 * @image: a #DfuImage
 * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY
 * @cancellable: a #GCancellable, or %NULL
 * @error: a #GError, or %NULL
 *
 * Downloads firmware from the host to the target, optionally verifying
 * the transfer.
 *
 * Return value: %TRUE for success
 *
 * Since: 0.5.4
 **/
gboolean
dfu_target_download (DfuTarget *target, DfuImage *image,
		     DfuTargetTransferFlags flags,
		     GCancellable *cancellable,
		     GError **error)
{
	DfuTargetPrivate *priv = GET_PRIVATE (target);
	DfuElement *element;
	GPtrArray *elements;
	gboolean ret;
	guint i;

	g_return_val_if_fail (DFU_IS_TARGET (target), FALSE);
	g_return_val_if_fail (DFU_IS_IMAGE (image), FALSE);
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

	/* ensure populated */
	if (!dfu_target_setup (target, error))
		return NULL;

	/* can the target do this? */
	if (!dfu_device_can_download (priv->device)) {
		g_set_error_literal (error,
				     DFU_ERROR,
				     DFU_ERROR_NOT_SUPPORTED,
				     "target cannot do downloading");
		return FALSE;
	}

	/* use correct alt */
	if (!dfu_target_use_alt_setting (target, error))
		return FALSE;

	/* mark these as all erased */
	if (dfu_device_has_dfuse_support (priv->device))
		g_hash_table_remove_all (priv->sectors_erased);

	/* download all elements in the image to the device */
	elements = dfu_image_get_elements (image);
	if (elements->len == 0) {
		g_set_error_literal (error,
				     DFU_ERROR,
				     DFU_ERROR_INVALID_FILE,
				     "no image elements");
		return FALSE;
	}
	for (i = 0; i < elements->len; i++) {
		element = dfu_image_get_element (image, i);
		g_debug ("downloading element at 0x%04x",
			 dfu_element_get_address (element));
		ret = dfu_target_download_element (target,
						   element,
						   flags,
						   cancellable,
						   error);
		if (!ret)
			return FALSE;
	}

	/* attempt to switch back to runtime */
	if ((flags & DFU_TARGET_TRANSFER_FLAG_ATTACH) > 0 ||
	    (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) > 0) {
		if (!dfu_device_attach (priv->device, error))
			return FALSE;
	}

	/* boot to runtime */
	if (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) {
		g_debug ("booting to runtime to set auto-boot");
		if (!dfu_device_wait_for_replug (priv->device,
						 DFU_DEVICE_REPLUG_TIMEOUT,
						 cancellable,
						 error))
			return FALSE;
	}

	/* success */
	return TRUE;
}