dfu: Use FuChunk rather than defining DfuElement

This commit is contained in:
Richard Hughes 2021-01-29 10:45:11 +00:00
parent 6de10e118c
commit ed4b8e28db
15 changed files with 175 additions and 378 deletions

View File

@ -123,7 +123,7 @@ dfu_version_to_string (DfuVersion version)
/** /**
* dfu_utils_bytes_join_array: * dfu_utils_bytes_join_array:
* @chunks: (element-kind GBytes): bytes * @chunks: (element-type GBytes): bytes
* *
* Creates a monolithic block of memory from an array of #GBytes. * Creates a monolithic block of memory from an array of #GBytes.
* *

View File

@ -1,170 +0,0 @@
/*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
/**
* SECTION:dfu-element
* @short_description: Object representing a binary element
*
* This object represents an binary blob of data at a specific address.
*
* This allows relocatable data segments to be stored in different
* locations on the device itself.
*
* See also: #DfuImage, #DfuFirmware
*/
#include "config.h"
#include <string.h>
#include <stdio.h>
#include "dfu-common.h"
#include "dfu-element.h"
#include "fwupd-error.h"
static void dfu_element_finalize (GObject *object);
typedef struct {
GBytes *contents;
guint32 address;
} DfuElementPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (DfuElement, dfu_element, G_TYPE_OBJECT)
#define GET_PRIVATE(o) (dfu_element_get_instance_private (o))
static void
dfu_element_class_init (DfuElementClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = dfu_element_finalize;
}
static void
dfu_element_init (DfuElement *element)
{
}
static void
dfu_element_finalize (GObject *object)
{
DfuElement *element = DFU_ELEMENT (object);
DfuElementPrivate *priv = GET_PRIVATE (element);
if (priv->contents != NULL)
g_bytes_unref (priv->contents);
G_OBJECT_CLASS (dfu_element_parent_class)->finalize (object);
}
/**
* dfu_element_new:
*
* Creates a new DFU element object.
*
* Return value: a new #DfuElement
**/
DfuElement *
dfu_element_new (void)
{
DfuElement *element;
element = g_object_new (DFU_TYPE_ELEMENT, NULL);
return element;
}
/**
* dfu_element_get_contents:
* @element: a #DfuElement
*
* Gets the element data.
*
* Return value: (transfer none): element data
**/
GBytes *
dfu_element_get_contents (DfuElement *element)
{
DfuElementPrivate *priv = GET_PRIVATE (element);
g_return_val_if_fail (DFU_IS_ELEMENT (element), NULL);
return priv->contents;
}
/**
* dfu_element_get_address:
* @element: a #DfuElement
*
* Gets the offset address of the element.
*
* Return value: memory offset value, or 0x00 for unset
**/
guint32
dfu_element_get_address (DfuElement *element)
{
DfuElementPrivate *priv = GET_PRIVATE (element);
g_return_val_if_fail (DFU_IS_ELEMENT (element), 0x00);
return priv->address;
}
/**
* dfu_element_set_contents:
* @element: a #DfuElement
* @contents: element data
*
* Sets the element data.
**/
void
dfu_element_set_contents (DfuElement *element, GBytes *contents)
{
DfuElementPrivate *priv = GET_PRIVATE (element);
g_return_if_fail (DFU_IS_ELEMENT (element));
g_return_if_fail (contents != NULL);
if (priv->contents == contents)
return;
if (priv->contents != NULL)
g_bytes_unref (priv->contents);
priv->contents = g_bytes_ref (contents);
}
/**
* dfu_element_set_address:
* @element: a #DfuElement
* @address: memory offset value
*
* Sets the offset address of the element.
**/
void
dfu_element_set_address (DfuElement *element, guint32 address)
{
DfuElementPrivate *priv = GET_PRIVATE (element);
g_return_if_fail (DFU_IS_ELEMENT (element));
priv->address = address;
}
/**
* dfu_element_to_string:
* @element: a #DfuElement
*
* Returns a string representation of the object.
*
* Return value: NULL terminated string, or %NULL for invalid
**/
gchar *
dfu_element_to_string (DfuElement *element)
{
DfuElementPrivate *priv = GET_PRIVATE (element);
GString *str;
g_return_val_if_fail (DFU_IS_ELEMENT (element), NULL);
str = g_string_new ("");
g_string_append_printf (str, "address: 0x%02x\n", priv->address);
if (priv->contents != NULL) {
g_string_append_printf (str, "contents: 0x%04x\n",
(guint32) g_bytes_get_size (priv->contents));
}
g_string_truncate (str, str->len - 1);
return g_string_free (str, FALSE);
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#pragma once
#include <glib-object.h>
#include <gio/gio.h>
#define DFU_TYPE_ELEMENT (dfu_element_get_type ())
G_DECLARE_DERIVABLE_TYPE (DfuElement, dfu_element, DFU, ELEMENT, GObject)
struct _DfuElementClass
{
GObjectClass parent_class;
};
DfuElement *dfu_element_new (void);
GBytes *dfu_element_get_contents (DfuElement *element);
guint32 dfu_element_get_address (DfuElement *element);
void dfu_element_set_contents (DfuElement *element,
GBytes *contents);
void dfu_element_set_address (DfuElement *element,
guint32 address);
gchar *dfu_element_to_string (DfuElement *element);

View File

@ -8,9 +8,9 @@
#include <string.h> #include <string.h>
#include "fu-chunk.h"
#include "fu-dfu-firmware.h" #include "fu-dfu-firmware.h"
#include "dfu-element.h"
#include "dfu-format-dfu.h" #include "dfu-format-dfu.h"
#include "dfu-format-dfuse.h" #include "dfu-format-dfuse.h"
#include "dfu-format-raw.h" #include "dfu-format-raw.h"
@ -125,21 +125,21 @@ dfu_firmware_to_dfu (DfuFirmware *firmware, GError **error)
{ {
/* plain DFU */ /* plain DFU */
if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFU) { if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFU) {
GBytes *contents; g_autoptr(GBytes) contents = NULL;
DfuElement *element; FuChunk *chk;
g_autoptr(DfuImage) image = NULL; g_autoptr(DfuImage) image = NULL;
image = DFU_IMAGE (fu_firmware_get_image_default (FU_FIRMWARE (firmware), error)); image = DFU_IMAGE (fu_firmware_get_image_default (FU_FIRMWARE (firmware), error));
if (image == NULL) if (image == NULL)
return NULL; return NULL;
element = dfu_image_get_element (image, 0); chk = dfu_image_get_chunk_by_idx (image, 0);
if (element == NULL) { if (chk == NULL) {
g_set_error (error, g_set_error (error,
FWUPD_ERROR, FWUPD_ERROR,
FWUPD_ERROR_NOT_FOUND, FWUPD_ERROR_NOT_FOUND,
"no firmware element data to write"); "no firmware element data to write");
return NULL; return NULL;
} }
contents = dfu_element_get_contents (element); contents = fu_chunk_get_bytes (chk);
return dfu_firmware_add_footer (firmware, contents, error); return dfu_firmware_add_footer (firmware, contents, error);
} }

View File

@ -9,8 +9,8 @@
#include <string.h> #include <string.h>
#include "fu-common.h" #include "fu-common.h"
#include "fu-chunk.h"
#include "dfu-element.h"
#include "dfu-format-dfuse.h" #include "dfu-format-dfuse.h"
#include "dfu-image.h" #include "dfu-image.h"
@ -31,15 +31,15 @@ typedef struct __attribute__((packed)) {
* *
* Unpacks an element from DfuSe data. * Unpacks an element from DfuSe data.
* *
* Returns: a #DfuElement, or %NULL for error * Returns: a #FuChunk, or %NULL for error
**/ **/
static DfuElement * static FuChunk *
dfu_element_from_dfuse (const guint8 *data, dfu_element_from_dfuse (const guint8 *data,
guint32 length, guint32 length,
guint32 *consumed, guint32 *consumed,
GError **error) GError **error)
{ {
DfuElement *element = NULL; FuChunk *chk = NULL;
DfuSeElementPrefix *el = (DfuSeElementPrefix *) data; DfuSeElementPrefix *el = (DfuSeElementPrefix *) data;
guint32 size; guint32 size;
g_autoptr(GBytes) contents = NULL; g_autoptr(GBytes) contents = NULL;
@ -68,39 +68,39 @@ dfu_element_from_dfuse (const guint8 *data,
return NULL; return NULL;
} }
/* create new element */ /* create new chk */
element = dfu_element_new ();
dfu_element_set_address (element, GUINT32_FROM_LE (el->address));
contents = g_bytes_new (data + sizeof(DfuSeElementPrefix), size); contents = g_bytes_new (data + sizeof(DfuSeElementPrefix), size);
dfu_element_set_contents (element, contents); chk = fu_chunk_bytes_new (contents);
fu_chunk_set_address (chk, GUINT32_FROM_LE (el->address));
/* return size */ /* return size */
if (consumed != NULL) if (consumed != NULL)
*consumed = (guint32) sizeof(DfuSeElementPrefix) + size; *consumed = (guint32) sizeof(DfuSeElementPrefix) + size;
return element; return chk;
} }
/** /**
* dfu_element_to_dfuse: (skip) * dfu_element_to_dfuse: (skip)
* @element: a #DfuElement * @chk: a #FuChunk
* *
* Packs a DfuSe element. * Packs a DfuSe element.
* *
* Returns: (transfer full): the packed data * Returns: (transfer full): the packed data
**/ **/
static GBytes * static GBytes *
dfu_element_to_dfuse (DfuElement *element) dfu_element_to_dfuse (FuChunk *chk)
{ {
DfuSeElementPrefix *el; DfuSeElementPrefix *el;
const guint8 *data; const guint8 *data;
gsize length; gsize length;
guint8 *buf; guint8 *buf;
data = g_bytes_get_data (dfu_element_get_contents (element), &length); data = fu_chunk_get_data (chk);
length = fu_chunk_get_data_sz (chk);
buf = g_malloc0 (length + sizeof (DfuSeElementPrefix)); buf = g_malloc0 (length + sizeof (DfuSeElementPrefix));
el = (DfuSeElementPrefix *) buf; el = (DfuSeElementPrefix *) buf;
el->address = GUINT32_TO_LE (dfu_element_get_address (element)); el->address = GUINT32_TO_LE (fu_chunk_get_address (chk));
el->size = GUINT32_TO_LE (length); el->size = GUINT32_TO_LE (length);
memcpy (buf + sizeof (DfuSeElementPrefix), data, length); memcpy (buf + sizeof (DfuSeElementPrefix), data, length);
@ -114,7 +114,7 @@ typedef struct __attribute__((packed)) {
guint32 target_named; guint32 target_named;
gchar target_name[255]; gchar target_name[255];
guint32 target_size; guint32 target_size;
guint32 elements; guint32 chunks;
} DfuSeImagePrefix; } DfuSeImagePrefix;
/** /**
@ -135,7 +135,7 @@ dfu_image_from_dfuse (const guint8 *data,
GError **error) GError **error)
{ {
DfuSeImagePrefix *im; DfuSeImagePrefix *im;
guint32 elements; guint32 chunks;
guint32 offset = sizeof(DfuSeImagePrefix); guint32 offset = sizeof(DfuSeImagePrefix);
g_autoptr(DfuImage) image = NULL; g_autoptr(DfuImage) image = NULL;
@ -167,17 +167,17 @@ dfu_image_from_dfuse (const guint8 *data,
if (GUINT32_FROM_LE (im->target_named) == 0x01) if (GUINT32_FROM_LE (im->target_named) == 0x01)
dfu_image_set_name (image, im->target_name); dfu_image_set_name (image, im->target_name);
/* parse elements */ /* parse chunks */
length -= offset; length -= offset;
elements = GUINT32_FROM_LE (im->elements); chunks = GUINT32_FROM_LE (im->chunks);
for (guint j = 0; j < elements; j++) { for (guint j = 0; j < chunks; j++) {
guint32 consumed_local; guint32 consumed_local;
g_autoptr(DfuElement) element = NULL; g_autoptr(FuChunk) chk = NULL;
element = dfu_element_from_dfuse (data + offset, length, chk = dfu_element_from_dfuse (data + offset, length,
&consumed_local, error); &consumed_local, error);
if (element == NULL) if (chk == NULL)
return NULL; return NULL;
dfu_image_add_element (image, element); dfu_image_add_chunk (image, chk);
offset += consumed_local; offset += consumed_local;
length -= consumed_local; length -= consumed_local;
} }
@ -201,7 +201,7 @@ static GBytes *
dfu_image_to_dfuse (DfuImage *image) dfu_image_to_dfuse (DfuImage *image)
{ {
DfuSeImagePrefix *im; DfuSeImagePrefix *im;
GPtrArray *elements; GPtrArray *chunks;
guint32 length_total = 0; guint32 length_total = 0;
guint32 offset = sizeof (DfuSeImagePrefix); guint32 offset = sizeof (DfuSeImagePrefix);
guint8 *buf; guint8 *buf;
@ -209,10 +209,10 @@ dfu_image_to_dfuse (DfuImage *image)
/* get total size */ /* get total size */
element_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref); element_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
elements = dfu_image_get_elements (image); chunks = dfu_image_get_chunks (image);
for (guint i = 0; i < elements->len; i++) { for (guint i = 0; i < chunks->len; i++) {
DfuElement *element = g_ptr_array_index (elements, i); FuChunk *chk = g_ptr_array_index (chunks, i);
GBytes *bytes = dfu_element_to_dfuse (element); GBytes *bytes = dfu_element_to_dfuse (chk);
g_ptr_array_add (element_array, bytes); g_ptr_array_add (element_array, bytes);
length_total += (guint32) g_bytes_get_size (bytes); length_total += (guint32) g_bytes_get_size (bytes);
} }
@ -227,7 +227,7 @@ dfu_image_to_dfuse (DfuImage *image)
memcpy (im->target_name, dfu_image_get_name (image), 255); memcpy (im->target_name, dfu_image_get_name (image), 255);
} }
im->target_size = GUINT32_TO_LE (length_total); im->target_size = GUINT32_TO_LE (length_total);
im->elements = GUINT32_TO_LE (elements->len); im->chunks = GUINT32_TO_LE (chunks->len);
/* copy data */ /* copy data */
for (guint i = 0; i < element_array->len; i++) { for (guint i = 0; i < element_array->len; i++) {

View File

@ -8,7 +8,8 @@
#include <string.h> #include <string.h>
#include "dfu-element.h" #include "fu-chunk.h"
#include "dfu-format-raw.h" #include "dfu-format-raw.h"
#include "dfu-image.h" #include "dfu-image.h"
@ -31,12 +32,11 @@ dfu_firmware_from_raw (DfuFirmware *firmware,
FwupdInstallFlags flags, FwupdInstallFlags flags,
GError **error) GError **error)
{ {
g_autoptr(DfuElement) element = NULL; g_autoptr(FuChunk) chk = NULL;
g_autoptr(DfuImage) image = NULL; g_autoptr(DfuImage) image = NULL;
image = dfu_image_new (); image = dfu_image_new ();
element = dfu_element_new (); chk = fu_chunk_bytes_new (bytes);
dfu_element_set_contents (element, bytes); dfu_image_add_chunk (image, chk);
dfu_image_add_element (image, element);
fu_firmware_add_image (FU_FIRMWARE (firmware), FU_FIRMWARE_IMAGE (image)); fu_firmware_add_image (FU_FIRMWARE (firmware), FU_FIRMWARE_IMAGE (image));
return TRUE; return TRUE;
} }
@ -53,21 +53,19 @@ dfu_firmware_from_raw (DfuFirmware *firmware,
GBytes * GBytes *
dfu_firmware_to_raw (DfuFirmware *firmware, GError **error) dfu_firmware_to_raw (DfuFirmware *firmware, GError **error)
{ {
DfuElement *element; FuChunk *chk;
DfuImage *image; DfuImage *image;
GBytes *contents;
image = DFU_IMAGE (fu_firmware_get_image_default (FU_FIRMWARE (firmware), error)); image = DFU_IMAGE (fu_firmware_get_image_default (FU_FIRMWARE (firmware), error));
if (image == NULL) if (image == NULL)
return NULL; return NULL;
element = dfu_image_get_element (image, 0); chk = dfu_image_get_chunk_by_idx (image, 0);
if (element == NULL) { if (chk == NULL) {
g_set_error_literal (error, g_set_error_literal (error,
FWUPD_ERROR, FWUPD_ERROR,
FWUPD_ERROR_NOT_FOUND, FWUPD_ERROR_NOT_FOUND,
"no firmware element data to write"); "no firmware chunk data to write");
return NULL; return NULL;
} }
contents = dfu_element_get_contents (element); return fu_chunk_get_bytes (chk);
return g_bytes_ref (contents);
} }

View File

@ -11,7 +11,7 @@
* A #DfuImage is typically made up of several #DfuElements, although * A #DfuImage is typically made up of several #DfuElements, although
* typically there will only be one. * typically there will only be one.
* *
* See also: #DfuElement * See also: #FuChunk
*/ */
#include "config.h" #include "config.h"
@ -22,13 +22,12 @@
#include "fu-common.h" #include "fu-common.h"
#include "dfu-common.h" #include "dfu-common.h"
#include "dfu-element.h"
#include "dfu-image.h" #include "dfu-image.h"
static void dfu_image_finalize (GObject *object); static void dfu_image_finalize (GObject *object);
typedef struct { typedef struct {
GPtrArray *elements; GPtrArray *chunks;
gchar name[255]; gchar name[255];
} DfuImagePrivate; } DfuImagePrivate;
@ -39,7 +38,7 @@ static void
dfu_image_init (DfuImage *image) dfu_image_init (DfuImage *image)
{ {
DfuImagePrivate *priv = GET_PRIVATE (image); DfuImagePrivate *priv = GET_PRIVATE (image);
priv->elements = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
memset (priv->name, 0x00, 255); memset (priv->name, 0x00, 255);
} }
@ -49,7 +48,7 @@ dfu_image_finalize (GObject *object)
DfuImage *image = DFU_IMAGE (object); DfuImage *image = DFU_IMAGE (object);
DfuImagePrivate *priv = GET_PRIVATE (image); DfuImagePrivate *priv = GET_PRIVATE (image);
g_ptr_array_unref (priv->elements); g_ptr_array_unref (priv->chunks);
G_OBJECT_CLASS (dfu_image_parent_class)->finalize (object); G_OBJECT_CLASS (dfu_image_parent_class)->finalize (object);
} }
@ -70,56 +69,56 @@ dfu_image_new (void)
} }
/** /**
* dfu_image_get_elements: * dfu_image_get_chunks:
* @image: a #DfuImage * @image: a #DfuImage
* *
* Gets the element data. * Gets the element data.
* *
* Return value: (transfer none) (element-type DfuElement): element data * Return value: (transfer none) (element-type FuChunk): chunk data
**/ **/
GPtrArray * GPtrArray *
dfu_image_get_elements (DfuImage *image) dfu_image_get_chunks (DfuImage *image)
{ {
DfuImagePrivate *priv = GET_PRIVATE (image); DfuImagePrivate *priv = GET_PRIVATE (image);
g_return_val_if_fail (DFU_IS_IMAGE (image), NULL); g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
return priv->elements; return priv->chunks;
} }
/** /**
* dfu_image_get_element: * dfu_image_get_chunk_by_idx:
* @image: a #DfuImage * @image: a #DfuImage
* @idx: an array index * @idx: an array index
* *
* Gets the element. * Gets the element.
* *
* Return value: (transfer none): element data, or %NULL for invalid * Return value: (transfer none): chunk data, or %NULL for invalid
**/ **/
DfuElement * FuChunk *
dfu_image_get_element (DfuImage *image, guint8 idx) dfu_image_get_chunk_by_idx (DfuImage *image, guint8 idx)
{ {
DfuImagePrivate *priv = GET_PRIVATE (image); DfuImagePrivate *priv = GET_PRIVATE (image);
g_return_val_if_fail (DFU_IS_IMAGE (image), NULL); g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
if (idx >= priv->elements->len) if (idx >= priv->chunks->len)
return NULL; return NULL;
return g_ptr_array_index (priv->elements, idx); return g_ptr_array_index (priv->chunks, idx);
} }
/** /**
* dfu_image_get_element_default: * dfu_image_get_chunk_default:
* @image: a #DfuImage * @image: a #DfuImage
* *
* Gets the default element. * Gets the default element.
* *
* Return value: (transfer none): element data, or %NULL for invalid * Return value: (transfer none): chunk data, or %NULL for invalid
**/ **/
DfuElement * FuChunk *
dfu_image_get_element_default (DfuImage *image) dfu_image_get_chunk_default (DfuImage *image)
{ {
DfuImagePrivate *priv = GET_PRIVATE (image); DfuImagePrivate *priv = GET_PRIVATE (image);
g_return_val_if_fail (DFU_IS_IMAGE (image), NULL); g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
if (priv->elements->len == 0) if (priv->chunks->len == 0)
return NULL; return NULL;
return g_ptr_array_index (priv->elements, 0); return g_ptr_array_index (priv->chunks, 0);
} }
/** /**
@ -157,12 +156,12 @@ dfu_image_get_name (DfuImage *image)
* dfu_image_get_size: * dfu_image_get_size:
* @image: a #DfuImage * @image: a #DfuImage
* *
* Gets the size of all the elements in the image. * Gets the size of all the chunks in the image.
* *
* This only returns actual data that would be sent to the device and * This only returns actual data that would be sent to the device and
* does not include any padding. * does not include any padding.
* *
* Return value: a integer value, or 0 if there are no elements. * Return value: a integer value, or 0 if there are no chunks.
**/ **/
guint32 guint32
dfu_image_get_size (DfuImage *image) dfu_image_get_size (DfuImage *image)
@ -170,27 +169,27 @@ dfu_image_get_size (DfuImage *image)
DfuImagePrivate *priv = GET_PRIVATE (image); DfuImagePrivate *priv = GET_PRIVATE (image);
guint32 length = 0; guint32 length = 0;
g_return_val_if_fail (DFU_IS_IMAGE (image), 0); g_return_val_if_fail (DFU_IS_IMAGE (image), 0);
for (guint i = 0; i < priv->elements->len; i++) { for (guint i = 0; i < priv->chunks->len; i++) {
DfuElement *element = g_ptr_array_index (priv->elements, i); FuChunk *chk = g_ptr_array_index (priv->chunks, i);
length += (guint32) g_bytes_get_size (dfu_element_get_contents (element)); length += fu_chunk_get_data_sz (chk);
} }
return length; return length;
} }
/** /**
* dfu_image_add_element: * dfu_image_add_chunk:
* @image: a #DfuImage * @image: a #DfuImage
* @element: a #DfuElement * @chk: a #FuChunk
* *
* Adds an element to the image. * Adds an element to the image.
**/ **/
void void
dfu_image_add_element (DfuImage *image, DfuElement *element) dfu_image_add_chunk (DfuImage *image, FuChunk *chk)
{ {
DfuImagePrivate *priv = GET_PRIVATE (image); DfuImagePrivate *priv = GET_PRIVATE (image);
g_return_if_fail (DFU_IS_IMAGE (image)); g_return_if_fail (DFU_IS_IMAGE (image));
g_return_if_fail (DFU_IS_ELEMENT (element)); g_return_if_fail (FU_IS_CHUNK (chk));
g_ptr_array_add (priv->elements, g_object_ref (element)); g_ptr_array_add (priv->chunks, g_object_ref (chk));
} }
/** /**
@ -239,13 +238,13 @@ dfu_image_to_string (FuFirmwareImage *self, guint idt, GString *str)
DfuImagePrivate *priv = GET_PRIVATE (image); DfuImagePrivate *priv = GET_PRIVATE (image);
if (priv->name[0] != '\0') if (priv->name[0] != '\0')
fu_common_string_append_kv (str, idt, "Name", priv->name); fu_common_string_append_kv (str, idt, "Name", priv->name);
fu_common_string_append_ku (str, idt, "Elements", priv->elements->len); fu_common_string_append_ku (str, idt, "Elements", priv->chunks->len);
/* add elements */ /* add chunks */
for (guint i = 0; i < priv->elements->len; i++) { for (guint i = 0; i < priv->chunks->len; i++) {
DfuElement *element = g_ptr_array_index (priv->elements, i); FuChunk *chk = g_ptr_array_index (priv->chunks, i);
g_autofree gchar *tmp = NULL; g_autofree gchar *tmp = NULL;
tmp = dfu_element_to_string (element); tmp = fu_chunk_to_string (chk);
g_string_append_printf (str, "== ELEMENT %u ==\n", i); g_string_append_printf (str, "== ELEMENT %u ==\n", i);
g_string_append_printf (str, "%s\n", tmp); g_string_append_printf (str, "%s\n", tmp);
} }

