mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-06 18:11:33 +00:00
steelseries: fizz: Add support for 2.4G connection
This commit is contained in:
parent
c5defa89e9
commit
714983d82d
@ -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"
|
||||
]
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
212
plugins/steelseries/fu-steelseries-fizz-tunnel.c
Normal file
212
plugins/steelseries/fu-steelseries-fizz-tunnel.c
Normal 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);
|
||||
}
|
21
plugins/steelseries/fu-steelseries-fizz-tunnel.h
Normal file
21
plugins/steelseries/fu-steelseries-fizz-tunnel.h
Normal 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);
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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',
|
||||
],
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user