synaptics-prometheus: Allow creating test firmware from builder.xml

This means we don't need a standalone executable to build blobs.
This commit is contained in:
Richard Hughes 2020-12-09 12:13:28 +00:00
parent 84617b6699
commit 4dcd167215
5 changed files with 61 additions and 104 deletions

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include "config.h"
#include "fu-synaprom-firmware.h"
static gboolean
fu_dump_parse (const gchar *filename, GError **error)
{
gchar *data = NULL;
gsize len = 0;
g_autoptr(GBytes) blob = NULL;
g_autoptr(FuFirmware) firmware = fu_synaprom_firmware_new ();
if (!g_file_get_contents (filename, &data, &len, error))
return FALSE;
blob = g_bytes_new_take (data, len);
return fu_firmware_parse (firmware, blob, 0, error);
}
static gboolean
fu_dump_generate (const gchar *filename, GError **error)
{
const gchar *data;
gsize len = 0;
g_autoptr(GBytes) blob = NULL;
g_autoptr(FuFirmware) firmware = fu_synaprom_firmware_new ();
blob = fu_firmware_write (firmware, error);
if (blob == NULL)
return FALSE;
data = g_bytes_get_data (blob, &len);
return g_file_set_contents (filename, data, len, error);
}
int
main (int argc, char **argv)
{
g_autoptr(GError) error = NULL;
if (argc == 2) {
if (!fu_dump_parse (argv[1], &error)) {
g_printerr ("parse failed: %s\n", error->message);
return 1;
}
} else if (argc == 3 && g_strcmp0 (argv[2], "gen") == 0) {
if (!fu_dump_generate (argv[1], &error)) {
g_printerr ("generate failed: %s\n", error->message);
return 1;
}
} else {
g_printerr ("firmware filename required\n");
return 2;
}
g_print ("OK!\n");
return 0;
}

View File

@ -48,6 +48,15 @@ typedef struct __attribute__((packed)) {
guint16 unused[3];
} FuSynapromIotaConfigVersion;
/* le */
typedef struct __attribute__((packed)) {
guint32 product;
guint32 id1; /* verification ID */
guint32 id2; /* verification ID */
guint16 version; /* config version */
guint8 unused[2];
} FuSynapromFirmwareCfgHeader;
#define FU_SYNAPROM_CMD_IOTA_FIND_FLAGS_ALLIOTAS 0x0001 /* itype ignored*/
#define FU_SYNAPROM_CMD_IOTA_FIND_FLAGS_READMAX 0x0002 /* nbytes ignored */
#define FU_SYNAPROM_MAX_IOTA_READ_SIZE (64 * 1024) /* max size of iota data returned */

View File

