mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-27 09:46:25 +00:00
dfu: Use FuChunk rather than defining DfuElement
This commit is contained in:
parent
6de10e118c
commit
ed4b8e28db
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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);
|
|
||||||
}
|
|
@ -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);
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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++) {
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
|
@ -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',
|
||||||
|
Loading…
Reference in New Issue
Block a user