diff --git a/plugins/unifying/fu-unifying-bootloader.c b/plugins/unifying/fu-unifying-bootloader.c index b4f471051..5a276dc5d 100644 --- a/plugins/unifying/fu-unifying-bootloader.c +++ b/plugins/unifying/fu-unifying-bootloader.c @@ -8,6 +8,7 @@ #include +#include "fu-firmware-common.h" #include "fu-unifying-common.h" #include "fu-unifying-bootloader.h" #include "fu-unifying-hidpp.h" @@ -57,6 +58,8 @@ fu_unifying_bootloader_parse_requests (FuUnifyingBootloader *self, GBytes *fw, G for (guint i = 0; lines[i] != NULL; i++) { g_autoptr(FuUnifyingBootloaderRequest) payload = NULL; guint8 rec_type = 0x00; + guint16 offset = 0x0000; + gboolean exit = FALSE; /* skip empty lines */ tmp = lines[i]; @@ -75,16 +78,52 @@ fu_unifying_bootloader_parse_requests (FuUnifyingBootloader *self, GBytes *fw, G } payload->addr = ((guint16) fu_unifying_buffer_read_uint8 (tmp + 0x03)) << 8; payload->addr |= fu_unifying_buffer_read_uint8 (tmp + 0x05); + payload->cmd = FU_UNIFYING_BOOTLOADER_CMD_WRITE_RAM_BUFFER; rec_type = fu_unifying_buffer_read_uint8 (tmp + 0x07); - /* record type of 0xFD indicates signature data */ - if (rec_type == 0xFD) { - payload->cmd = FU_UNIFYING_BOOTLOADER_CMD_WRITE_SIGNATURE; - } else { - payload->cmd = FU_UNIFYING_BOOTLOADER_CMD_WRITE_RAM_BUFFER; + switch (rec_type) { + case 0x00: /* data */ + break; + case 0x01: /* EOF */ + exit = TRUE; + break; + case 0x03: /* start segment address */ + /* this is used to specify the start address, + it is doesn't mater in this context so we can + safely ignore it */ + continue; + case 0x04: /* extended linear address */ + offset = fu_firmware_strparse_uint16 (tmp + 0x09); + if (offset != 0x0000) { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + "extended linear addresses with offset different from 0 are not supported"); + return NULL; + } + continue; + case 0x05: /* start linear address */ + /* this is used to specify the start address, + it is doesn't mater in this context so we can + safely ignore it */ + continue; + case 0xFD: /* custom - vendor */ + /* record type of 0xFD indicates signature data */ + payload->cmd = FU_UNIFYING_BOOTLOADER_CMD_WRITE_SIGNATURE; + break; + default: + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + "intel hex file record type %02x not supported", + rec_type); + return NULL; } + if (exit) + break; + /* read the data, but skip the checksum byte */ for (guint j = 0; j < payload->len; j++) { const gchar *ptr = tmp + 0x09 + (j * 2);