steelseries: fizz: Add support for 2.4G connection

This commit is contained in:
Gaël PORTAY 2022-05-23 12:05:10 +02:00 committed by Gaël PORTAY
parent c5defa89e9
commit 714983d82d
9 changed files with 479 additions and 77 deletions

View File

@ -20,6 +20,7 @@
{
"version": "1.8.1",
"guids": [
"541b2713-d367-5240-a443-bed07f09ffbf",
"4f3fac7c-981b-58cc-bb58-8a3b90f31c9c",
"ac7d7cbb-7ef5-5466-ab3d-e70ced97ee61"
]
@ -44,6 +45,7 @@
{
"version": "1.9.3",
"guids": [
"541b2713-d367-5240-a443-bed07f09ffbf",
"4f3fac7c-981b-58cc-bb58-8a3b90f31c9c",
"ac7d7cbb-7ef5-5466-ab3d-e70ced97ee61"
]

View File

@ -59,7 +59,9 @@ Wireless adapter must be connected to host.
### Aerox 3 Wireless
The mouse must be connected to host via the USB-A to USB-C cable.
The mouse switch button underneath must be set to 2.4G, and its 2.4G USB
Wireless adapter must be connected to host; or the mouse must be connected to
host via the USB-A to USB-C cable.
## Vendor ID Security

View File

@ -8,6 +8,7 @@
#include <fwupdplugin.h>
#include "fu-steelseries-fizz-tunnel.h"
#include "fu-steelseries-fizz.h"
#include "fu-steelseries-gamepad.h"
#include "fu-steelseries-mouse.h"
@ -18,6 +19,7 @@ fu_plugin_steelseries_init(FuPlugin *plugin)
{
fu_plugin_add_device_gtype(plugin, FU_TYPE_STEELSERIES_MOUSE);
fu_plugin_add_device_gtype(plugin, FU_TYPE_STEELSERIES_FIZZ);
fu_plugin_add_device_gtype(plugin, FU_TYPE_STEELSERIES_FIZZ_TUNNEL);
fu_plugin_add_device_gtype(plugin, FU_TYPE_STEELSERIES_GAMEPAD);
fu_plugin_add_device_gtype(plugin, FU_TYPE_STEELSERIES_SONIC);
}

View File

@ -0,0 +1,212 @@
/*
* Copyright (C) 2022 Gaël PORTAY <gael.portay@collabora.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include "config.h"
#include "fu-steelseries-firmware.h"
#include "fu-steelseries-fizz-tunnel.h"
struct _FuSteelseriesFizzTunnel {
FuDevice parent_instance;
};
G_DEFINE_TYPE(FuSteelseriesFizzTunnel, fu_steelseries_fizz_tunnel, FU_TYPE_DEVICE)
static gboolean
fu_steelseries_fizz_tunnel_attach(FuDevice *device, FuProgress *progress, GError **error)
{
FuDevice *parent = fu_device_get_parent(device);
g_autoptr(GError) error_local = NULL;
if (!fu_steelseries_fizz_reset(parent,
TRUE,
STEELSERIES_FIZZ_RESET_MODE_NORMAL,
&error_local))
g_warning("failed to reset: %s", error_local->message);
fu_progress_sleep(fu_progress_get_child(progress),
fu_device_get_remove_delay(FU_DEVICE(device)));
/* success */
return TRUE;
}
static gboolean
fu_steelseries_fizz_tunnel_probe(FuDevice *device, GError **error)
{
FuDevice *parent = fu_device_get_parent(device);
GUsbDevice *usb_device = fu_usb_device_get_dev(FU_USB_DEVICE(parent));
guint16 release;
/* set the version if the release has been set */
release = g_usb_device_get_release(usb_device);
if (release != 0x0 &&
fu_device_get_version_format(device) == FWUPD_VERSION_FORMAT_UNKNOWN) {
g_autofree gchar *version = NULL;
version = fu_common_version_from_uint16(release, FWUPD_VERSION_FORMAT_BCD);
fu_device_set_version_format(device, FWUPD_VERSION_FORMAT_BCD);
fu_device_set_version(device, version);
}
/* add GUIDs in order of priority */
fu_device_add_instance_str(device, "PROTOCOL", "FIZZ_TUNNEL");
fu_device_add_instance_u16(device, "VID", g_usb_device_get_vid(usb_device));
fu_device_add_instance_u16(device, "PID", g_usb_device_get_pid(usb_device));
fu_device_add_instance_u16(device, "REV", release);
fu_device_build_instance_id_quirk(device, NULL, "STEELSERIES", "VID", "PROTOCOL", NULL);
fu_device_build_instance_id(device, NULL, "STEELSERIES", "VID", "PID", "PROTOCOL", NULL);
fu_device_build_instance_id(device,
NULL,
"STEELSERIES",
"VID",
"PID",
"REV",
"PROTOCOL",
NULL);
/* success */
return TRUE;
}
static gboolean
fu_steelseries_fizz_tunnel_setup(FuDevice *device, GError **error)
{
FuDevice *parent = fu_device_get_parent(device);
guint32 calculated_crc;
guint32 stored_crc;
guint8 fs = STEELSERIES_FIZZ_FILESYSTEM_MOUSE;
guint8 id = STEELSERIES_FIZZ_MOUSE_FILESYSTEM_BACKUP_APP_ID;
g_autofree gchar *version = NULL;
version = fu_steelseries_fizz_version(parent, TRUE, error);
if (version == NULL) {
g_prefix_error(error, "failed to get version: ");
return FALSE;
}
fu_device_set_version(device, version);
if (!fu_steelseries_fizz_file_crc32(parent,
TRUE,
fs,
id,
&calculated_crc,
&stored_crc,
error)) {
g_prefix_error(error,
"failed to get file CRC32 from FS 0x%02x ID 0x%02x: ",
fs,
id);
return FALSE;
}
if (calculated_crc != stored_crc) {
g_warning("%s: checksum mismatch, got 0x%08x, expected 0x%08x",
fu_device_get_name(device),
calculated_crc,
stored_crc);
}
/* success */
return TRUE;
}
static gboolean
fu_steelseries_fizz_tunnel_write_firmware(FuDevice *device,
FuFirmware *firmware,
FuProgress *progress,
FwupdInstallFlags flags,
GError **error)
{
FuDevice *parent = fu_device_get_parent(device);
guint8 fs = STEELSERIES_FIZZ_FILESYSTEM_MOUSE;
guint8 id = STEELSERIES_FIZZ_MOUSE_FILESYSTEM_BACKUP_APP_ID;
fu_progress_set_id(progress, G_STRLOC);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 100);
if (!fu_steelseries_fizz_write_file(parent,
TRUE,
fs,
id,
firmware,
fu_progress_get_child(progress),
flags,
error))
return FALSE;
fu_progress_step_done(progress);
/* success */
return TRUE;
}
static FuFirmware *
fu_steelseries_fizz_tunnel_read_firmware(FuDevice *device, FuProgress *progress, GError **error)
{
FuDevice *parent = fu_device_get_parent(device);
guint8 fs = STEELSERIES_FIZZ_FILESYSTEM_MOUSE;
guint8 id = STEELSERIES_FIZZ_MOUSE_FILESYSTEM_BACKUP_APP_ID;
g_autoptr(FuFirmware) firmware = NULL;
fu_progress_set_id(progress, G_STRLOC);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_READ, 100);
firmware = fu_steelseries_fizz_read_file(parent,
TRUE,
fs,
id,
fu_device_get_firmware_size_max(device),
fu_progress_get_child(progress),
error);
if (firmware == NULL)
return NULL;
fu_progress_step_done(progress);
/* success */
return g_steal_pointer(&firmware);
}
static void
fu_steelseries_fizz_tunnel_set_progress(FuDevice *self, FuProgress *progress)
{
fu_progress_set_id(progress, G_STRLOC);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 75); /* write */
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 25); /* attach */
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
}
static void
fu_steelseries_fizz_tunnel_class_init(FuSteelseriesFizzTunnelClass *klass)
{
FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
klass_device->attach = fu_steelseries_fizz_tunnel_attach;
klass_device->probe = fu_steelseries_fizz_tunnel_probe;
klass_device->setup = fu_steelseries_fizz_tunnel_setup;
klass_device->write_firmware = fu_steelseries_fizz_tunnel_write_firmware;
klass_device->read_firmware = fu_steelseries_fizz_tunnel_read_firmware;
klass_device->set_progress = fu_steelseries_fizz_tunnel_set_progress;
}
static void
fu_steelseries_fizz_tunnel_init(FuSteelseriesFizzTunnel *self)
{
fu_device_set_version_format(FU_DEVICE(self), FWUPD_VERSION_FORMAT_TRIPLET);
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE);
fu_device_add_internal_flag(FU_DEVICE(self), FU_DEVICE_INTERNAL_FLAG_USE_PARENT_FOR_OPEN);
fu_device_add_protocol(FU_DEVICE(self), "com.steelseries.fizz");
fu_device_set_logical_id(FU_DEVICE(self), "tunnel");
fu_device_set_install_duration(FU_DEVICE(self), 38); /* 38 s */
fu_device_set_remove_delay(FU_DEVICE(self), FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE); /* 10 s */
fu_device_set_firmware_gtype(FU_DEVICE(self), FU_TYPE_STEELSERIES_FIRMWARE);
}
FuSteelseriesFizzTunnel *
fu_steelseries_fizz_tunnel_new(FuSteelseriesFizz *parent)
{
return g_object_new(FU_TYPE_STEELSERIES_FIZZ_TUNNEL, "parent", FU_DEVICE(parent), NULL);
}

