trivial: Add some common functionality from reading and writing to a buffer

This commit is contained in:
Richard Hughes 2017-12-08 10:48:15 +00:00
parent 725c19fa88
commit ae252cd83c
10 changed files with 158 additions and 33 deletions

View File

@ -23,6 +23,8 @@
#include <string.h> #include <string.h>
#include "fu-common.h"
#include "dfu-cipher-xtea.h" #include "dfu-cipher-xtea.h"
#include "fwupd-error.h" #include "fwupd-error.h"
@ -33,21 +35,15 @@
static void static void
dfu_cipher_buf_to_uint32 (const guint8 *buf, guint buflen, guint32 *array) dfu_cipher_buf_to_uint32 (const guint8 *buf, guint buflen, guint32 *array)
{ {
guint32 tmp_le; for (guint i = 0; i < buflen / 4; i++)
for (guint i = 0; i < buflen / 4; i++) { array[i] = fu_common_read_uint32 (&buf[i * 4], G_LITTLE_ENDIAN);
memcpy (&tmp_le, &buf[i * 4], 4);
array[i] = GUINT32_FROM_LE (tmp_le);
}
} }
static void static void
dfu_cipher_uint32_to_buf (guint8 *buf, guint buflen, const guint32 *array) dfu_cipher_uint32_to_buf (guint8 *buf, guint buflen, const guint32 *array)
{ {
guint32 tmp_le; for (guint i = 0; i < buflen / 4; i++)
for (guint i = 0; i < buflen / 4; i++) { fu_common_write_uint32 (&buf[i * 4], array[i], G_LITTLE_ENDIAN);
tmp_le = GUINT32_TO_LE (array[i]);
memcpy (&buf[i * 4], &tmp_le, 4);
}
} }
static gboolean static gboolean

View File

