mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-11 22:30:47 +00:00
trivial: Add some common functionality from reading and writing to a buffer
This commit is contained in:
parent
725c19fa88
commit
ae252cd83c
@ -23,6 +23,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -36,6 +36,7 @@ executable(
|
||||
],
|
||||
link_with : [
|
||||
fwupd,
|
||||
libfwupdprivate,
|
||||
],
|
||||
c_args : cargs,
|
||||
)
|
||||
|
@ -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;
|
||||
|
||||
|
105
src/fu-common.c
105
src/fu-common.c
@ -27,6 +27,7 @@
|
||||
#include <archive_entry.h>
|
||||
#include <archive.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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 ();
|
||||
|
Loading…
Reference in New Issue
Block a user