diff --git a/plugins/dfu/dfu-cipher-xtea.c b/plugins/dfu/dfu-cipher-xtea.c index 7002ec093..c89f19744 100644 --- a/plugins/dfu/dfu-cipher-xtea.c +++ b/plugins/dfu/dfu-cipher-xtea.c @@ -23,6 +23,8 @@ #include +#include "fu-common.h" + #include "dfu-cipher-xtea.h" #include "fwupd-error.h" @@ -33,21 +35,15 @@ static void dfu_cipher_buf_to_uint32 (const guint8 *buf, guint buflen, guint32 *array) { - guint32 tmp_le; - for (guint i = 0; i < buflen / 4; i++) { - memcpy (&tmp_le, &buf[i * 4], 4); - array[i] = GUINT32_FROM_LE (tmp_le); - } + for (guint i = 0; i < buflen / 4; i++) + array[i] = fu_common_read_uint32 (&buf[i * 4], G_LITTLE_ENDIAN); } static void dfu_cipher_uint32_to_buf (guint8 *buf, guint buflen, const guint32 *array) { - guint32 tmp_le; - for (guint i = 0; i < buflen / 4; i++) { - tmp_le = GUINT32_TO_LE (array[i]); - memcpy (&buf[i * 4], &tmp_le, 4); - } + for (guint i = 0; i < buflen / 4; i++) + fu_common_write_uint32 (&buf[i * 4], array[i], G_LITTLE_ENDIAN); } static gboolean diff --git a/plugins/dfu/dfu-format-ihex.c b/plugins/dfu/dfu-format-ihex.c index 01f2b6a2a..2b03d324d 100644 --- a/plugins/dfu/dfu-format-ihex.c +++ b/plugins/dfu/dfu-format-ihex.c @@ -23,6 +23,8 @@ #include +#include "fu-common.h" + #include "dfu-element.h" #include "dfu-firmware.h" #include "dfu-format-ihex.h" @@ -331,10 +333,11 @@ dfu_firmware_to_ihex_bytes (GString *str, guint8 record_type, /* need to offset */ 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_INHX32_RECORD_TYPE_EXTENDED, - (guint8 *) &tmp, 2); + buf, 2); address_offset_last = address_offset; } address_tmp &= 0xffff; diff --git a/plugins/dfu/dfu-target-avr.c b/plugins/dfu/dfu-target-avr.c index 555d4fee1..10fa6efb9 100644 --- a/plugins/dfu/dfu-target-avr.c +++ b/plugins/dfu/dfu-target-avr.c @@ -240,14 +240,13 @@ dfu_target_avr32_select_memory_page (DfuTarget *target, GError **error) { g_autoptr(GBytes) data_in = NULL; - guint16 memory_page_le = GUINT16_TO_BE (memory_page); guint8 buf[5]; /* format buffer */ buf[0] = DFU_AVR32_GROUP_SELECT; buf[1] = DFU_AVR32_CMD_SELECT_MEMORY; 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)); g_debug ("selecting memory page 0x%02x", (guint) memory_page); if (!dfu_target_download_chunk (target, 0, data_in, error)) { @@ -275,15 +274,13 @@ dfu_target_avr_read_memory (DfuTarget *target, GError **error) { 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]; /* format buffer */ buf[0] = DFU_AVR32_GROUP_UPLOAD; buf[1] = DFU_AVR32_CMD_READ_MEMORY; - memcpy (&buf[2], &addr_start_le, 2); - memcpy (&buf[4], &addr_end_le, 2); + fu_common_write_uint16 (&buf[2], addr_start, G_BIG_ENDIAN); + fu_common_write_uint16 (&buf[4], addr_end, G_BIG_ENDIAN); data_in = g_bytes_new_static (buf, sizeof(buf)); g_debug ("reading memory from 0x%04x to 0x%04x", (guint) addr_start, (guint) addr_end); @@ -564,8 +561,6 @@ dfu_target_avr_download_element (DfuTarget *target, /* process each chunk */ for (guint i = 0; i < packets->len; i++) { const DfuChunkedPacket *packet = g_ptr_array_index (packets, i); - guint16 addr_start_le; - guint16 addr_end_le; g_autofree guint8 *buf = NULL; g_autoptr(GBytes) chunk_tmp = NULL; @@ -587,13 +582,11 @@ dfu_target_avr_download_element (DfuTarget *target, } /* 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[0] = DFU_AVR32_GROUP_DOWNLOAD; buf[1] = DFU_AVR32_CMD_PROGRAM_START; - memcpy (&buf[2], &addr_start_le, 2); - memcpy (&buf[4], &addr_end_le, 2); + fu_common_write_uint16 (&buf[2], packet->address, G_BIG_ENDIAN); + 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_sz], footer, sizeof(footer)); diff --git a/plugins/nitrokey/fu-nitrokey-device.c b/plugins/nitrokey/fu-nitrokey-device.c index 781cad61b..223f26b31 100644 --- a/plugins/nitrokey/fu-nitrokey-device.c +++ b/plugins/nitrokey/fu-nitrokey-device.c @@ -99,7 +99,6 @@ nitrokey_execute_cmd (GUsbDevice *usb_device, guint8 command, gboolean ret; gsize actual_len = 0; guint32 crc_tmp; - guint32 crc_le; guint8 buf[64]; 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) memcpy (&buf[1], buf_in, buf_in_sz); crc_tmp = fu_nitrokey_perform_crc32 (buf, sizeof(buf) - 4); - crc_le = GUINT32_TO_LE (crc_tmp); - memcpy (&buf[NITROKEY_REQUEST_DATA_LENGTH + 1], &crc_le, sizeof(guint32)); + fu_common_write_uint32 (&buf[NITROKEY_REQUEST_DATA_LENGTH + 1], crc_tmp, G_LITTLE_ENDIAN); /* send request */ _dump_to_console ("request", buf, sizeof(buf)); diff --git a/plugins/udev/fu-rom-tool.c b/plugins/udev/fu-rom-tool.c index 1a86c2248..93d9e3706 100644 --- a/plugins/udev/fu-rom-tool.c +++ b/plugins/udev/fu-rom-tool.c @@ -27,6 +27,7 @@ #include "fwupd-common-private.h" #include "fu-rom.h" +#include "fu-common.h" static gboolean fu_fuzzer_rom_parse (const gchar *fn, GError **error) @@ -88,7 +89,6 @@ static gboolean fu_fuzzer_rom_create (GError **error) { GString *str; - guint16 sz; guint8 *buffer; g_autofree guint8 *blob_header = NULL; g_autofree guint8 *blob_ifr = NULL; @@ -147,8 +147,7 @@ fu_fuzzer_rom_create (GError **error) blob_ifr = g_malloc0 (0x80); buffer = blob_ifr; memcpy (buffer, "NVGI", 4); - sz = GUINT16_TO_BE (0x80); - memcpy (&buffer[0x15], &sz, 2); + fu_common_write_uint16 (&buffer[0x15], 0x80, G_BIG_ENDIAN); g_hash_table_insert (hash, (gpointer) "naked-ifr.rom", g_string_new_len ((const gchar *) blob_ifr, 0x80)); str = g_string_new_len ((gchar *) blob_ifr, 0x80); diff --git a/plugins/udev/meson.build b/plugins/udev/meson.build index e24441bd0..c37d27caf 100644 --- a/plugins/udev/meson.build +++ b/plugins/udev/meson.build @@ -36,6 +36,7 @@ executable( ], link_with : [ fwupd, + libfwupdprivate, ], c_args : cargs, ) diff --git a/plugins/unifying/lu-device-peripheral.c b/plugins/unifying/lu-device-peripheral.c index 24631ed3d..7cdb001b0 100644 --- a/plugins/unifying/lu-device-peripheral.c +++ b/plugins/unifying/lu-device-peripheral.c @@ -600,7 +600,7 @@ lu_device_peripheral_write_firmware_pkt (LuDevice *device, const guint8 *data, GError **error) { - guint32 packet_cnt_be; + guint32 packet_cnt; g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); g_autoptr(GError) error_local = NULL; @@ -616,8 +616,8 @@ lu_device_peripheral_write_firmware_pkt (LuDevice *device, } /* check error */ - memcpy (&packet_cnt_be, msg->data, 4); - g_debug ("packet_cnt=0x%04x", GUINT32_FROM_BE (packet_cnt_be)); + packet_cnt = fu_common_read_uint32 (msg->data, G_BIG_ENDIAN); + g_debug ("packet_cnt=0x%04x", packet_cnt); if (lu_device_peripheral_check_status (msg->data[4], &error_local)) return TRUE; diff --git a/src/fu-common.c b/src/fu-common.c index cb2d24f86..0626235d0 100644 --- a/src/fu-common.c +++ b/src/fu-common.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "fwupd-error.h" @@ -538,3 +539,107 @@ fu_common_spawn_sync (const gchar * const * argv, g_main_loop_run (helper->loop); 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; +} diff --git a/src/fu-common.h b/src/fu-common.h index fad1fcfd1..c31177b83 100644 --- a/src/fu-common.h +++ b/src/fu-common.h @@ -53,4 +53,17 @@ GBytes *fu_common_firmware_builder (GBytes *bytes, const gchar *output_fn, 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__ */ diff --git a/src/fu-self-test.c b/src/fu-self-test.c index b6ecf125c..48d86c73a 100644 --- a/src/fu-self-test.c +++ b/src/fu-self-test.c @@ -1338,6 +1338,22 @@ fu_progressbar_func (void) 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 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/keyring{gpg}", fu_keyring_gpg_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{firmware-builder}", fu_common_firmware_builder_func); return g_test_run ();