@ -23,6 +23,8 @@
#include <string.h> #include <string.h>
#include "fu-common.h"
#include "dfu-element.h" #include "dfu-element.h"
#include "dfu-firmware.h" #include "dfu-firmware.h"
#include "dfu-format-ihex.h" #include "dfu-format-ihex.h"
@ -331,10 +333,11 @@ dfu_firmware_to_ihex_bytes (GString *str, guint8 record_type,
/* need to offset */ /* need to offset */
if (address_offset != address_offset_last) { if (address_offset != address_offset_last) {
guint16 tmp = GUINT16_TO_BE (address_offset); guint8 buf[2];
fu_common_write_uint16 (buf, address_offset, G_BIG_ENDIAN);
dfu_firmware_ihex_emit_chunk (str, 0x0, dfu_firmware_ihex_emit_chunk (str, 0x0,
DFU_INHX32_RECORD_TYPE_EXTENDED, DFU_INHX32_RECORD_TYPE_EXTENDED,
(guint8 *) &tmp, 2); buf, 2);
address_offset_last = address_offset; address_offset_last = address_offset;
} }
address_tmp &= 0xffff; address_tmp &= 0xffff;

View File

@ -240,14 +240,13 @@ dfu_target_avr32_select_memory_page (DfuTarget *target,
GError **error) GError **error)
{ {
g_autoptr(GBytes) data_in = NULL; g_autoptr(GBytes) data_in = NULL;
guint16 memory_page_le = GUINT16_TO_BE (memory_page);
guint8 buf[5]; guint8 buf[5];
/* format buffer */ /* format buffer */
buf[0] = DFU_AVR32_GROUP_SELECT; buf[0] = DFU_AVR32_GROUP_SELECT;
buf[1] = DFU_AVR32_CMD_SELECT_MEMORY; buf[1] = DFU_AVR32_CMD_SELECT_MEMORY;
buf[2] = DFU_AVR32_MEMORY_PAGE; buf[2] = DFU_AVR32_MEMORY_PAGE;
memcpy (&buf[3], &memory_page_le, 2); fu_common_write_uint16 (&buf[3], memory_page, G_BIG_ENDIAN);
data_in = g_bytes_new_static (buf, sizeof(buf)); data_in = g_bytes_new_static (buf, sizeof(buf));
g_debug ("selecting memory page 0x%02x", (guint) memory_page); g_debug ("selecting memory page 0x%02x", (guint) memory_page);
if (!dfu_target_download_chunk (target, 0, data_in, error)) { if (!dfu_target_download_chunk (target, 0, data_in, error)) {
@ -275,15 +274,13 @@ dfu_target_avr_read_memory (DfuTarget *target,
GError **error) GError **error)
{ {
g_autoptr(GBytes) data_in = NULL; g_autoptr(GBytes) data_in = NULL;
guint16 addr_start_le = GUINT16_TO_BE (addr_start);
guint16 addr_end_le = GUINT16_TO_BE (addr_end);
guint8 buf[6]; guint8 buf[6];
/* format buffer */ /* format buffer */
buf[0] = DFU_AVR32_GROUP_UPLOAD; buf[0] = DFU_AVR32_GROUP_UPLOAD;
buf[1] = DFU_AVR32_CMD_READ_MEMORY; buf[1] = DFU_AVR32_CMD_READ_MEMORY;
memcpy (&buf[2], &addr_start_le, 2); fu_common_write_uint16 (&buf[2], addr_start, G_BIG_ENDIAN);
memcpy (&buf[4], &addr_end_le, 2); fu_common_write_uint16 (&buf[4], addr_end, G_BIG_ENDIAN);
data_in = g_bytes_new_static (buf, sizeof(buf)); data_in = g_bytes_new_static (buf, sizeof(buf));
g_debug ("reading memory from 0x%04x to 0x%04x", g_debug ("reading memory from 0x%04x to 0x%04x",
(guint) addr_start, (guint) addr_end); (guint) addr_start, (guint) addr_end);
@ -564,8 +561,6 @@ dfu_target_avr_download_element (DfuTarget *target,
/* process each chunk */ /* process each chunk */
for (guint i = 0; i < packets->len; i++) { for (guint i = 0; i < packets->len; i++) {
const DfuChunkedPacket *packet = g_ptr_array_index (packets, i); const DfuChunkedPacket *packet = g_ptr_array_index (packets, i);
guint16 addr_start_le;
guint16 addr_end_le;
g_autofree guint8 *buf = NULL; g_autofree guint8 *buf = NULL;
g_autoptr(GBytes) chunk_tmp = NULL; g_autoptr(GBytes) chunk_tmp = NULL;
@ -587,13 +582,11 @@ dfu_target_avr_download_element (DfuTarget *target,
} }
/* create packet with header and footer */ /* create packet with header and footer */
addr_start_le = GUINT16_TO_BE (packet->address);
addr_end_le = GUINT16_TO_BE (packet->address + packet->data_sz - 1);
buf = g_malloc0 (packet->data_sz + header_sz + sizeof(footer)); buf = g_malloc0 (packet->data_sz + 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;
memcpy (&buf[2], &addr_start_le, 2); fu_common_write_uint16 (&buf[2], packet->address, G_BIG_ENDIAN);
memcpy (&buf[4], &addr_end_le, 2); fu_common_write_uint16 (&buf[4], packet->address + packet->data_sz - 1, G_BIG_ENDIAN);
memcpy (&buf[header_sz], packet->data, packet->data_sz); memcpy (&buf[header_sz], packet->data, packet->data_sz);
memcpy (&buf[header_sz + packet->data_sz], footer, sizeof(footer)); memcpy (&buf[header_sz + packet->data_sz], footer, sizeof(footer));

View File

@ -99,7 +99,6 @@ nitrokey_execute_cmd (GUsbDevice *usb_device, guint8 command,
gboolean ret; gboolean ret;
gsize actual_len = 0; gsize actual_len = 0;
guint32 crc_tmp; guint32 crc_tmp;
guint32 crc_le;
guint8 buf[64]; guint8 buf[64];
g_return_val_if_fail (buf_in_sz <= NITROKEY_REQUEST_DATA_LENGTH, FALSE); g_return_val_if_fail (buf_in_sz <= NITROKEY_REQUEST_DATA_LENGTH, FALSE);
@ -111,8 +110,7 @@ nitrokey_execute_cmd (GUsbDevice *usb_device, guint8 command,
if (buf_in != NULL) if (buf_in != NULL)
memcpy (&buf[1], buf_in, buf_in_sz); memcpy (&buf[1], buf_in, buf_in_sz);
crc_tmp = fu_nitrokey_perform_crc32 (buf, sizeof(buf) - 4); crc_tmp = fu_nitrokey_perform_crc32 (buf, sizeof(buf) - 4);
crc_le = GUINT32_TO_LE (crc_tmp); fu_common_write_uint32 (&buf[NITROKEY_REQUEST_DATA_LENGTH + 1], crc_tmp, G_LITTLE_ENDIAN);
memcpy (&buf[NITROKEY_REQUEST_DATA_LENGTH + 1], &crc_le, sizeof(guint32));
/* send request */ /* send request */
_dump_to_console ("request", buf, sizeof(buf)); _dump_to_console ("request", buf, sizeof(buf));

View File

@ -27,6 +27,7 @@
#include "fwupd-common-private.h" #include "fwupd-common-private.h"
#include "fu-rom.h" #include "fu-rom.h"
#include "fu-common.h"
static gboolean static gboolean
fu_fuzzer_rom_parse (const gchar *fn, GError **error) fu_fuzzer_rom_parse (const gchar *fn, GError **error)
@ -88,7 +89,6 @@ static gboolean
fu_fuzzer_rom_create (GError **error) fu_fuzzer_rom_create (GError **error)
{ {
GString *str; GString *str;
guint16 sz;
guint8 *buffer; guint8 *buffer;
g_autofree guint8 *blob_header = NULL; g_autofree guint8 *blob_header = NULL;
g_autofree guint8 *blob_ifr = NULL; g_autofree guint8 *blob_ifr = NULL;
@ -147,8 +147,7 @@ fu_fuzzer_rom_create (GError **error)
blob_ifr = g_malloc0 (0x80); blob_ifr = g_malloc0 (0x80);
buffer = blob_ifr; buffer = blob_ifr;
memcpy (buffer, "NVGI", 4); memcpy (buffer, "NVGI", 4);
sz = GUINT16_TO_BE (0x80); fu_common_write_uint16 (&buffer[0x15], 0x80, G_BIG_ENDIAN);
memcpy (&buffer[0x15], &sz, 2);
g_hash_table_insert (hash, (gpointer) "naked-ifr.rom", g_hash_table_insert (hash, (gpointer) "naked-ifr.rom",
g_string_new_len ((const gchar *) blob_ifr, 0x80)); g_string_new_len ((const gchar *) blob_ifr, 0x80));
str = g_string_new_len ((gchar *) blob_ifr, 0x80); str = g_string_new_len ((gchar *) blob_ifr, 0x80);

View File

@ -36,6 +36,7 @@ executable(
], ],
link_with : [ link_with : [
fwupd, fwupd,
libfwupdprivate,
], ],
c_args : cargs, c_args : cargs,
) )

View File

@ -600,7 +600,7 @@ lu_device_peripheral_write_firmware_pkt (LuDevice *device,
const guint8 *data, const guint8 *data,
GError **error) GError **error)
{ {
guint32 packet_cnt_be; guint32 packet_cnt;
g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new ();
g_autoptr(GError) error_local = NULL; g_autoptr(GError) error_local = NULL;
@ -616,8 +616,8 @@ lu_device_peripheral_write_firmware_pkt (LuDevice *device,
} }
/* check error */ /* check error */
memcpy (&packet_cnt_be, msg->data, 4); packet_cnt = fu_common_read_uint32 (msg->data, G_BIG_ENDIAN);
g_debug ("packet_cnt=0x%04x", GUINT32_FROM_BE (packet_cnt_be)); g_debug ("packet_cnt=0x%04x", packet_cnt);
if (lu_device_peripheral_check_status (msg->data[4], &error_local)) if (lu_device_peripheral_check_status (msg->data[4], &error_local))
return TRUE; return TRUE;

View File

@ -27,6 +27,7 @@
#include <archive_entry.h> #include <archive_entry.h>
#include <archive.h> #include <archive.h>
#include <errno.h> #include <errno.h>
#include <string.h>
#include "fwupd-error.h" #include "fwupd-error.h"
@ -538,3 +539,107 @@ fu_common_spawn_sync (const gchar * const * argv,
g_main_loop_run (helper->loop); g_main_loop_run (helper->loop);
return g_subprocess_wait_check (subprocess, cancellable, error); return g_subprocess_wait_check (subprocess, cancellable, error);
} }
/**
* fu_common_write_uint16:
* @buf: A writable buffer
* @val_native: a value in host byte-order
* @error: A #FuEndianType, e.g. %G_LITTLE_ENDIAN
*
* Writes a value to a buffer using a specified endian.
**/
void
fu_common_write_uint16 (guint8 *buf, guint16 val_native, FuEndianType endian)
{
guint16 val_hw;
switch (endian) {
case G_BIG_ENDIAN:
val_hw = GUINT16_TO_BE(val_native);
break;
case G_LITTLE_ENDIAN:
val_hw = GUINT16_TO_LE(val_native);
break;
default:
g_assert_not_reached ();
}
memcpy (buf, &val_hw, sizeof(val_hw));
}
/**
* fu_common_write_uint32:
* @buf: A writable buffer
* @val_native: a value in host byte-order
* @error: A #FuEndianType, e.g. %G_LITTLE_ENDIAN
*
* Writes a value to a buffer using a specified endian.
**/
void
fu_common_write_uint32 (guint8 *buf, guint32 val_native, FuEndianType endian)
{
guint32 val_hw;
switch (endian) {
case G_BIG_ENDIAN:
val_hw = GUINT32_TO_BE(val_native);
break;
case G_LITTLE_ENDIAN:
val_hw = GUINT32_TO_LE(val_native);
break;
default:
g_assert_not_reached ();
}
memcpy (buf, &val_hw, sizeof(val_hw));
}
/**
* fu_common_read_uint16:
* @buf: A readable buffer
* @error: A #FuEndianType, e.g. %G_LITTLE_ENDIAN
*
* Read a value from a buffer using a specified endian.
*
* Returns: a value in host byte-order
**/
guint16
fu_common_read_uint16 (const guint8 *buf, FuEndianType endian)
{
guint16 val_hw, val_native;
memcpy (&val_hw, buf, sizeof(val_hw));
switch (endian) {
case G_BIG_ENDIAN:
val_native = GUINT16_FROM_BE(val_hw);
break;
case G_LITTLE_ENDIAN:
val_native = GUINT16_FROM_LE(val_hw);
break;
default:
g_assert_not_reached ();
}
return val_native;
}
/**
* fu_common_read_uint32:
* @buf: A readable buffer
* @error: A #FuEndianType, e.g. %G_LITTLE_ENDIAN
*
* Read a value from a buffer using a specified endian.
*
* Returns: a value in host byte-order
**/
guint32
fu_common_read_uint32 (const guint8 *buf, FuEndianType endian)
{
guint32 val_hw, val_native;
memcpy (&val_hw, buf, sizeof(val_hw));
switch (endian) {
case G_BIG_ENDIAN:
val_native = GUINT32_FROM_BE(val_hw);
break;
case G_LITTLE_ENDIAN:
val_native = GUINT32_FROM_LE(val_hw);
break;
default:
g_assert_not_reached ();
}
return val_native;
}

View File

@ -53,4 +53,17 @@ GBytes *fu_common_firmware_builder (GBytes *bytes,
const gchar *output_fn, const gchar *output_fn,
GError **error); GError **error);
typedef guint FuEndianType;
void fu_common_write_uint16 (guint8 *buf,
guint16 val_native,
FuEndianType endian);
void fu_common_write_uint32 (guint8 *buf,
guint32 val_native,
FuEndianType endian);
guint16 fu_common_read_uint16 (const guint8 *buf,
FuEndianType endian);
guint32 fu_common_read_uint32 (const guint8 *buf,
FuEndianType endian);
#endif /* __FU_COMMON_H__ */ #endif /* __FU_COMMON_H__ */

View File

@ -1338,6 +1338,22 @@ fu_progressbar_func (void)
fu_progressbar_update (progressbar, FWUPD_STATUS_IDLE, 0); fu_progressbar_update (progressbar, FWUPD_STATUS_IDLE, 0);
} }
static void
fu_common_endian_func (void)
{
guint8 buf[2];
fu_common_write_uint16 (buf, 0x1234, G_LITTLE_ENDIAN);
g_assert_cmpint (buf[0], ==, 0x34);
g_assert_cmpint (buf[1], ==, 0x12);
g_assert_cmpint (fu_common_read_uint16 (buf, G_LITTLE_ENDIAN), ==, 0x1234);
fu_common_write_uint16 (buf, 0x1234, G_BIG_ENDIAN);
g_assert_cmpint (buf[0], ==, 0x12);
g_assert_cmpint (buf[1], ==, 0x34);
g_assert_cmpint (fu_common_read_uint16 (buf, G_BIG_ENDIAN), ==, 0x1234);
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@ -1372,6 +1388,7 @@ main (int argc, char **argv)
g_test_add_func ("/fwupd/plugin{quirks}", fu_plugin_quirks_func); g_test_add_func ("/fwupd/plugin{quirks}", fu_plugin_quirks_func);
g_test_add_func ("/fwupd/keyring{gpg}", fu_keyring_gpg_func); g_test_add_func ("/fwupd/keyring{gpg}", fu_keyring_gpg_func);
g_test_add_func ("/fwupd/keyring{pkcs7}", fu_keyring_pkcs7_func); g_test_add_func ("/fwupd/keyring{pkcs7}", fu_keyring_pkcs7_func);
g_test_add_func ("/fwupd/common{endian}", fu_common_endian_func);
g_test_add_func ("/fwupd/common{spawn)", fu_common_spawn_func); g_test_add_func ("/fwupd/common{spawn)", fu_common_spawn_func);
g_test_add_func ("/fwupd/common{firmware-builder}", fu_common_firmware_builder_func); g_test_add_func ("/fwupd/common{firmware-builder}", fu_common_firmware_builder_func);
return g_test_run (); return g_test_run ();