@ -14,10 +14,16 @@
struct _FuSynapromFirmware {
FuFirmware parent_instance;
guint32 product_id;
};
G_DEFINE_TYPE (FuSynapromFirmware, fu_synaprom_firmware, FU_TYPE_FIRMWARE)
#define FU_SYNAPROM_FIRMWARE_TAG_MFW_HEADER 0x0001
#define FU_SYNAPROM_FIRMWARE_TAG_MFW_PAYLOAD 0x0002
#define FU_SYNAPROM_FIRMWARE_TAG_CFG_HEADER 0x0003
#define FU_SYNAPROM_FIRMWARE_TAG_CFG_PAYLOAD 0x0004
typedef struct __attribute__((packed)) {
guint16 tag;
guint32 bufsz;
@ -41,6 +47,13 @@ fu_synaprom_firmware_tag_to_string (guint16 tag)
return NULL;
}
static void
fu_synaprom_firmware_to_string (FuFirmware *firmware, guint idt, GString *str)
{
FuSynapromFirmware *self = FU_SYNAPROM_FIRMWARE (firmware);
fu_common_string_append_kx (str, idt, "ProductId", self->product_id);
}
static gboolean
fu_synaprom_firmware_parse (FuFirmware *firmware,
GBytes *fw,
@ -116,12 +129,13 @@ fu_synaprom_firmware_parse (FuFirmware *firmware,
}
static GBytes *
fu_synaprom_firmware_write (FuFirmware *self, GError **error)
fu_synaprom_firmware_write (FuFirmware *firmware, GError **error)
{
FuSynapromFirmware *self = FU_SYNAPROM_FIRMWARE (firmware);
GByteArray *blob = g_byte_array_new ();
const guint8 data[] = { 'R', 'H' };
g_autoptr(GBytes) payload = NULL;
FuSynapromFirmwareMfwHeader hdr = {
.product = GUINT32_TO_LE(0x41),
.product = GUINT32_TO_LE(self->product_id),
.id = GUINT32_TO_LE(0xff),
.buildtime = GUINT32_TO_LE(0xff),
.buildnum = GUINT32_TO_LE(0xff),
@ -130,14 +144,27 @@ fu_synaprom_firmware_write (FuFirmware *self, GError **error)
};
/* add header */
fu_byte_array_append_uint16 (blob, FU_SYNAPROM_FIRMWARE_TAG_MFW_HEADER, G_LITTLE_ENDIAN);
fu_byte_array_append_uint32 (blob, sizeof(hdr), G_LITTLE_ENDIAN);
fu_byte_array_append_uint16 (blob,
FU_SYNAPROM_FIRMWARE_TAG_MFW_HEADER,
G_LITTLE_ENDIAN);
fu_byte_array_append_uint32 (blob,
sizeof(hdr),
G_LITTLE_ENDIAN);
g_byte_array_append (blob, (const guint8 *) &hdr, sizeof(hdr));
/* add payload */
fu_byte_array_append_uint16 (blob, FU_SYNAPROM_FIRMWARE_TAG_MFW_PAYLOAD, G_LITTLE_ENDIAN);
fu_byte_array_append_uint32 (blob, sizeof(data), G_LITTLE_ENDIAN);
g_byte_array_append (blob, data, sizeof(data));
payload = fu_firmware_get_image_default_bytes (firmware, error);
if (payload == NULL)
return FALSE;
fu_byte_array_append_uint16 (blob,
FU_SYNAPROM_FIRMWARE_TAG_MFW_PAYLOAD,
G_LITTLE_ENDIAN);
fu_byte_array_append_uint32 (blob,
g_bytes_get_size (payload),
G_LITTLE_ENDIAN);
g_byte_array_append (blob,
g_bytes_get_data (payload, NULL),
g_bytes_get_size (payload));
/* add signature */
for (guint i = 0; i < FU_SYNAPROM_FIRMWARE_SIGSIZE; i++)
@ -145,6 +172,21 @@ fu_synaprom_firmware_write (FuFirmware *self, GError **error)
return g_byte_array_free_to_bytes (blob);
}
static gboolean
fu_synaprom_firmware_build (FuFirmware *firmware, XbNode *n, GError **error)
{
FuSynapromFirmware *self = FU_SYNAPROM_FIRMWARE (firmware);
guint64 tmp;
/* simple properties */
tmp = xb_node_query_text_as_uint (n, "product_id", NULL);
if (tmp != G_MAXUINT64 && tmp <= G_MAXUINT32)
self->product_id = tmp;
/* success */
return TRUE;
}
static void
fu_synaprom_firmware_init (FuSynapromFirmware *self)
{
@ -156,6 +198,8 @@ fu_synaprom_firmware_class_init (FuSynapromFirmwareClass *klass)
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
klass_firmware->parse = fu_synaprom_firmware_parse;
klass_firmware->write = fu_synaprom_firmware_write;
klass_firmware->to_string = fu_synaprom_firmware_to_string;
klass_firmware->build = fu_synaprom_firmware_build;
}
FuFirmware *

View File

@ -8,16 +8,10 @@
#pragma once
#include "fu-firmware.h"
#include "fu-synaprom-firmware.h"
#define FU_TYPE_SYNAPROM_FIRMWARE (fu_synaprom_firmware_get_type ())
G_DECLARE_FINAL_TYPE (FuSynapromFirmware, fu_synaprom_firmware, FU, SYNAPROM_FIRMWARE, FuFirmware)
#define FU_SYNAPROM_FIRMWARE_TAG_MFW_HEADER 0x0001
#define FU_SYNAPROM_FIRMWARE_TAG_MFW_PAYLOAD 0x0002
#define FU_SYNAPROM_FIRMWARE_TAG_CFG_HEADER 0x0003
#define FU_SYNAPROM_FIRMWARE_TAG_CFG_PAYLOAD 0x0004
/* le */
typedef struct __attribute__((packed)) {
guint32 product;
@ -29,13 +23,4 @@ typedef struct __attribute__((packed)) {
guint8 unused[6];
} FuSynapromFirmwareMfwHeader;
/* le */
typedef struct __attribute__((packed)) {
guint32 product;
guint32 id1; /* verification ID */
guint32 id2; /* verification ID */
guint16 version; /* config version */
guint8 unused[2];
} FuSynapromFirmwareCfgHeader;
FuFirmware *fu_synaprom_firmware_new (void);

View File

@ -61,27 +61,4 @@ if get_option('tests')
install_dir : installed_test_bindir,
)
test('synaptics-prometheus-self-test', e, env : testdatadirs) # added to installed-tests
# for fuzzing
executable(
'synaptics-prometheus-dump',
sources : [
'fu-dump.c',
'fu-synaprom-firmware.c',
],
include_directories : [
root_incdir,
fwupd_incdir,
fwupdplugin_incdir,
],
dependencies : [
gio,
libxmlb,
],
link_with : [
fwupd,
fwupdplugin,
],
c_args : cargs
)
endif