View File

@ -0,0 +1,21 @@
/*
* Copyright (C) 2022 Gaël PORTAY <gael.portay@collabora.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#pragma once
#include <fwupdplugin.h>
#include "fu-steelseries-fizz.h"
#define FU_TYPE_STEELSERIES_FIZZ_TUNNEL (fu_steelseries_fizz_tunnel_get_type())
G_DECLARE_FINAL_TYPE(FuSteelseriesFizzTunnel,
fu_steelseries_fizz_tunnel,
FU,
STEELSERIES_FIZZ_TUNNEL,
FuDevice)
FuSteelseriesFizzTunnel *
fu_steelseries_fizz_tunnel_new(FuSteelseriesFizz *parent);

View File

@ -7,43 +7,11 @@
#include "config.h"
#include "fu-steelseries-firmware.h"
#include "fu-steelseries-fizz-tunnel.h"
#include "fu-steelseries-fizz.h"
#define STEELSERIES_BUFFER_TRANSFER_SIZE 52
#define STEELSERIES_FIZZ_FILESYSTEM_RECEIVER 0x01U
#define STEELSERIES_FIZZ_FILESYSTEM_MOUSE 0x02U
#define STEELSERIES_FIZZ_RESET_MODE_NORMAL 0x00U
#define STEELSERIES_FIZZ_RESET_MODE_BOOTLOADER 0x01U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_MAIN_BOOT_ID 0x01U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_FSDATA_FILE_ID 0x02U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_FACTORY_SETTINGS_ID 0x03U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_MAIN_APP_ID 0x04U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_BACKUP_APP_ID 0x05U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_PROFILES_MOUSE_ID 0x06U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_PROFILES_LIGHTING_ID 0x0fU
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_PROFILES_DEVICE_ID 0x10U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_PROFILES_RESERVED_ID 0x11U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_RECOVERY_ID 0x0dU
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_FREE_SPACE_ID 0xf1U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_SOFT_DEVICE_ID 0x00U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_PROFILES_MOUSE_ID 0x06U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_MAIN_APP_ID 0x07U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_BACKUP_APP_ID 0x08U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_MSB_DATA_ID 0x09U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_FACTORY_SETTINGS_ID 0x0aU
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_FSDATA_FILE_ID 0x0bU
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_MAIN_BOOT_ID 0x0cU
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_RECOVERY_ID 0x0eU
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_PROFILES_LIGHTING_ID 0x0fU
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_PROFILES_DEVICE_ID 0x10U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_FDS_PAGES_ID 0x12U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_PROFILES_BLUETOOTH_ID 0x13U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_FREE_SPACE_ID 0xf0U
#define STEELSERIES_FIZZ_COMMAND_ERROR_SUCCESS 0
#define STEELSERIES_FIZZ_COMMAND_ERROR_FILE_NOT_FOUND 1
#define STEELSERIES_FIZZ_COMMAND_ERROR_FILE_TOO_SHORT 2
@ -51,6 +19,8 @@
#define STEELSERIES_FIZZ_COMMAND_ERROR_PERMISSION_DENIED 4
#define STEELSERIES_FIZZ_COMMAND_ERROR_OPERATION_NO_SUPPORTED 5
#define STEELSERIES_FIZZ_COMMAND_TUNNEL_BIT 1U << 6
#define STEELSERIES_FIZZ_COMMAND_OFFSET 0x00U
#define STEELSERIES_FIZZ_ERROR_OFFSET 0x01U
@ -195,13 +165,16 @@ fu_steelseries_device_command_and_check_error(FuDevice *device, guint8 *data, GE
return fu_steelseries_device_command_error_to_error(cmd, err, error);
}
static gchar *
fu_steelseries_fizz_version(FuDevice *device, GError **error)
gchar *
fu_steelseries_fizz_version(FuDevice *device, gboolean tunnel, GError **error)
{
guint8 data[STEELSERIES_BUFFER_CONTROL_SIZE] = {0};
const guint16 cmd = 0x90U;
guint16 cmd = 0x90U;
const guint8 mode = 0U; /* string */
if (tunnel)
cmd |= STEELSERIES_FIZZ_COMMAND_TUNNEL_BIT;
if (!fu_common_write_uint8_safe(data,
sizeof(data),
STEELSERIES_FIZZ_VERSION_COMMAND_OFFSET,
@ -227,8 +200,9 @@ fu_steelseries_fizz_version(FuDevice *device, GError **error)
return g_strndup((const gchar *)data, sizeof(data));
}
static gboolean
gboolean
fu_steelseries_fizz_write_access_file(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
const guint8 *buf,
@ -236,10 +210,13 @@ fu_steelseries_fizz_write_access_file(FuDevice *device,
FuProgress *progress,
GError **error)
{
const guint16 cmd = 0x03U;
guint16 cmd = 0x03U;
guint8 data[STEELSERIES_BUFFER_CONTROL_SIZE] = {0};
g_autoptr(GPtrArray) chunks = NULL;
if (tunnel)
cmd |= STEELSERIES_FIZZ_COMMAND_TUNNEL_BIT;
chunks = fu_chunk_array_new(buf, bufsz, 0x0, 0x0, STEELSERIES_BUFFER_TRANSFER_SIZE);
fu_progress_set_id(progress, G_STRLOC);
fu_progress_set_steps(progress, chunks->len);
@ -310,11 +287,18 @@ fu_steelseries_fizz_write_access_file(FuDevice *device,
return TRUE;
}
static gboolean
fu_steelseries_fizz_erase_file(FuDevice *device, guint8 fs, guint8 id, GError **error)
gboolean
fu_steelseries_fizz_erase_file(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
GError **error)
{
guint8 data[STEELSERIES_BUFFER_CONTROL_SIZE] = {0};
const guint16 cmd = 0x02U;
guint16 cmd = 0x02U;
if (tunnel)
cmd |= STEELSERIES_FIZZ_COMMAND_TUNNEL_BIT;
if (!fu_common_write_uint8_safe(data,
sizeof(data),
@ -348,11 +332,14 @@ fu_steelseries_fizz_erase_file(FuDevice *device, guint8 fs, guint8 id, GError **
return TRUE;
}
static gboolean
fu_steelseries_fizz_reset(FuDevice *device, guint8 mode, GError **error)
gboolean
fu_steelseries_fizz_reset(FuDevice *device, gboolean tunnel, guint8 mode, GError **error)
{
guint8 data[STEELSERIES_BUFFER_CONTROL_SIZE] = {0};
const guint16 cmd = 0x01U;
guint16 cmd = 0x01U;
if (tunnel)
cmd |= STEELSERIES_FIZZ_COMMAND_TUNNEL_BIT;
if (!fu_common_write_uint8_safe(data,
sizeof(data),
@ -377,8 +364,9 @@ fu_steelseries_fizz_reset(FuDevice *device, guint8 mode, GError **error)
return TRUE;
}
static gboolean
gboolean
fu_steelseries_fizz_file_crc32(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
guint32 *calculated_crc,
@ -386,7 +374,10 @@ fu_steelseries_fizz_file_crc32(FuDevice *device,
GError **error)
{
guint8 data[STEELSERIES_BUFFER_CONTROL_SIZE] = {0};
const guint16 cmd = 0x84U;
guint16 cmd = 0x84U;
if (tunnel)
cmd |= STEELSERIES_FIZZ_COMMAND_TUNNEL_BIT;
if (!fu_common_write_uint8_safe(data, sizeof(data), 0x00U, cmd, error))
return FALSE;
@ -424,8 +415,9 @@ fu_steelseries_fizz_file_crc32(FuDevice *device,
return TRUE;
}
static gboolean
gboolean
fu_steelseries_fizz_read_access_file(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
guint8 *buf,
@ -433,10 +425,13 @@ fu_steelseries_fizz_read_access_file(FuDevice *device,
FuProgress *progress,
GError **error)
{
const guint16 cmd = 0x83U;
guint16 cmd = 0x83U;
guint8 data[STEELSERIES_BUFFER_CONTROL_SIZE] = {0};
g_autoptr(GPtrArray) chunks = NULL;
if (tunnel)
cmd |= STEELSERIES_FIZZ_COMMAND_TUNNEL_BIT;
chunks = fu_chunk_array_mutable_new(buf, bufsz, 0x0, 0x0, STEELSERIES_BUFFER_TRANSFER_SIZE);
fu_progress_set_id(progress, G_STRLOC);
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
@ -512,7 +507,10 @@ fu_steelseries_fizz_attach(FuDevice *device, FuProgress *progress, GError **erro
{
g_autoptr(GError) error_local = NULL;
if (!fu_steelseries_fizz_reset(device, STEELSERIES_FIZZ_RESET_MODE_NORMAL, &error_local))
if (!fu_steelseries_fizz_reset(device,
FALSE,
STEELSERIES_FIZZ_RESET_MODE_NORMAL,
&error_local))
g_warning("failed to reset: %s", error_local->message);
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
@ -528,8 +526,13 @@ fu_steelseries_fizz_setup(FuDevice *device, GError **error)
guint32 stored_crc;
guint8 fs = STEELSERIES_FIZZ_FILESYSTEM_MOUSE;
guint8 id = STEELSERIES_FIZZ_MOUSE_FILESYSTEM_BACKUP_APP_ID;
g_autoptr(GError) error_local = NULL;
g_autofree gchar *version = NULL;
/* in bootloader mode */
if (fu_device_has_private_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER))
return TRUE;
/* FuUsbDevice->setup */
if (!FU_DEVICE_CLASS(fu_steelseries_fizz_parent_class)->setup(device, error))
return FALSE;
@ -538,7 +541,18 @@ fu_steelseries_fizz_setup(FuDevice *device, GError **error)
if (fu_device_has_private_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER))
return TRUE;
version = fu_steelseries_fizz_version(device, error);
/* it is a USB receiver */
if (fu_device_has_private_flag(device, FU_STEELSERIES_DEVICE_FLAG_IS_RECEIVER)) {
g_autoptr(FuSteelseriesFizzTunnel) mouse_device =
fu_steelseries_fizz_tunnel_new(FU_STEELSERIES_FIZZ(device));
fu_device_add_child(device, FU_DEVICE(mouse_device));
fs = STEELSERIES_FIZZ_FILESYSTEM_RECEIVER;
id = STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_BACKUP_APP_ID;
}
version = fu_steelseries_fizz_version(device, FALSE, error);
if (version == NULL) {
g_prefix_error(error, "failed to get version: ");
return FALSE;
@ -551,7 +565,13 @@ fu_steelseries_fizz_setup(FuDevice *device, GError **error)
id = STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_BACKUP_APP_ID;
}
if (!fu_steelseries_fizz_file_crc32(device, fs, id, &calculated_crc, &stored_crc, error)) {
if (!fu_steelseries_fizz_file_crc32(device,
FALSE,
fs,
id,
&calculated_crc,
&stored_crc,
error)) {
g_prefix_error(error,
"failed to get file CRC32 from FS 0x%02x ID 0x%02x: ",
fs,
@ -569,8 +589,9 @@ fu_steelseries_fizz_setup(FuDevice *device, GError **error)
return TRUE;
}
static gboolean
gboolean
fu_steelseries_fizz_write_file(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
FuFirmware *firmware,
@ -585,9 +606,15 @@ fu_steelseries_fizz_write_file(FuDevice *device,
g_autoptr(GBytes) blob = NULL;
fu_progress_set_id(progress, G_STRLOC);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 38);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 60);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 2);
if (tunnel) {
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 13);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 87);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 1);
} else {
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 38);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 60);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 2);
}
blob = fu_firmware_get_bytes(firmware, error);
if (blob == NULL)
@ -597,12 +624,13 @@ fu_steelseries_fizz_write_file(FuDevice *device,
return FALSE;
if (g_getenv("FWUPD_STEELSERIES_FIZZ_VERBOSE") != NULL)
fu_common_dump_raw(G_LOG_DOMAIN, "File", buf, bufsz);
if (!fu_steelseries_fizz_erase_file(device, fs, id, error)) {
if (!fu_steelseries_fizz_erase_file(device, tunnel, fs, id, error)) {
g_prefix_error(error, "failed to erase file 0x%02x:0x%02x: ", fs, id);
return FALSE;
}
fu_progress_step_done(progress);
if (!fu_steelseries_fizz_write_access_file(device,
tunnel,
fs,
id,
buf,
@ -614,7 +642,13 @@ fu_steelseries_fizz_write_file(FuDevice *device,
}
fu_progress_step_done(progress);
if (!fu_steelseries_fizz_file_crc32(device, fs, id, &calculated_crc, &stored_crc, error)) {
if (!fu_steelseries_fizz_file_crc32(device,
tunnel,
fs,
id,
&calculated_crc,
&stored_crc,
error)) {
g_prefix_error(error,
"failed to get file CRC32 from FS 0x%02x ID 0x%02x: ",
fs,
@ -652,6 +686,7 @@ fu_steelseries_fizz_write_firmware(FuDevice *device,
fu_progress_set_steps(progress, 1);
if (!fu_steelseries_fizz_write_file(device,
FALSE,
fs,
id,
firmware,
@ -665,15 +700,52 @@ fu_steelseries_fizz_write_firmware(FuDevice *device,
return TRUE;
}
FuFirmware *
fu_steelseries_fizz_read_file(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
gsize size,
FuProgress *progress,
GError **error)
{
g_autoptr(FuFirmware) firmware = fu_steelseries_firmware_new();
g_autoptr(GBytes) blob = NULL;
g_autofree guint8 *buf = NULL;
fu_progress_set_id(progress, G_STRLOC);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_READ, 100);
buf = g_malloc0(size);
if (!fu_steelseries_fizz_read_access_file(device,
tunnel,
fs,
id,
buf,
size,
fu_progress_get_child(progress),
error)) {
g_prefix_error(error, "failed to read FS 0x%02x ID 0x%02x: ", fs, id);
return NULL;
}
fu_progress_step_done(progress);
if (g_getenv("FWUPD_STEELSERIES_FIZZ_VERBOSE") != NULL)
fu_common_dump_raw(G_LOG_DOMAIN, "Firmware", buf, size);
blob = g_bytes_new_take(g_steal_pointer(&buf), size);
if (!fu_firmware_parse(firmware, blob, FWUPD_INSTALL_FLAG_NONE, error))
return NULL;
/* success */
return g_steal_pointer(&firmware);
}
static FuFirmware *
fu_steelseries_fizz_read_firmware(FuDevice *device, FuProgress *progress, GError **error)
{
guint8 fs = STEELSERIES_FIZZ_FILESYSTEM_MOUSE;
guint8 id = STEELSERIES_FIZZ_MOUSE_FILESYSTEM_BACKUP_APP_ID;
gsize bufsz = 0x27000;
g_autoptr(FuFirmware) firmware = fu_steelseries_firmware_new();
g_autoptr(GBytes) blob = NULL;
g_autofree guint8 *buf = NULL;
g_autoptr(FuFirmware) firmware = NULL;
fu_progress_set_id(progress, G_STRLOC);
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_READ, 100);
@ -682,26 +754,19 @@ fu_steelseries_fizz_read_firmware(FuDevice *device, FuProgress *progress, GError
if (fu_device_has_private_flag(device, FU_STEELSERIES_DEVICE_FLAG_IS_RECEIVER)) {
fs = STEELSERIES_FIZZ_FILESYSTEM_RECEIVER;
id = STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_BACKUP_APP_ID;
bufsz = 0x23000;
}
buf = g_malloc0(bufsz);
if (!fu_steelseries_fizz_read_access_file(device,
fs,
id,
buf,
bufsz,
fu_progress_get_child(progress),
error))
firmware = fu_steelseries_fizz_read_file(device,
FALSE,
fs,
id,
fu_device_get_firmware_size_max(device),
fu_progress_get_child(progress),
error);
if (firmware == NULL)
return NULL;
fu_progress_step_done(progress);
if (g_getenv("FWUPD_STEELSERIES_FIZZ_VERBOSE") != NULL)
fu_common_dump_raw(G_LOG_DOMAIN, "Firmware", buf, bufsz);
blob = g_bytes_new_take(g_steal_pointer(&buf), bufsz);
if (!fu_firmware_parse(firmware, blob, FWUPD_INSTALL_FLAG_NONE, error))
return NULL;
/* success */
return g_steal_pointer(&firmware);
}

View File

@ -16,3 +16,93 @@ G_DECLARE_FINAL_TYPE(FuSteelseriesFizz,
FU,
STEELSERIES_FIZZ,
FuSteelseriesDevice)
FuSteelseriesFizz *
fu_steelseries_fizz_new(FuDevice *self);
#define STEELSERIES_FIZZ_FILESYSTEM_RECEIVER 0x01U
#define STEELSERIES_FIZZ_FILESYSTEM_MOUSE 0x02U
#define STEELSERIES_FIZZ_RESET_MODE_NORMAL 0x00U
#define STEELSERIES_FIZZ_RESET_MODE_BOOTLOADER 0x01U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_MAIN_BOOT_ID 0x01U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_FSDATA_FILE_ID 0x02U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_FACTORY_SETTINGS_ID 0x03U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_MAIN_APP_ID 0x04U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_BACKUP_APP_ID 0x05U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_PROFILES_MOUSE_ID 0x06U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_PROFILES_LIGHTING_ID 0x0fU
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_PROFILES_DEVICE_ID 0x10U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_PROFILES_RESERVED_ID 0x11U
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_RECOVERY_ID 0x0dU
#define STEELSERIES_FIZZ_RECEIVER_FILESYSTEM_FREE_SPACE_ID 0xf1U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_SOFT_DEVICE_ID 0x00U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_PROFILES_MOUSE_ID 0x06U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_MAIN_APP_ID 0x07U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_BACKUP_APP_ID 0x08U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_MSB_DATA_ID 0x09U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_FACTORY_SETTINGS_ID 0x0aU
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_FSDATA_FILE_ID 0x0bU
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_MAIN_BOOT_ID 0x0cU
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_RECOVERY_ID 0x0eU
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_PROFILES_LIGHTING_ID 0x0fU
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_PROFILES_DEVICE_ID 0x10U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_FDS_PAGES_ID 0x12U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_PROFILES_BLUETOOTH_ID 0x13U
#define STEELSERIES_FIZZ_MOUSE_FILESYSTEM_FREE_SPACE_ID 0xf0U
gchar *
fu_steelseries_fizz_version(FuDevice *device, gboolean tunnel, GError **error);
gboolean
fu_steelseries_fizz_read_access_file(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
guint8 *buf,
gsize bufsz,
FuProgress *progress,
GError **error);
gboolean
fu_steelseries_fizz_write_access_file(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
const guint8 *buf,
gsize bufsz,
FuProgress *progress,
GError **error);
gboolean
fu_steelseries_fizz_erase_file(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
GError **error);
gboolean
fu_steelseries_fizz_reset(FuDevice *device, gboolean tunnel, guint8 mode, GError **error);
gboolean
fu_steelseries_fizz_file_crc32(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
guint32 *calculated_crc,
guint32 *stored_crc,
GError **error);
FuFirmware *
fu_steelseries_fizz_read_file(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
gsize size,
FuProgress *progress,
GError **error);
gboolean
fu_steelseries_fizz_write_file(FuDevice *device,
gboolean tunnel,
guint8 fs,
guint8 id,
FuFirmware *firmware,
FuProgress *progress,
FwupdInstallFlags flags,
GError **error);

View File

@ -13,6 +13,7 @@ shared_module('fu_plugin_steelseries',
'fu-steelseries-mouse.c',
'fu-steelseries-firmware.c',
'fu-steelseries-fizz.c',
'fu-steelseries-fizz-tunnel.c',
'fu-steelseries-gamepad.c',
'fu-steelseries-sonic.c',
],

View File

@ -29,6 +29,13 @@ Icon = usb-receiver
FirmwareSize = 0x23000
Flags = is-bootloader,is-receiver,~usable-during-update
[STEELSERIES\VID_1038&PID_1838&PROTOCOL_FIZZ_TUNNEL]
Plugin = steelseries
GType = FuSteelseriesFizzTunnel
Name = Aerox 3 Wireless Mouse via USB Receiver
Icon = input-mouse
FirmwareSize = 0x27000
[USB\VID_1038&PID_183A]
Plugin = steelseries
GType = FuSteelseriesFizz