View File

@ -9,10 +9,9 @@
#include <glib-object.h> #include <glib-object.h>
#include <gio/gio.h> #include <gio/gio.h>
#include "fu-chunk.h"
#include "fu-firmware-image.h" #include "fu-firmware-image.h"
#include "dfu-element.h"
#define DFU_TYPE_IMAGE (dfu_image_get_type ()) #define DFU_TYPE_IMAGE (dfu_image_get_type ())
G_DECLARE_DERIVABLE_TYPE (DfuImage, dfu_image, DFU, IMAGE, FuFirmwareImage) G_DECLARE_DERIVABLE_TYPE (DfuImage, dfu_image, DFU, IMAGE, FuFirmwareImage)
@ -23,16 +22,16 @@ struct _DfuImageClass
DfuImage *dfu_image_new (void); DfuImage *dfu_image_new (void);
GPtrArray *dfu_image_get_elements (DfuImage *image); GPtrArray *dfu_image_get_chunks (DfuImage *image);
DfuElement *dfu_image_get_element (DfuImage *image, FuChunk *dfu_image_get_chunk_by_idx (DfuImage *image,
guint8 idx); guint8 idx);
DfuElement *dfu_image_get_element_default (DfuImage *image); FuChunk *dfu_image_get_chunk_default (DfuImage *image);
guint8 dfu_image_get_alt_setting (DfuImage *image); guint8 dfu_image_get_alt_setting (DfuImage *image);
const gchar *dfu_image_get_name (DfuImage *image); const gchar *dfu_image_get_name (DfuImage *image);
guint32 dfu_image_get_size (DfuImage *image); guint32 dfu_image_get_size (DfuImage *image);
void dfu_image_add_element (DfuImage *image, void dfu_image_add_chunk (DfuImage *image,
DfuElement *element); FuChunk *chk);
void dfu_image_set_alt_setting (DfuImage *image, void dfu_image_set_alt_setting (DfuImage *image,
guint8 alt_setting); guint8 alt_setting);

