diff --git a/Controllers/SteelSeriesController/SteelSeriesAerox3WirelessController/SteelSeriesAerox3WirelessController.cpp b/Controllers/SteelSeriesController/SteelSeriesAerox3WirelessController/SteelSeriesAerox3WirelessController.cpp new file mode 100644 index 00000000..3df4efa4 --- /dev/null +++ b/Controllers/SteelSeriesController/SteelSeriesAerox3WirelessController/SteelSeriesAerox3WirelessController.cpp @@ -0,0 +1,152 @@ +/*---------------------------------------------------------*\ +| SteelSeriesAerox3WirelessController.cpp | +| | +| Driver for SteelSeries Aerox 3 Wireless | +| | +| Ensar S (esensar) 09 Sep 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include "SteelSeriesAerox3WirelessController.h" +#include "LogManager.h" +#include "SteelSeriesGeneric.h" + +SteelSeriesAerox3WirelessController::SteelSeriesAerox3WirelessController(hid_device* dev_handle, steelseries_type proto_type, const char* path) + : SteelSeriesMouseController(dev_handle, proto_type, path) +{ + SendInit(); +} + +SteelSeriesAerox3WirelessController::~SteelSeriesAerox3WirelessController() +{ + hid_close(dev); +} + +void SteelSeriesAerox3WirelessController::SendInit() +{ + /*-----------------------------------------------------------------*\ + | This sets sensitivity and allows software mode?? max 5 uint8 | + | buffer[2] = Count eg. 0 thru 5 | + | buffer[4] to [8] = dpi / 50 range = 0x04 - 0xC7 eg. 400 = 0x08 | + \*-----------------------------------------------------------------*/ + uint8_t buffer[STEELSERIES_AEROX3_PACKET_SIZE] = { 0x00, 0x2D }; + + hid_send_feature_report(dev, buffer, STEELSERIES_AEROX3_PACKET_SIZE); +} + +std::string SteelSeriesAerox3WirelessController::GetFirmwareVersion() +{ + uint8_t result = 0; + const uint8_t CMD = 0x90; + const uint8_t sz = 16; + char version[sz + 1]; + + uint8_t buffer[STEELSERIES_AEROX3_PACKET_SIZE] = { 0x00, CMD, 0x00 }; + + hid_send_feature_report(dev, buffer, STEELSERIES_AEROX3_PACKET_SIZE); + do + { + result = hid_read_timeout(dev, buffer, STEELSERIES_AEROX3_PACKET_SIZE, STEELSERIES_AEROX3_TIMEOUT); + LOG_DEBUG("[%s] Reading version buffer: Bytes Read %d Buffer %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", (proto == AEROX_3_WIRELESS) ? STEELSERIES_AEROX3_WIRELESS_NAME : STEELSERIES_AEROX3_WIRELESS_WIRED_NAME, result, + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10]); + } while(result > 0 && buffer[0] != CMD); + + if(buffer[0] == CMD) + { + /*-----------------------------------------------------------------*\ + | Read the version from the second character | + \*-----------------------------------------------------------------*/ + memcpy(version, &buffer[1], sz); + version[sz] = 0; + std::string tmp = std::string(version); + LOG_DEBUG("[%s] Version: %s as string %s", (proto == AEROX_3_WIRELESS) ? STEELSERIES_AEROX3_WIRELESS_NAME : STEELSERIES_AEROX3_WIRELESS_WIRED_NAME, version, tmp.c_str()); + + return tmp; + } + else + { + LOG_DEBUG("[%s] Unable to get version: giving up!", (proto == AEROX_3_WIRELESS) ? STEELSERIES_AEROX3_WIRELESS_NAME : STEELSERIES_AEROX3_WIRELESS_WIRED_NAME); + return ""; + } +} + +steelseries_mouse SteelSeriesAerox3WirelessController::GetMouse() +{ + return aerox_3_wireless; +} + +void SteelSeriesAerox3WirelessController::SetLightEffectAll(uint8_t effect) +{ + if(effect == 0x05) + { + uint8_t buffer[STEELSERIES_AEROX3_PACKET_SIZE] = { 0x00, 0x22, 0xFF }; + + WriteBuffer(buffer); + } +} + +void SteelSeriesAerox3WirelessController::SetColor + ( + unsigned char zone_id, + unsigned char red, + unsigned char green, + unsigned char blue, + unsigned char brightness + ) +{ + uint8_t buffer[STEELSERIES_AEROX3_PACKET_SIZE] = { 0x00, 0x21, 0x01 }; + + buffer[0x03] = zone_id; + uint8_t offset = 0x04; + + buffer[offset] = red; + buffer[offset + 1] = green; + buffer[offset + 2] = blue; + + WriteBuffer(buffer); + + // Supports only 10 steps of brightness + brightness = (uint8_t)(brightness / 10); + + if(brightness != current_brightness) + { + SetBrightness(brightness); + current_brightness = brightness; + } +} + +void SteelSeriesAerox3WirelessController::SetBrightness(uint8_t brightness) +{ + uint8_t buffer[STEELSERIES_AEROX3_PACKET_SIZE] = { 0x00, 0x23, brightness }; + + WriteBuffer(buffer); +} + +void SteelSeriesAerox3WirelessController::Save() +{ + /*---------------------------------------------------------------------------------*\ + | Save packet was not confirmed as working but packet is verified as correct. | + | https://github.com/flozz/rivalcfg/blob/master/rivalcfg/devices/aerox3.py#L141 | + \*---------------------------------------------------------------------------------*/ + uint8_t buffer2[STEELSERIES_AEROX3_PACKET_SIZE] = { 0x00, 0x11, 0x00 }; + + WriteBuffer(buffer2); +} + +void SteelSeriesAerox3WirelessController::WriteBuffer(uint8_t* buffer) +{ + if(proto == AEROX_3_WIRELESS) + { + buffer[1] |= STEELSERIES_AEROX3_WIRELESS_FLAG; + } + + hid_write(dev, buffer, STEELSERIES_AEROX3_PACKET_SIZE); + + if(proto == AEROX_3_WIRELESS) + { + // Readback required in wireless mode + hid_read_timeout(dev, buffer, STEELSERIES_AEROX3_PACKET_SIZE, STEELSERIES_AEROX3_TIMEOUT); + } +} diff --git a/Controllers/SteelSeriesController/SteelSeriesAerox3WirelessController/SteelSeriesAerox3WirelessController.h b/Controllers/SteelSeriesController/SteelSeriesAerox3WirelessController/SteelSeriesAerox3WirelessController.h new file mode 100644 index 00000000..3a681713 --- /dev/null +++ b/Controllers/SteelSeriesController/SteelSeriesAerox3WirelessController/SteelSeriesAerox3WirelessController.h @@ -0,0 +1,61 @@ +/*---------------------------------------------------------*\ +| SteelSeriesAerox3WirelessController.h | +| | +| Driver for SteelSeries Aerox 3 Wireless | +| | +| Ensar S (esensar) 09 Sep 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include +#include +#include "RGBController.h" +#include "SteelSeriesGeneric.h" +#include "SteelSeriesMouseController.h" + +#define STEELSERIES_AEROX3_WIRELESS_NAME "SteelSeries Aerox 3 Wireless (2.4 GHz wireless mode)" +#define STEELSERIES_AEROX3_WIRELESS_WIRED_NAME "SteelSeries Aerox 3 Wireless (wired mode)" +#define STEELSERIES_AEROX3_PACKET_SIZE 64 +#define STEELSERIES_AEROX3_TIMEOUT 250 +#define STEELSERIES_AEROX3_WIRELESS_FLAG 0b01000000 + +static const steelseries_mouse aerox_3_wireless = +{ + { 0x04, 0x05 }, + { + {"Front", 0 }, + {"Middle", 1 }, + {"Rear", 2 }, + } +}; + +class SteelSeriesAerox3WirelessController: public SteelSeriesMouseController +{ +public: + SteelSeriesAerox3WirelessController(hid_device* dev_handle, steelseries_type proto_type, const char* path); + ~SteelSeriesAerox3WirelessController(); + + std::string GetFirmwareVersion() override; + steelseries_mouse GetMouse() override; + + void Save() override; + void SetLightEffectAll(uint8_t effect) override; + void SetColor + ( + unsigned char zone_id, + unsigned char red, + unsigned char green, + unsigned char blue, + unsigned char brightness + ) override; +private: + void SendInit(); + void WriteBuffer(uint8_t* buffer); + void SetBrightness(uint8_t brightness); + uint8_t current_brightness; +}; diff --git a/Controllers/SteelSeriesController/SteelSeriesControllerDetect.cpp b/Controllers/SteelSeriesController/SteelSeriesControllerDetect.cpp index d60f6ff1..0c6445d3 100644 --- a/Controllers/SteelSeriesController/SteelSeriesControllerDetect.cpp +++ b/Controllers/SteelSeriesController/SteelSeriesControllerDetect.cpp @@ -11,6 +11,7 @@ #include "Detector.h" #include "RGBController.h" #include "SteelSeriesGeneric.h" +#include "SteelSeriesAerox3WirelessController.h" #include "SteelSeriesAerox5Controller.h" #include "SteelSeriesAerox9Controller.h" #include "SteelSeriesArctis5Controller.h" @@ -43,6 +44,8 @@ | Mouse product IDs | \*-----------------------------------------------------*/ #define STEELSERIES_AEROX_3_PID 0x1836 +#define STEELSERIES_AEROX_3_WIRELESS_PID 0x1838 +#define STEELSERIES_AEROX_3_WIRELESS_WIRED_PID 0x183A #define STEELSERIES_AEROX_5_PID 0x1850 #define STEELSERIES_AEROX_9_PID 0x185A #define STEELSERIES_RIVAL_100_PID 0x1702 @@ -118,6 +121,30 @@ void DetectSteelSeriesAerox3(hid_device_info* info, const std::string& name) } } +void DetectSteelSeriesAerox3Wireless(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + if(dev) + { + SteelSeriesAerox3WirelessController* controller = new SteelSeriesAerox3WirelessController(dev, AEROX_3_WIRELESS, info->path); + RGBController_SteelSeriesRival3* rgb_controller = new RGBController_SteelSeriesRival3(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +void DetectSteelSeriesAerox3WirelessWired(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + if(dev) + { + SteelSeriesAerox3WirelessController* controller = new SteelSeriesAerox3WirelessController(dev, AEROX_3_WIRELESS_WIRED, info->path); + RGBController_SteelSeriesRival3* rgb_controller = new RGBController_SteelSeriesRival3(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + void DetectSteelSeriesAerox5(hid_device_info* info, const std::string& name) { hid_device* dev = hid_open_path(info->path); @@ -328,6 +355,8 @@ void DetectSteelSeriesArctis5(hid_device_info* info, const std::string& name) /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------*\ | Mice | \*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +REGISTER_HID_DETECTOR_IPU("SteelSeries Aerox 3 Wireless", DetectSteelSeriesAerox3Wireless, STEELSERIES_VID, STEELSERIES_AEROX_3_WIRELESS_PID, 3, 0xFFC0, 1 ); +REGISTER_HID_DETECTOR_IPU("SteelSeries Aerox 3 Wireless Wired", DetectSteelSeriesAerox3WirelessWired, STEELSERIES_VID, STEELSERIES_AEROX_3_WIRELESS_WIRED_PID, 3, 0xFFC0, 1 ); REGISTER_HID_DETECTOR_IPU("SteelSeries Aerox 3 Wired", DetectSteelSeriesAerox3, STEELSERIES_VID, STEELSERIES_AEROX_3_PID, 3, 0xFFC0, 1 ); REGISTER_HID_DETECTOR_IPU("SteelSeries Aerox 5 Wired", DetectSteelSeriesAerox5, STEELSERIES_VID, STEELSERIES_AEROX_5_PID, 3, 0xFFC0, 1 ); REGISTER_HID_DETECTOR_IPU("SteelSeries Aerox 9 Wired", DetectSteelSeriesAerox9, STEELSERIES_VID, STEELSERIES_AEROX_9_PID, 3, 0xFFC0, 1 ); diff --git a/Controllers/SteelSeriesController/SteelSeriesGeneric.h b/Controllers/SteelSeriesController/SteelSeriesGeneric.h index 92d17455..94a81573 100644 --- a/Controllers/SteelSeriesController/SteelSeriesGeneric.h +++ b/Controllers/SteelSeriesController/SteelSeriesGeneric.h @@ -19,19 +19,20 @@ * for every possible device. */ typedef enum { - RIVAL_100 = 0x00, - RIVAL_300 = 0x01, - RIVAL_650 = 0x02, - SIBERIA_350 = 0x03, - APEX = 0x04, - APEX_M = 0x05, - APEX_OLD = 0x06, - SENSEI = 0x07, - RIVAL_600 = 0x08, - RIVAL_3 = 0x09, - APEX_TZONE = 0x0A, - RIVAL_700 = 0x0B, - AEROX_3 = 0x0C, - APEX_8ZONE = 0x0D, + RIVAL_100 = 0x00, + RIVAL_300 = 0x01, + RIVAL_650 = 0x02, + SIBERIA_350 = 0x03, + APEX = 0x04, + APEX_M = 0x05, + APEX_OLD = 0x06, + SENSEI = 0x07, + RIVAL_600 = 0x08, + RIVAL_3 = 0x09, + APEX_TZONE = 0x0A, + RIVAL_700 = 0x0B, + AEROX_3 = 0x0C, + APEX_8ZONE = 0x0D, + AEROX_3_WIRELESS = 0x0E, + AEROX_3_WIRELESS_WIRED = 0x0F, } steelseries_type; -