link system hub fixups

This commit is contained in:
Nikola Jurkovic 2025-08-11 15:08:54 +00:00 committed by Adam Honse
parent ca554d9ef6
commit 12f90a67f9
4 changed files with 51 additions and 22 deletions

1
.gitignore vendored
View file

@ -28,6 +28,7 @@ Build/
.qmake.stash .qmake.stash
.vscode .vscode
.vs .vs
.idea
# Generic Files # Generic Files
.DS_Store .DS_Store

View file

@ -5,6 +5,7 @@
| | | |
| Aiden Vigue (acvigue) 02 Mar 2025 | | Aiden Vigue (acvigue) 02 Mar 2025 |
| Adam Honse <calcprogrammer1@gmail.com> 01 Aug 2025 | | Adam Honse <calcprogrammer1@gmail.com> 01 Aug 2025 |
| Nikola Jurkovic (jurkovic.nikola) 11 Aug 2025 |
| | | |
| This file is part of the OpenRGB project | | This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only | | SPDX-License-Identifier: GPL-2.0-only |
@ -27,31 +28,44 @@ CorsairICueLinkController::CorsairICueLinkController(hid_device* dev_handle, con
guard_manager_ptr = new DeviceGuardManager(new CorsairDeviceGuard()); guard_manager_ptr = new DeviceGuardManager(new CorsairDeviceGuard());
InitHub(); GetControllerFirmware(); // Firmware
SetControllerSoftwareMode(); // Software mode
GetControllerDevices(); // Get connected devices
} }
CorsairICueLinkController::~CorsairICueLinkController() CorsairICueLinkController::~CorsairICueLinkController()
{ {
SetControllerHardwareMode(); // Release device back to hardware mode
hid_close(dev); hid_close(dev);
delete guard_manager_ptr; delete guard_manager_ptr;
} }
void CorsairICueLinkController::InitHub() void CorsairICueLinkController::SetControllerSoftwareMode()
{
SendCommand(CORSAIR_ICUE_LINK_CMD_SOFTWARE_MODE, { }, { });
}
void CorsairICueLinkController::SetControllerHardwareMode()
{
SendCommand(CORSAIR_ICUE_LINK_CMD_HARDWARE_MODE, { }, { });
}
void CorsairICueLinkController::GetControllerFirmware()
{ {
/*-----------------------------------------------------*\ /*-----------------------------------------------------*\
| Get the firmware version | | Get the firmware version |
\*-----------------------------------------------------*/ \*-----------------------------------------------------*/
std::vector<unsigned char> firmware_data = SendCommand(CORSAIR_ICUE_LINK_CMD_GET_FIRMWARE, { }, { }); std::vector<unsigned char> firmware_data = SendCommand(CORSAIR_ICUE_LINK_CMD_GET_FIRMWARE, { }, { });
version[0] = firmware_data[0]; version =
version[1] = firmware_data[1]; {
version[2] = firmware_data[2]; firmware_data[4],
firmware_data[5],
/*-----------------------------------------------------*\ static_cast<unsigned short>(firmware_data[6] | (firmware_data[7] << 8))
| Command the hub to enter software mode | };
\*-----------------------------------------------------*/ }
SendCommand(CORSAIR_ICUE_LINK_CMD_SOFTWARE_MODE, { }, { });
void CorsairICueLinkController::GetControllerDevices()
{
/*-----------------------------------------------------*\ /*-----------------------------------------------------*\
| Get the endpoints data | | Get the endpoints data |
\*-----------------------------------------------------*/ \*-----------------------------------------------------*/
@ -93,6 +107,13 @@ void CorsairICueLinkController::InitHub()
continue; continue;
} }
// Dont process internal device due to duplication
if (device->internal == true)
{
pos += 8 + device_id_length;
continue;
}
if(device->led_channels == 0) if(device->led_channels == 0)
{ {
LOG_WARNING("[CorsairICueLinkController] Device type %s has 0 LEDs, please open issue", device->display_name.c_str()); LOG_WARNING("[CorsairICueLinkController] Device type %s has 0 LEDs, please open issue", device->display_name.c_str());
@ -105,7 +126,7 @@ void CorsairICueLinkController::InitHub()
| device's serial number string | | device's serial number string |
\*-------------------------------------------------*/ \*-------------------------------------------------*/
std::string endpoint_id_str(endpoint_id.begin(), endpoint_id.end()); std::string endpoint_id_str(endpoint_id.begin(), endpoint_id.end());
serial += "\r\n" + endpoint_id_str; serial += "\r\n" + endpoint_id_str; // Why do we need endpoint IDs when colors are managed via endpoint channel IDs ?
/*-------------------------------------------------*\ /*-------------------------------------------------*\
| Add endpoint device to list | | Add endpoint device to list |
@ -118,7 +139,9 @@ void CorsairICueLinkController::InitHub()
std::string CorsairICueLinkController::GetFirmwareString() std::string CorsairICueLinkController::GetFirmwareString()
{ {
return("v" + std::to_string(version[0]) + "." + std::to_string(version[1]) + "." + std::to_string(version[2])); char buffer[20];
std::snprintf(buffer, sizeof(buffer), "v%d.%d.%d", version[0], version[1], version[2]);
return std::string(buffer);
} }
std::string CorsairICueLinkController::GetNameString() std::string CorsairICueLinkController::GetNameString()

View file

@ -5,6 +5,7 @@
| | | |
| Aiden Vigue (acvigue) 02 Mar 2025 | | Aiden Vigue (acvigue) 02 Mar 2025 |
| Adam Honse <calcprogrammer1@gmail.com> 01 Aug 2025 | | Adam Honse <calcprogrammer1@gmail.com> 01 Aug 2025 |
| Nikola Jurkovic 11 Aug 2025 |
| | | |
| This file is part of the OpenRGB project | | This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only | | SPDX-License-Identifier: GPL-2.0-only |
@ -40,19 +41,20 @@ private:
std::string name; std::string name;
std::string location; std::string location;
std::string serial; std::string serial;
std::vector<unsigned short> version;
unsigned short int version[3] = { 0, 0, 0 };
DeviceGuardManager* guard_manager_ptr; DeviceGuardManager* guard_manager_ptr;
std::vector<const CorsairICueLinkDevice *> endpoints; std::vector<const CorsairICueLinkDevice *> endpoints;
void InitHub(); void GetControllerFirmware();
void GetControllerDevices();
void SetControllerSoftwareMode();
void SetControllerHardwareMode();
std::vector<std::vector<unsigned char>> ProcessMultiChunkPacket(const std::vector<unsigned char>& data, size_t max_chunk_size); std::vector<std::vector<unsigned char>> ProcessMultiChunkPacket(const std::vector<unsigned char>& data, size_t max_chunk_size);
std::vector<unsigned char> SendCommand(std::vector<unsigned char> command, std::vector<unsigned char> data, std::vector<unsigned char> waitForDataType); std::vector<unsigned char> SendCommand(std::vector<unsigned char> command, std::vector<unsigned char> data, std::vector<unsigned char> waitForDataType);
std::vector<unsigned char> Read(std::vector<unsigned char> endpoint, std::vector<unsigned char> data_type); std::vector<unsigned char> Read(std::vector<unsigned char> endpoint, std::vector<unsigned char> data_type);
void Write(std::vector<unsigned char> endpoint, std::vector<unsigned char> data_type, std::vector<unsigned char> data, CORSAIR_ICUE_ENDPOINT_TYPE endpoint_type); void Write(std::vector<unsigned char> endpoint, std::vector<unsigned char> data_type, std::vector<unsigned char> data, CORSAIR_ICUE_ENDPOINT_TYPE endpoint_type);
}; };

View file

@ -4,6 +4,7 @@
| Driver for Corsair iCue Link System Hub | | Driver for Corsair iCue Link System Hub |
| | | |
| Aiden Vigue (acvigue) 02 Mar 2025 | | Aiden Vigue (acvigue) 02 Mar 2025 |
| Nikola Jurkovic (jurkovic.nikola) 11 Aug 2025 |
| | | |
| This file is part of the OpenRGB project | | This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only | | SPDX-License-Identifier: GPL-2.0-only |
@ -19,13 +20,14 @@ typedef struct CorsairICueLinkDevice
unsigned char model = 0x00; unsigned char model = 0x00;
std::string display_name = "Unknown"; std::string display_name = "Unknown";
unsigned char led_channels = 0; unsigned char led_channels = 0;
bool internal = false;
} CorsairICueLinkDevice; } CorsairICueLinkDevice;
static const CorsairICueLinkDevice known_devices[] = static const CorsairICueLinkDevice known_devices[] =
{ {
{ 0x05, 0x02, "iCUE LINK 5000T RGB", 160 }, { 0x05, 0x02, "iCUE LINK 5000T RGB", 160 },
{ 0x05, 0x01, "iCUE LINK 9000D RGB AIRFLOW", 22 }, { 0x05, 0x01, "iCUE LINK 9000D RGB AIRFLOW", 22 },
{ 0x05, 0x00, "iCUE LINK ADAPTER", 16 }, { 0x05, 0x00, "iCUE LINK ADAPTER", 0 },
{ 0x06, 0x00, "iCUE LINK COOLER PUMP LCD", 24 }, { 0x06, 0x00, "iCUE LINK COOLER PUMP LCD", 24 },
{ 0x11, 0x00, "iCUE LINK TITAN 240", 20 }, { 0x11, 0x00, "iCUE LINK TITAN 240", 20 },
{ 0x11, 0x04, "iCUE LINK TITAN 240", 20 }, { 0x11, 0x04, "iCUE LINK TITAN 240", 20 },
@ -47,9 +49,10 @@ static const CorsairICueLinkDevice known_devices[] =
{ 0x04, 0x00, "iCUE LINK RX MAX", 0 }, { 0x04, 0x00, "iCUE LINK RX MAX", 0 },
{ 0x0F, 0x00, "iCUE LINK RX RGB", 8 }, { 0x0F, 0x00, "iCUE LINK RX RGB", 8 },
{ 0x03, 0x00, "iCUE LINK RX RGB MAX", 8 }, { 0x03, 0x00, "iCUE LINK RX RGB MAX", 8 },
{ 0x09, 0x00, "iCUE LINK XC7 ELITE", 0 }, { 0x09, 0x00, "iCUE LINK XC7 ELITE", 24 },
{ 0x0C, 0x00, "iCUE LINK XD5 ELITE", 22 }, { 0x0C, 0x00, "iCUE LINK XD5 ELITE", 22 },
{ 0x0E, 0x00, "iCUE LINK XD5 ELITE LCD", 22 }, { 0x0E, 0x00, "iCUE LINK XD5 ELITE LCD", 22, true },
{ 0x19, 0x00, "iCUE LINK XD6 ELITE", 22 },
{ 0x0A, 0x00, "iCUE LINK XG3 HYBRID", 0 }, { 0x0A, 0x00, "iCUE LINK XG3 HYBRID", 0 },
{ 0x0D, 0x00, "iCUE LINK XG7 RGB", 16 } { 0x0D, 0x00, "iCUE LINK XG7 RGB", 16 }
}; };
@ -67,7 +70,7 @@ static const CorsairICueLinkDevice known_devices[] =
#define CORSAIR_ICUE_LINK_CMD_CLOSE_ENDPOINT {0x05, 0x01, 0x01} #define CORSAIR_ICUE_LINK_CMD_CLOSE_ENDPOINT {0x05, 0x01, 0x01}
#define CORSAIR_ICUE_LINK_CMD_GET_FIRMWARE {0x02, 0x13} #define CORSAIR_ICUE_LINK_CMD_GET_FIRMWARE {0x02, 0x13}
#define CORSAIR_ICUE_LINK_CMD_SOFTWARE_MODE {0x01, 0x03, 0x00, 0x02} #define CORSAIR_ICUE_LINK_CMD_SOFTWARE_MODE {0x01, 0x03, 0x00, 0x02}
#define CORSAIR_ICUE_LINK_CMD_HARDWARE_MODE {0x01, 0x02, 0x00, 0x01} #define CORSAIR_ICUE_LINK_CMD_HARDWARE_MODE {0x01, 0x03, 0x00, 0x01}
#define CORSAIR_ICUE_LINK_CMD_WRITE {0x06, 0x01} #define CORSAIR_ICUE_LINK_CMD_WRITE {0x06, 0x01}
#define CORSAIR_ICUE_LINK_CMD_WRITE_COLOR {0x06, 0x00} #define CORSAIR_ICUE_LINK_CMD_WRITE_COLOR {0x06, 0x00}
#define CORSAIR_ICUE_LINK_CMD_READ {0x08, 0x01} #define CORSAIR_ICUE_LINK_CMD_READ {0x08, 0x01}