View File

@ -17,6 +17,7 @@
#include "dfu-target-private.h" #include "dfu-target-private.h"
#include "fu-common.h" #include "fu-common.h"
#include "fu-chunk.h"
#include "fwupd-error.h" #include "fwupd-error.h"
@ -61,13 +62,13 @@ fu_test_compare_lines (const gchar *txt1, const gchar *txt2, GError **error)
static void static void
dfu_firmware_raw_func (void) dfu_firmware_raw_func (void)
{ {
DfuElement *element; FuChunk *chk;
GBytes *no_suffix_contents;
gchar buf[256]; gchar buf[256];
gboolean ret; gboolean ret;
g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(DfuFirmware) firmware = NULL;
g_autoptr(DfuImage) image_tmp = NULL; g_autoptr(DfuImage) image_tmp = NULL;
g_autoptr(GBytes) fw = NULL; g_autoptr(GBytes) fw = NULL;
g_autoptr(GBytes) no_suffix_contents = NULL;
g_autoptr(GBytes) roundtrip = NULL; g_autoptr(GBytes) roundtrip = NULL;
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
@ -90,9 +91,9 @@ dfu_firmware_raw_func (void)
image_tmp = DFU_IMAGE (fu_firmware_get_image_by_idx (FU_FIRMWARE (firmware), 0, NULL)); image_tmp = DFU_IMAGE (fu_firmware_get_image_by_idx (FU_FIRMWARE (firmware), 0, NULL));
g_assert (image_tmp != NULL); g_assert (image_tmp != NULL);
g_assert_cmpint (dfu_image_get_size (image_tmp), ==, 256); g_assert_cmpint (dfu_image_get_size (image_tmp), ==, 256);
element = dfu_image_get_element (image_tmp, 0); chk = dfu_image_get_chunk_by_idx (image_tmp, 0);
g_assert (element != NULL); g_assert (chk != NULL);
no_suffix_contents = dfu_element_get_contents (element); no_suffix_contents = fu_chunk_get_bytes (chk);
g_assert (no_suffix_contents != NULL); g_assert (no_suffix_contents != NULL);
g_assert_cmpint (g_bytes_compare (no_suffix_contents, fw), ==, 0); g_assert_cmpint (g_bytes_compare (no_suffix_contents, fw), ==, 0);
@ -116,7 +117,7 @@ dfu_firmware_dfu_func (void)
g_autoptr(DfuFirmware) firmware2 = dfu_firmware_new (); g_autoptr(DfuFirmware) firmware2 = dfu_firmware_new ();
g_autoptr(DfuFirmware) firmware3 = dfu_firmware_new (); g_autoptr(DfuFirmware) firmware3 = dfu_firmware_new ();
g_autoptr(DfuImage) image = NULL; g_autoptr(DfuImage) image = NULL;
g_autoptr(DfuElement) element = NULL; g_autoptr(FuChunk) chk = NULL;
g_autoptr(GBytes) data = NULL; g_autoptr(GBytes) data = NULL;
g_autoptr(GBytes) fw = NULL; g_autoptr(GBytes) fw = NULL;
g_autoptr(GBytes) roundtrip_orig = NULL; g_autoptr(GBytes) roundtrip_orig = NULL;
@ -135,9 +136,8 @@ dfu_firmware_dfu_func (void)
fu_dfu_firmware_set_pid (FU_DFU_FIRMWARE (firmware1), 0x5678); fu_dfu_firmware_set_pid (FU_DFU_FIRMWARE (firmware1), 0x5678);
fu_dfu_firmware_set_release (FU_DFU_FIRMWARE (firmware1), 0xfedc); fu_dfu_firmware_set_release (FU_DFU_FIRMWARE (firmware1), 0xfedc);
image = dfu_image_new (); image = dfu_image_new ();
element = dfu_element_new (); chk = fu_chunk_bytes_new (fw);
dfu_element_set_contents (element, fw); dfu_image_add_chunk (image, chk);
dfu_image_add_element (image, element);
fu_firmware_add_image (FU_FIRMWARE (firmware1), FU_FIRMWARE_IMAGE (image)); fu_firmware_add_image (FU_FIRMWARE (firmware1), FU_FIRMWARE_IMAGE (image));
g_assert_cmpint (dfu_firmware_get_size (firmware1), ==, 256); g_assert_cmpint (dfu_firmware_get_size (firmware1), ==, 256);
data = dfu_firmware_write_data (firmware1, &error); data = dfu_firmware_write_data (firmware1, &error);

View File

@ -26,7 +26,7 @@
* *
* Assigns a sector description for the chip ID. This is required so fwupd can * Assigns a sector description for the chip ID. This is required so fwupd can
* program the user firmware avoiding the bootloader and for checking the total * program the user firmware avoiding the bootloader and for checking the total
* element size. * chunk size.
* *
* The chip ID can be found from a datasheet or using `dfu-tool list` when the * The chip ID can be found from a datasheet or using `dfu-tool list` when the
* hardware is connected and in bootloader mode. * hardware is connected and in bootloader mode.
@ -491,17 +491,17 @@ dfu_target_avr_setup (DfuTarget *target, GError **error)
static gboolean static gboolean
dfu_target_avr_download_element (DfuTarget *target, dfu_target_avr_download_element (DfuTarget *target,
DfuElement *element, FuChunk *chk,
DfuTargetTransferFlags flags, DfuTargetTransferFlags flags,
GError **error) GError **error)
{ {
DfuSector *sector; DfuSector *sector;
GBytes *blob;
const guint8 *data; const guint8 *data;
gsize header_sz = ATMEL_AVR32_CONTROL_BLOCK_SIZE; gsize header_sz = ATMEL_AVR32_CONTROL_BLOCK_SIZE;
guint16 page_last = G_MAXUINT16; guint16 page_last = G_MAXUINT16;
guint32 address; guint32 address;
guint32 address_offset = 0x0; guint32 address_offset = 0x0;
g_autoptr(GBytes) blob = NULL;
g_autoptr(GPtrArray) chunks = NULL; g_autoptr(GPtrArray) chunks = NULL;
const guint8 footer[] = { 0x00, 0x00, 0x00, 0x00, /* CRC */ const guint8 footer[] = { 0x00, 0x00, 0x00, 0x00, /* CRC */
16, /* len */ 16, /* len */
@ -520,7 +520,7 @@ dfu_target_avr_download_element (DfuTarget *target,
return FALSE; return FALSE;
/* verify the element isn't larger than the target size */ /* verify the element isn't larger than the target size */
blob = dfu_element_get_contents (element); blob = fu_chunk_get_bytes (chk);
sector = dfu_target_get_sector_default (target); sector = dfu_target_get_sector_default (target);
if (sector == NULL) { if (sector == NULL) {
g_set_error_literal (error, g_set_error_literal (error,
@ -529,7 +529,7 @@ dfu_target_avr_download_element (DfuTarget *target,
"no sector defined for target"); "no sector defined for target");
return FALSE; return FALSE;
} }
address = dfu_element_get_address (element) & ~0x80000000; address = fu_chunk_get_address (chk) & ~0x80000000;
if (address < dfu_sector_get_address (sector)) { if (address < dfu_sector_get_address (sector)) {
address_offset = dfu_sector_get_address (sector) - address; address_offset = dfu_sector_get_address (sector) - address;
g_warning ("firmware element starts at 0x%x but sector " g_warning ("firmware element starts at 0x%x but sector "
@ -566,38 +566,38 @@ dfu_target_avr_download_element (DfuTarget *target,
/* process each chunk */ /* process each chunk */
for (guint i = 0; i < chunks->len; i++) { for (guint i = 0; i < chunks->len; i++) {
FuChunk *chk = g_ptr_array_index (chunks, i); FuChunk *chk2 = g_ptr_array_index (chunks, i);
g_autofree guint8 *buf = NULL; g_autofree guint8 *buf = NULL;
g_autoptr(GBytes) chunk_tmp = NULL; g_autoptr(GBytes) chunk_tmp = NULL;
/* select page if required */ /* select page if required */
if (fu_chunk_get_page (chk) != page_last) { if (fu_chunk_get_page (chk2) != page_last) {
if (fu_device_has_custom_flag (FU_DEVICE (dfu_target_get_device (target)), if (fu_device_has_custom_flag (FU_DEVICE (dfu_target_get_device (target)),
"legacy-protocol")) { "legacy-protocol")) {
if (!dfu_target_avr_select_memory_page (target, if (!dfu_target_avr_select_memory_page (target,
fu_chunk_get_page (chk), fu_chunk_get_page (chk2),
error)) error))
return FALSE; return FALSE;
} else { } else {
if (!dfu_target_avr32_select_memory_page (target, if (!dfu_target_avr32_select_memory_page (target,
fu_chunk_get_page (chk), fu_chunk_get_page (chk2),
error)) error))
return FALSE; return FALSE;
} }
page_last = fu_chunk_get_page (chk); page_last = fu_chunk_get_page (chk2);
} }
/* create chk with header and footer */ /* create chunk with header and footer */
buf = g_malloc0 (fu_chunk_get_data_sz (chk) + header_sz + sizeof(footer)); buf = g_malloc0 (fu_chunk_get_data_sz (chk2) + header_sz + sizeof(footer));
buf[0] = DFU_AVR32_GROUP_DOWNLOAD; buf[0] = DFU_AVR32_GROUP_DOWNLOAD;
buf[1] = DFU_AVR32_CMD_PROGRAM_START; buf[1] = DFU_AVR32_CMD_PROGRAM_START;
fu_common_write_uint16 (&buf[2], fu_chunk_get_address (chk), G_BIG_ENDIAN); fu_common_write_uint16 (&buf[2], fu_chunk_get_address (chk2), G_BIG_ENDIAN);
fu_common_write_uint16 (&buf[4], fu_chunk_get_address (chk) + fu_chunk_get_data_sz (chk) - 1, G_BIG_ENDIAN); fu_common_write_uint16 (&buf[4], fu_chunk_get_address (chk2) + fu_chunk_get_data_sz (chk2) - 1, G_BIG_ENDIAN);
memcpy (&buf[header_sz], fu_chunk_get_data (chk), fu_chunk_get_data_sz (chk)); memcpy (&buf[header_sz], fu_chunk_get_data (chk2), fu_chunk_get_data_sz (chk2));
memcpy (&buf[header_sz + fu_chunk_get_data_sz (chk)], footer, sizeof(footer)); memcpy (&buf[header_sz + fu_chunk_get_data_sz (chk2)], footer, sizeof(footer));
/* download data */ /* download data */
chunk_tmp = g_bytes_new_static (buf, fu_chunk_get_data_sz (chk) + header_sz + sizeof(footer)); chunk_tmp = g_bytes_new_static (buf, fu_chunk_get_data_sz (chk2) + header_sz + sizeof(footer));
g_debug ("sending %" G_GSIZE_FORMAT " bytes to the hardware", g_debug ("sending %" G_GSIZE_FORMAT " bytes to the hardware",
g_bytes_get_size (chunk_tmp)); g_bytes_get_size (chunk_tmp));
if (!dfu_target_download_chunk (target, i, chunk_tmp, error)) if (!dfu_target_download_chunk (target, i, chunk_tmp, error))
@ -613,7 +613,7 @@ dfu_target_avr_download_element (DfuTarget *target,
return TRUE; return TRUE;
} }
static DfuElement * static FuChunk *
dfu_target_avr_upload_element (DfuTarget *target, dfu_target_avr_upload_element (DfuTarget *target,
guint32 address, guint32 address,
gsize expected_size, gsize expected_size,
@ -622,7 +622,7 @@ dfu_target_avr_upload_element (DfuTarget *target,
{ {
guint16 page_last = G_MAXUINT16; guint16 page_last = G_MAXUINT16;
guint chunk_valid = G_MAXUINT; guint chunk_valid = G_MAXUINT;
g_autoptr(DfuElement) element = NULL; g_autoptr(FuChunk) chk2 = NULL;
g_autoptr(GBytes) contents = NULL; g_autoptr(GBytes) contents = NULL;
g_autoptr(GBytes) contents_truncated = NULL; g_autoptr(GBytes) contents_truncated = NULL;
g_autoptr(GPtrArray) blobs = NULL; g_autoptr(GPtrArray) blobs = NULL;
@ -738,10 +738,9 @@ dfu_target_avr_upload_element (DfuTarget *target,
contents_truncated = g_bytes_ref (contents); contents_truncated = g_bytes_ref (contents);
} }
element = dfu_element_new (); chk2 = fu_chunk_bytes_new (contents_truncated);
dfu_element_set_address (element, address | 0x80000000); /* flash */ fu_chunk_set_address (chk2, address | 0x80000000); /* flash */
dfu_element_set_contents (element, contents_truncated); return g_steal_pointer (&chk2);
return g_steal_pointer (&element);
} }
static void static void

View File

@ -15,6 +15,8 @@
#include "dfu-target-stm.h" #include "dfu-target-stm.h"
#include "dfu-target-private.h" #include "dfu-target-private.h"
#include "fu-chunk.h"
#include "fwupd-error.h" #include "fwupd-error.h"
G_DEFINE_TYPE (DfuTargetStm, dfu_target_stm, DFU_TYPE_TARGET) G_DEFINE_TYPE (DfuTargetStm, dfu_target_stm, DFU_TYPE_TARGET)
@ -83,7 +85,7 @@ dfu_target_stm_set_address (DfuTarget *target, guint32 address, GError **error)
return dfu_target_check_status (target, error); return dfu_target_check_status (target, error);
} }
static DfuElement * static FuChunk *
dfu_target_stm_upload_element (DfuTarget *target, dfu_target_stm_upload_element (DfuTarget *target,
guint32 address, guint32 address,
gsize expected_size, gsize expected_size,
@ -92,7 +94,7 @@ dfu_target_stm_upload_element (DfuTarget *target,
{ {
DfuDevice *device = dfu_target_get_device (target); DfuDevice *device = dfu_target_get_device (target);
DfuSector *sector; DfuSector *sector;
DfuElement *element = NULL; FuChunk *chk = NULL;
GBytes *chunk_tmp; GBytes *chunk_tmp;
guint32 offset = address; guint32 offset = address;
guint percentage_size = expected_size > 0 ? expected_size : maximum_size; guint percentage_size = expected_size > 0 ? expected_size : maximum_size;
@ -204,10 +206,9 @@ dfu_target_stm_upload_element (DfuTarget *target,
} else { } else {
contents_truncated = g_bytes_ref (contents); contents_truncated = g_bytes_ref (contents);
} }
element = dfu_element_new (); chk = fu_chunk_bytes_new (contents_truncated);
dfu_element_set_contents (element, contents_truncated); fu_chunk_set_address (chk, address);
dfu_element_set_address (element, address); return chk;
return element;
} }
/** /**
@ -242,21 +243,21 @@ dfu_target_stm_erase_address (DfuTarget *target, guint32 address, GError **error
static gboolean static gboolean
dfu_target_stm_download_element (DfuTarget *target, dfu_target_stm_download_element (DfuTarget *target,
DfuElement *element, FuChunk *chk,
DfuTargetTransferFlags flags, DfuTargetTransferFlags flags,
GError **error) GError **error)
{ {
DfuDevice *device = dfu_target_get_device (target); DfuDevice *device = dfu_target_get_device (target);
DfuSector *sector; DfuSector *sector;
GBytes *bytes;
guint nr_chunks; guint nr_chunks;
guint zone_last = G_MAXUINT; guint zone_last = G_MAXUINT;
guint16 transfer_size = dfu_device_get_transfer_size (device); guint16 transfer_size = dfu_device_get_transfer_size (device);
g_autoptr(GBytes) bytes = NULL;
g_autoptr(GPtrArray) sectors_array = NULL; g_autoptr(GPtrArray) sectors_array = NULL;
g_autoptr(GHashTable) sectors_hash = NULL; g_autoptr(GHashTable) sectors_hash = NULL;
/* round up as we have to transfer incomplete blocks */ /* round up as we have to transfer incomplete blocks */
bytes = dfu_element_get_contents (element); bytes = fu_chunk_get_bytes (chk);
nr_chunks = (guint) ceil ((gdouble) g_bytes_get_size (bytes) / nr_chunks = (guint) ceil ((gdouble) g_bytes_get_size (bytes) /
(gdouble) transfer_size); (gdouble) transfer_size);
if (nr_chunks == 0) { if (nr_chunks == 0) {
@ -275,7 +276,7 @@ dfu_target_stm_download_element (DfuTarget *target,
/* for DfuSe devices we need to handle the erase and setting /* for DfuSe devices we need to handle the erase and setting
* the sectory address manually */ * the sectory address manually */
offset_dev = dfu_element_get_address (element) + (i * transfer_size); offset_dev = fu_chunk_get_address (chk) + (i * transfer_size);
sector = dfu_target_get_sector_for_addr (target, offset_dev); sector = dfu_target_get_sector_for_addr (target, offset_dev);
if (sector == NULL) { if (sector == NULL) {
g_set_error (error, g_set_error (error,
@ -332,7 +333,7 @@ dfu_target_stm_download_element (DfuTarget *target,
/* caclulate the offset into the element data */ /* caclulate the offset into the element data */
offset = i * transfer_size; offset = i * transfer_size;
offset_dev = dfu_element_get_address (element) + offset; offset_dev = fu_chunk_get_address (chk) + offset;
/* for DfuSe devices we need to set the address manually */ /* for DfuSe devices we need to set the address manually */
sector = dfu_target_get_sector_for_addr (target, offset_dev); sector = dfu_target_get_sector_for_addr (target, offset_dev);

View File

@ -964,7 +964,7 @@ dfu_target_attach (DfuTarget *target, GError **error)
return dfu_device_reset (priv->device, error); return dfu_device_reset (priv->device, error);
} }
static DfuElement * static FuChunk *
dfu_target_upload_element_dfu (DfuTarget *target, dfu_target_upload_element_dfu (DfuTarget *target,
guint32 address, guint32 address,
gsize expected_size, gsize expected_size,
@ -972,7 +972,6 @@ dfu_target_upload_element_dfu (DfuTarget *target,
GError **error) GError **error)
{ {
DfuTargetPrivate *priv = GET_PRIVATE (target); DfuTargetPrivate *priv = GET_PRIVATE (target);
DfuElement *element = NULL;
GBytes *chunk_tmp; GBytes *chunk_tmp;
guint32 offset = 0; guint32 offset = 0;
guint percentage_size = expected_size > 0 ? expected_size : maximum_size; guint percentage_size = expected_size > 0 ? expected_size : maximum_size;
@ -1035,12 +1034,10 @@ dfu_target_upload_element_dfu (DfuTarget *target,
/* create new image */ /* create new image */
contents = dfu_utils_bytes_join_array (chunks); contents = dfu_utils_bytes_join_array (chunks);
element = dfu_element_new (); return fu_chunk_bytes_new (contents);
dfu_element_set_contents (element, contents);
return element;
} }
static DfuElement * static FuChunk *
dfu_target_upload_element (DfuTarget *target, dfu_target_upload_element (DfuTarget *target,
guint32 address, guint32 address,
gsize expected_size, gsize expected_size,
@ -1133,7 +1130,7 @@ dfu_target_upload (DfuTarget *target,
/* get all the sectors for the device */ /* get all the sectors for the device */
for (guint i = 0; i < priv->sectors->len; i++) { for (guint i = 0; i < priv->sectors->len; i++) {
g_autoptr(DfuElement) element = NULL; g_autoptr(FuChunk) chk = NULL;
/* only upload to the start of any zone:sector */ /* only upload to the start of any zone:sector */
sector = g_ptr_array_index (priv->sectors, i); sector = g_ptr_array_index (priv->sectors, i);
@ -1145,20 +1142,20 @@ dfu_target_upload (DfuTarget *target,
zone_size = dfu_target_get_size_of_zone (target, zone_cur); zone_size = dfu_target_get_size_of_zone (target, zone_cur);
zone_last = zone_cur; zone_last = zone_cur;
/* get the first element from the hardware */ /* get the first chk from the hardware */
g_debug ("starting upload from 0x%08x (0x%04x)", g_debug ("starting upload from 0x%08x (0x%04x)",
dfu_sector_get_address (sector), dfu_sector_get_address (sector),
zone_size); zone_size);
element = dfu_target_upload_element (target, chk = dfu_target_upload_element (target,
dfu_sector_get_address (sector), dfu_sector_get_address (sector),
0, /* expected */ 0, /* expected */
zone_size, /* maximum */ zone_size, /* maximum */
error); error);
if (element == NULL) if (chk == NULL)
return NULL; return NULL;
/* this element was uploaded okay */ /* this chk was uploaded okay */
dfu_image_add_element (image, element); dfu_image_add_chunk (image, chk);
} }
/* success */ /* success */
@ -1195,17 +1192,17 @@ _g_bytes_compare_verbose (GBytes *bytes1, GBytes *bytes2)
static gboolean static gboolean
dfu_target_download_element_dfu (DfuTarget *target, dfu_target_download_element_dfu (DfuTarget *target,
DfuElement *element, FuChunk *chk,
DfuTargetTransferFlags flags, DfuTargetTransferFlags flags,
GError **error) GError **error)
{ {
DfuTargetPrivate *priv = GET_PRIVATE (target); DfuTargetPrivate *priv = GET_PRIVATE (target);
GBytes *bytes; g_autoptr(GBytes) bytes = NULL;
guint32 nr_chunks; guint32 nr_chunks;
guint16 transfer_size = dfu_device_get_transfer_size (priv->device); guint16 transfer_size = dfu_device_get_transfer_size (priv->device);
/* round up as we have to transfer incomplete blocks */ /* round up as we have to transfer incomplete blocks */
bytes = dfu_element_get_contents (element); bytes = fu_chunk_get_bytes (chk);
nr_chunks = (guint) ceil ((gdouble) g_bytes_get_size (bytes) / nr_chunks = (guint) ceil ((gdouble) g_bytes_get_size (bytes) /
(gdouble) transfer_size); (gdouble) transfer_size);
if (nr_chunks == 0) { if (nr_chunks == 0) {
@ -1221,7 +1218,7 @@ dfu_target_download_element_dfu (DfuTarget *target,
guint32 offset; guint32 offset;
g_autoptr(GBytes) bytes_tmp = NULL; g_autoptr(GBytes) bytes_tmp = NULL;
/* caclulate the offset into the element data */ /* caclulate the offset into the chunk data */
offset = i * transfer_size; offset = i * transfer_size;
/* we have to write one final zero-sized chunk for EOF */ /* we have to write one final zero-sized chunk for EOF */
@ -1257,7 +1254,7 @@ dfu_target_download_element_dfu (DfuTarget *target,
static gboolean static gboolean
dfu_target_download_element (DfuTarget *target, dfu_target_download_element (DfuTarget *target,
DfuElement *element, FuChunk *chk,
DfuTargetTransferFlags flags, DfuTargetTransferFlags flags,
GError **error) GError **error)
{ {
@ -1266,11 +1263,11 @@ dfu_target_download_element (DfuTarget *target,
/* implemented as part of a superclass */ /* implemented as part of a superclass */
if (klass->download_element != NULL) { if (klass->download_element != NULL) {
if (!klass->download_element (target, element, flags, error)) if (!klass->download_element (target, chk, flags, error))
return FALSE; return FALSE;
} else { } else {
if (!dfu_target_download_element_dfu (target, if (!dfu_target_download_element_dfu (target,
element, chk,
flags, flags,
error)) error))
return FALSE; return FALSE;
@ -1279,19 +1276,19 @@ dfu_target_download_element (DfuTarget *target,
/* verify */ /* verify */
if (flags & DFU_TARGET_TRANSFER_FLAG_VERIFY && if (flags & DFU_TARGET_TRANSFER_FLAG_VERIFY &&
dfu_device_has_attribute (priv->device, DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD)) { dfu_device_has_attribute (priv->device, DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD)) {
GBytes *bytes; g_autoptr(GBytes) bytes = NULL;
GBytes *bytes_tmp; g_autoptr(GBytes) bytes_tmp = NULL;
g_autoptr(DfuElement) element_tmp = NULL; g_autoptr(FuChunk) chunk_tmp = NULL;
dfu_target_set_action (target, FWUPD_STATUS_DEVICE_VERIFY); dfu_target_set_action (target, FWUPD_STATUS_DEVICE_VERIFY);
bytes = dfu_element_get_contents (element); bytes = fu_chunk_get_bytes (chk);
element_tmp = dfu_target_upload_element (target, chunk_tmp = dfu_target_upload_element (target,
dfu_element_get_address (element), fu_chunk_get_address (chk),
g_bytes_get_size (bytes), g_bytes_get_size (bytes),
g_bytes_get_size (bytes), g_bytes_get_size (bytes),
error); error);
if (element_tmp == NULL) if (chunk_tmp == NULL)
return FALSE; return FALSE;
bytes_tmp = dfu_element_get_contents (element_tmp); bytes_tmp = fu_chunk_get_bytes (chunk_tmp);
if (g_bytes_compare (bytes_tmp, bytes) != 0) { if (g_bytes_compare (bytes_tmp, bytes) != 0) {
g_autofree gchar *bytes_cmp_str = NULL; g_autofree gchar *bytes_cmp_str = NULL;
bytes_cmp_str = _g_bytes_compare_verbose (bytes_tmp, bytes); bytes_cmp_str = _g_bytes_compare_verbose (bytes_tmp, bytes);
@ -1325,7 +1322,7 @@ dfu_target_download (DfuTarget *target, DfuImage *image,
DfuTargetTransferFlags flags, GError **error) DfuTargetTransferFlags flags, GError **error)
{ {
DfuTargetPrivate *priv = GET_PRIVATE (target); DfuTargetPrivate *priv = GET_PRIVATE (target);
GPtrArray *elements; GPtrArray *chunks;
gboolean ret; gboolean ret;
g_return_val_if_fail (DFU_IS_TARGET (target), FALSE); g_return_val_if_fail (DFU_IS_TARGET (target), FALSE);
@ -1349,36 +1346,36 @@ dfu_target_download (DfuTarget *target, DfuImage *image,
if (!dfu_target_use_alt_setting (target, error)) if (!dfu_target_use_alt_setting (target, error))
return FALSE; return FALSE;
/* download all elements in the image to the device */ /* download all chunks in the image to the device */
elements = dfu_image_get_elements (image); chunks = dfu_image_get_chunks (image);
if (elements->len == 0) { if (chunks->len == 0) {
g_set_error_literal (error, g_set_error_literal (error,
FWUPD_ERROR, FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE, FWUPD_ERROR_INVALID_FILE,
"no image elements"); "no image chunks");
return FALSE; return FALSE;
} }
for (guint i = 0; i < elements->len; i++) { for (guint i = 0; i < chunks->len; i++) {
DfuElement *element = dfu_image_get_element (image, (guint8) i); FuChunk *chk = dfu_image_get_chunk_by_idx (image, (guint8) i);
g_debug ("downloading element at 0x%04x", g_debug ("downloading chk at 0x%04x",
dfu_element_get_address (element)); fu_chunk_get_address (chk));
/* auto-detect missing firmware address -- this assumes /* auto-detect missing firmware address -- this assumes
* that the first target is the main program memory and that * that the first target is the main program memory and that
* there is only one element in the firmware file */ * there is only one element in the firmware file */
if (flags & DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC && if (flags & DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC &&
dfu_element_get_address (element) == 0x0 && fu_chunk_get_address (chk) == 0x0 &&
elements->len == 1 && chunks->len == 1 &&
priv->sectors->len > 0) { priv->sectors->len > 0) {
DfuSector *sector = g_ptr_array_index (priv->sectors, 0); DfuSector *sector = g_ptr_array_index (priv->sectors, 0);
g_debug ("fixing up firmware address from 0x0 to 0x%x", g_debug ("fixing up firmware address from 0x0 to 0x%x",
dfu_sector_get_address (sector)); dfu_sector_get_address (sector));
dfu_element_set_address (element, dfu_sector_get_address (sector)); fu_chunk_set_address (chk, dfu_sector_get_address (sector));
} }
/* download to device */ /* download to device */
ret = dfu_target_download_element (target, ret = dfu_target_download_element (target,
element, chk,
flags, flags,
error); error);
if (!ret) if (!ret)

View File

@ -14,6 +14,8 @@
#include "dfu-image.h" #include "dfu-image.h"
#include "dfu-sector.h" #include "dfu-sector.h"
#include "fu-chunk.h"
#include "fwupd-enums.h" #include "fwupd-enums.h"
#define DFU_TYPE_TARGET (dfu_target_get_type ()) #define DFU_TYPE_TARGET (dfu_target_get_type ())
@ -54,13 +56,13 @@ struct _DfuTargetClass
GError **error); GError **error);
gboolean (*mass_erase) (DfuTarget *target, gboolean (*mass_erase) (DfuTarget *target,
GError **error); GError **error);
DfuElement *(*upload_element) (DfuTarget *target, FuChunk *(*upload_element) (DfuTarget *target,
guint32 address, guint32 address,
gsize expected_size, gsize expected_size,
gsize maximum_size, gsize maximum_size,
GError **error); GError **error);
gboolean (*download_element) (DfuTarget *target, gboolean (*download_element) (DfuTarget *target,
DfuElement *element, FuChunk *chk,
DfuTargetTransferFlags flags, DfuTargetTransferFlags flags,
GError **error); GError **error);
}; };

View File

@ -17,6 +17,7 @@
#include "dfu-device.h" #include "dfu-device.h"
#include "dfu-sector.h" #include "dfu-sector.h"
#include "fu-chunk.h"
#include "fu-device-locker.h" #include "fu-device-locker.h"
#include "fwupd-error.h" #include "fwupd-error.h"
@ -413,10 +414,10 @@ dfu_tool_replace_data (DfuToolPrivate *priv, gchar **values, GError **error)
images = fu_firmware_get_images (FU_FIRMWARE (firmware)); images = fu_firmware_get_images (FU_FIRMWARE (firmware));
for (guint i = 0; i < images->len; i++) { for (guint i = 0; i < images->len; i++) {
DfuImage *image = g_ptr_array_index (images, i); DfuImage *image = g_ptr_array_index (images, i);
GPtrArray *elements = dfu_image_get_elements (image); GPtrArray *chunks = dfu_image_get_chunks (image);
for (guint j = 0; j < elements->len; j++) { for (guint j = 0; j < chunks->len; j++) {
DfuElement *element = g_ptr_array_index (elements, j); FuChunk *chk = g_ptr_array_index (chunks, j);
GBytes *contents = dfu_element_get_contents (element); g_autoptr(GBytes) contents = fu_chunk_get_bytes (chk);
if (contents == NULL) if (contents == NULL)
continue; continue;
cnt += dfu_tool_bytes_replace (contents, data_search, data_replace); cnt += dfu_tool_bytes_replace (contents, data_search, data_replace);

View File

@ -10,7 +10,6 @@ dfu = static_library(
sources : [ sources : [
'dfu-common.c', 'dfu-common.c',
'dfu-device.c', 'dfu-device.c',
'dfu-element.c',
'dfu-firmware.c', 'dfu-firmware.c',
'dfu-format-dfu.c', 'dfu-format-dfu.c',
'dfu-format-dfuse.c', 'dfu-format-dfuse.c',