mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-15 13:59:15 +00:00
elantp: Use the recently added FuCfuOffer and FuCfuPayload
This increases the amount of parsing we do ahead-of-time.
This commit is contained in:
parent
10549674b1
commit
3a86c7e386
@ -11,6 +11,8 @@
|
||||
#include <libfwupdplugin/fu-archive.h>
|
||||
#include <libfwupdplugin/fu-backend.h>
|
||||
#include <libfwupdplugin/fu-bluez-device.h>
|
||||
#include <libfwupdplugin/fu-cfu-offer.h>
|
||||
#include <libfwupdplugin/fu-cfu-payload.h>
|
||||
#include <libfwupdplugin/fu-chunk.h>
|
||||
#include <libfwupdplugin/fu-common-cab.h>
|
||||
#include <libfwupdplugin/fu-common-guid.h>
|
||||
|
@ -108,7 +108,6 @@ fu_elanfp_iap_send_command(FuElanfpDevice *self,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!g_usb_device_control_transfer(usb_device,
|
||||
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||
@ -265,48 +264,16 @@ fu_elanfp_device_setup(FuDevice *device, GError **error)
|
||||
|
||||
static gboolean
|
||||
fu_elanfp_device_write_payload(FuElanfpDevice *self,
|
||||
GBytes *fw,
|
||||
FuFirmware *payload,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
guint32 offset = 0;
|
||||
gsize bufsz = 0;
|
||||
const guint8 *buf = g_bytes_get_data(fw, &bufsz);
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* process into chunks */
|
||||
chunks = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
|
||||
while (offset < bufsz) {
|
||||
guint32 chunk_addr = 0;
|
||||
guint8 chunk_size = 0;
|
||||
g_autoptr(FuChunk) chk = NULL;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
|
||||
/* read chunk header */
|
||||
if (!fu_common_read_uint32_safe(buf,
|
||||
bufsz,
|
||||
offset,
|
||||
&chunk_addr,
|
||||
G_LITTLE_ENDIAN,
|
||||
error))
|
||||
return FALSE;
|
||||
if (!fu_common_read_uint8_safe(buf, bufsz, offset + 0x4, &chunk_size, error))
|
||||
return FALSE;
|
||||
offset += 0x5;
|
||||
blob = fu_common_bytes_new_offset(fw, offset, chunk_size, error);
|
||||
if (blob == NULL) {
|
||||
g_prefix_error(error, "memory copy for offer fail: ");
|
||||
return FALSE;
|
||||
}
|
||||
chk = fu_chunk_bytes_new(blob);
|
||||
fu_chunk_set_address(chk, chunk_addr);
|
||||
g_ptr_array_add(chunks, g_steal_pointer(&chk));
|
||||
|
||||
/* next! */
|
||||
offset += chunk_size;
|
||||
}
|
||||
|
||||
/* write each chunk */
|
||||
chunks = fu_firmware_get_chunks(payload, error);
|
||||
if (chunks == NULL)
|
||||
return FALSE;
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_set_steps(progress, chunks->len);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
@ -395,8 +362,11 @@ fu_elanfp_device_write_firmware(FuDevice *device,
|
||||
const gchar *tag;
|
||||
guint8 offer_idx;
|
||||
guint8 payload_idx;
|
||||
} items[] = {{"A", 0x72, 0x74}, {"B", 0x73, 0x75}, {NULL, 0x0, 0x0}};
|
||||
g_autoptr(GBytes) payload = NULL;
|
||||
} items[] = {
|
||||
{"A", FU_ELANTP_FIRMWARE_IDX_CFU_OFFER_A, FU_ELANTP_FIRMWARE_IDX_CFU_PAYLOAD_A},
|
||||
{"B", FU_ELANTP_FIRMWARE_IDX_CFU_OFFER_B, FU_ELANTP_FIRMWARE_IDX_CFU_PAYLOAD_B},
|
||||
{NULL, FU_ELANTP_FIRMWARE_IDX_END, FU_ELANTP_FIRMWARE_IDX_END}};
|
||||
g_autoptr(FuFirmware) payload = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
@ -442,7 +412,7 @@ fu_elanfp_device_write_firmware(FuDevice *device,
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* send payload */
|
||||
payload = fu_firmware_get_image_by_idx_bytes(firmware, items[i].payload_idx, error);
|
||||
payload = fu_firmware_get_image_by_idx(firmware, items[i].payload_idx, error);
|
||||
if (payload == NULL)
|
||||
return FALSE;
|
||||
if (!fu_elanfp_device_write_payload(self, payload, fu_progress_get_child(progress), error))
|
||||
|
@ -17,8 +17,6 @@ struct _FuElanfpFirmware {
|
||||
|
||||
G_DEFINE_TYPE(FuElanfpFirmware, fu_elanfp_firmware, FU_TYPE_FIRMWARE)
|
||||
|
||||
#define FU_ELANTP_FIRMWARE_IDX_END 0xFF
|
||||
|
||||
static void
|
||||
fu_elanfp_firmware_export(FuFirmware *firmware, FuFirmwareExportFlags flags, XbBuilderNode *bn)
|
||||
{
|
||||
@ -90,6 +88,23 @@ fu_elanfp_firmware_parse(FuFirmware *firmware,
|
||||
G_LITTLE_ENDIAN,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* done */
|
||||
if (fwtype == FU_ELANTP_FIRMWARE_IDX_END)
|
||||
break;
|
||||
switch (fwtype) {
|
||||
case FU_ELANTP_FIRMWARE_IDX_CFU_OFFER_A:
|
||||
case FU_ELANTP_FIRMWARE_IDX_CFU_OFFER_B:
|
||||
img = fu_cfu_offer_new();
|
||||
break;
|
||||
case FU_ELANTP_FIRMWARE_IDX_CFU_PAYLOAD_A:
|
||||
case FU_ELANTP_FIRMWARE_IDX_CFU_PAYLOAD_B:
|
||||
img = fu_cfu_payload_new();
|
||||
break;
|
||||
default:
|
||||
img = fu_firmware_new();
|
||||
break;
|
||||
}
|
||||
fu_firmware_set_idx(img, fwtype);
|
||||
if (!fu_common_read_uint32_safe(buf,
|
||||
bufsz,
|
||||
@ -109,13 +124,10 @@ fu_elanfp_firmware_parse(FuFirmware *firmware,
|
||||
blob = fu_common_bytes_new_offset(fw, start_addr, length, error);
|
||||
if (blob == NULL)
|
||||
return FALSE;
|
||||
fu_firmware_set_bytes(img, blob);
|
||||
if (!fu_firmware_parse(img, blob, flags, error))
|
||||
return FALSE;
|
||||
fu_firmware_add_image(firmware, img);
|
||||
|
||||
/* done */
|
||||
if (fwtype == FU_ELANTP_FIRMWARE_IDX_END)
|
||||
break;
|
||||
|
||||
offset += 0x10;
|
||||
}
|
||||
|
||||
@ -141,11 +153,14 @@ fu_elanfp_firmware_write(FuFirmware *firmware, GError **error)
|
||||
offset += 0x10 + ((imgs->len + 1) * 0x10);
|
||||
for (guint i = 0; i < imgs->len; i++) {
|
||||
FuFirmware *img = g_ptr_array_index(imgs, i);
|
||||
g_autoptr(GBytes) blob = fu_firmware_write(img, error);
|
||||
if (blob == NULL)
|
||||
return NULL;
|
||||
fu_byte_array_append_uint32(buf, fu_firmware_get_idx(img), G_LITTLE_ENDIAN);
|
||||
fu_byte_array_append_uint32(buf, 0x0, G_LITTLE_ENDIAN); /* reserved */
|
||||
fu_byte_array_append_uint32(buf, offset, G_LITTLE_ENDIAN);
|
||||
fu_byte_array_append_uint32(buf, fu_firmware_get_size(img), G_LITTLE_ENDIAN);
|
||||
offset += fu_firmware_get_size(img);
|
||||
fu_byte_array_append_uint32(buf, g_bytes_get_size(blob), G_LITTLE_ENDIAN);
|
||||
offset += g_bytes_get_size(blob);
|
||||
}
|
||||
|
||||
/* end of index */
|
||||
@ -157,7 +172,9 @@ fu_elanfp_firmware_write(FuFirmware *firmware, GError **error)
|
||||
/* data */
|
||||
for (guint i = 0; i < imgs->len; i++) {
|
||||
FuFirmware *img = g_ptr_array_index(imgs, i);
|
||||
g_autoptr(GBytes) blob = fu_firmware_get_bytes(img, error);
|
||||
g_autoptr(GBytes) blob = fu_firmware_write(img, error);
|
||||
if (blob == NULL)
|
||||
return NULL;
|
||||
fu_byte_array_append_bytes(buf, blob);
|
||||
}
|
||||
|
||||
|
@ -11,5 +11,12 @@
|
||||
#define FU_TYPE_ELANFP_FIRMWARE (fu_elanfp_firmware_get_type())
|
||||
G_DECLARE_FINAL_TYPE(FuElanfpFirmware, fu_elanfp_firmware, FU, ELANFP_FIRMWARE, FuFirmware)
|
||||
|
||||
#define FU_ELANTP_FIRMWARE_IDX_FIRMWAREVERSION 0x00
|
||||
#define FU_ELANTP_FIRMWARE_IDX_CFU_OFFER_A 0x72
|
||||
#define FU_ELANTP_FIRMWARE_IDX_CFU_OFFER_B 0x73
|
||||
#define FU_ELANTP_FIRMWARE_IDX_CFU_PAYLOAD_A 0x74
|
||||
#define FU_ELANTP_FIRMWARE_IDX_CFU_PAYLOAD_B 0x75
|
||||
#define FU_ELANTP_FIRMWARE_IDX_END 0xFF
|
||||
|
||||
FuFirmware *
|
||||
fu_elanfp_firmware_new(void);
|
||||
|
@ -1,19 +1,33 @@
|
||||
<firmware gtype="FuElanfpFirmware">
|
||||
<format_version>0x123</format_version>
|
||||
<firmware>
|
||||
<firmware gtype="FuCfuOffer">
|
||||
<idx>0x72</idx>
|
||||
<data>aGVsbG8gd29ybGQ=</data>
|
||||
<version_raw>0x1234</version_raw>
|
||||
<product_id>0x5678</product_id>
|
||||
<bank>0x1</bank>
|
||||
</firmware>
|
||||
<firmware>
|
||||
<firmware gtype="FuCfuOffer">
|
||||
<idx>0x73</idx>
|
||||
<data>aGVsbG8gd29ybGQ=</data>
|
||||
<version_raw>0x1234</version_raw>
|
||||
<product_id>0x5678</product_id>
|
||||
<bank>0x2</bank>
|
||||
</firmware>
|
||||
<firmware>
|
||||
<firmware gtype="FuCfuPayload">
|
||||
<idx>0x74</idx>
|
||||
<chunks>
|
||||
<chunk>
|
||||
<data>aGVsbG8gd29ybGQ=</data>
|
||||
<addr>0x8001234</addr>
|
||||
</chunk>
|
||||
</chunks>
|
||||
</firmware>
|
||||
<firmware>
|
||||
<firmware gtype="FuCfuPayload">
|
||||
<idx>0x75</idx>
|
||||
<chunks>
|
||||
<chunk>
|
||||
<data>aGVsbG8gd29ybGQ=</data>
|
||||
<addr>0x8001234</addr>
|
||||
</chunk>
|
||||
</chunks>
|
||||
</firmware>
|
||||
</firmware>
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user