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]; guint16 unused[3];
} FuSynapromIotaConfigVersion; } 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_ALLIOTAS 0x0001 /* itype ignored*/
#define FU_SYNAPROM_CMD_IOTA_FIND_FLAGS_READMAX 0x0002 /* nbytes 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 */ #define FU_SYNAPROM_MAX_IOTA_READ_SIZE (64 * 1024) /* max size of iota data returned */

View File

@ -14,10 +14,16 @@
struct _FuSynapromFirmware { struct _FuSynapromFirmware {
FuFirmware parent_instance; FuFirmware parent_instance;
guint32 product_id;
}; };
G_DEFINE_TYPE (FuSynapromFirmware, fu_synaprom_firmware, FU_TYPE_FIRMWARE) 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)) { typedef struct __attribute__((packed)) {
guint16 tag; guint16 tag;
guint32 bufsz; guint32 bufsz;
@ -41,6 +47,13 @@ fu_synaprom_firmware_tag_to_string (guint16 tag)
return NULL; 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 static gboolean
fu_synaprom_firmware_parse (FuFirmware *firmware, fu_synaprom_firmware_parse (FuFirmware *firmware,
GBytes *fw, GBytes *fw,
@ -116,12 +129,13 @@ fu_synaprom_firmware_parse (FuFirmware *firmware,
} }
static GBytes * 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 (); GByteArray *blob = g_byte_array_new ();
const guint8 data[] = { 'R', 'H' }; g_autoptr(GBytes) payload = NULL;
FuSynapromFirmwareMfwHeader hdr = { FuSynapromFirmwareMfwHeader hdr = {
.product = GUINT32_TO_LE(0x41), .product = GUINT32_TO_LE(self->product_id),
.id = GUINT32_TO_LE(0xff), .id = GUINT32_TO_LE(0xff),
.buildtime = GUINT32_TO_LE(0xff), .buildtime = GUINT32_TO_LE(0xff),
.buildnum = GUINT32_TO_LE(0xff), .buildnum = GUINT32_TO_LE(0xff),
@ -130,14 +144,27 @@ fu_synaprom_firmware_write (FuFirmware *self, GError **error)
}; };
/* add header */ /* add header */
fu_byte_array_append_uint16 (blob, FU_SYNAPROM_FIRMWARE_TAG_MFW_HEADER, G_LITTLE_ENDIAN); fu_byte_array_append_uint16 (blob,
fu_byte_array_append_uint32 (blob, sizeof(hdr), G_LITTLE_ENDIAN); 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)); g_byte_array_append (blob, (const guint8 *) &hdr, sizeof(hdr));
/* add payload */ /* add payload */
fu_byte_array_append_uint16 (blob, FU_SYNAPROM_FIRMWARE_TAG_MFW_PAYLOAD, G_LITTLE_ENDIAN); payload = fu_firmware_get_image_default_bytes (firmware, error);
fu_byte_array_append_uint32 (blob, sizeof(data), G_LITTLE_ENDIAN); if (payload == NULL)
g_byte_array_append (blob, data, sizeof(data)); 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 */ /* add signature */
for (guint i = 0; i < FU_SYNAPROM_FIRMWARE_SIGSIZE; i++) 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); 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 static void
fu_synaprom_firmware_init (FuSynapromFirmware *self) fu_synaprom_firmware_init (FuSynapromFirmware *self)
{ {
@ -156,6 +198,8 @@ fu_synaprom_firmware_class_init (FuSynapromFirmwareClass *klass)
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass); FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
klass_firmware->parse = fu_synaprom_firmware_parse; klass_firmware->parse = fu_synaprom_firmware_parse;
klass_firmware->write = fu_synaprom_firmware_write; klass_firmware->write = fu_synaprom_firmware_write;
klass_firmware->to_string = fu_synaprom_firmware_to_string;
klass_firmware->build = fu_synaprom_firmware_build;
} }
FuFirmware * FuFirmware *

View File

@ -8,16 +8,10 @@
#pragma once #pragma once
#include "fu-firmware.h" #include "fu-firmware.h"
#include "fu-synaprom-firmware.h"
#define FU_TYPE_SYNAPROM_FIRMWARE (fu_synaprom_firmware_get_type ()) #define FU_TYPE_SYNAPROM_FIRMWARE (fu_synaprom_firmware_get_type ())
G_DECLARE_FINAL_TYPE (FuSynapromFirmware, fu_synaprom_firmware, FU, SYNAPROM_FIRMWARE, FuFirmware) 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 */ /* le */
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
guint32 product; guint32 product;
@ -29,13 +23,4 @@ typedef struct __attribute__((packed)) {
guint8 unused[6]; guint8 unused[6];
} FuSynapromFirmwareMfwHeader; } 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); FuFirmware *fu_synaprom_firmware_new (void);

View File

@ -61,27 +61,4 @@ if get_option('tests')
install_dir : installed_test_bindir, install_dir : installed_test_bindir,
) )
test('synaptics-prometheus-self-test', e, env : testdatadirs) # added to installed-tests 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 endif