Generic device guard; use Corsair implementation for all Corsair HID cooling-capable controllers
This commit is contained in:
parent
c5c5bf519b
commit
f672397563
15 changed files with 387 additions and 109 deletions
|
|
@ -7,6 +7,7 @@
|
|||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CorsairCommanderCoreController.h"
|
||||
#include "CorsairDeviceGuard.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
|
|
@ -23,9 +24,7 @@ CorsairCommanderCoreController::CorsairCommanderCoreController(hid_device* dev_h
|
|||
packet_size = CORSAIR_COMMANDER_CORE_PACKET_SIZE_V2;
|
||||
command_res_size = packet_size - 4;
|
||||
this->pid = pid;
|
||||
#ifdef _WIN32
|
||||
global_corsair_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_CORSAIR_MUTEX_NAME);
|
||||
#endif
|
||||
guard_manager_ptr = new DeviceGuardManager(new CorsairDeviceGuard());
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize controller |
|
||||
|
|
@ -43,12 +42,6 @@ CorsairCommanderCoreController::~CorsairCommanderCoreController()
|
|||
/*-----------------------------------------------------*\
|
||||
| Close keepalive thread |
|
||||
\*-----------------------------------------------------*/
|
||||
#ifdef _WIN32
|
||||
if(global_corsair_access_handle != NULL)
|
||||
{
|
||||
CloseHandle(global_corsair_access_handle);
|
||||
}
|
||||
#endif
|
||||
keepalive_thread_run = 0;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
|
|
@ -57,6 +50,7 @@ CorsairCommanderCoreController::~CorsairCommanderCoreController()
|
|||
| Close HID device |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_close(dev);
|
||||
delete guard_manager_ptr;
|
||||
}
|
||||
|
||||
void CorsairCommanderCoreController::InitController()
|
||||
|
|
@ -153,13 +147,6 @@ void CorsairCommanderCoreController::SendCommand(unsigned char command[2], unsig
|
|||
\*---------------------------------------------------------*/
|
||||
unsigned char* buf = new unsigned char[packet_size];
|
||||
|
||||
#ifdef _WIN32
|
||||
if(global_corsair_access_handle != NULL)
|
||||
{
|
||||
WaitForSingleObject(global_corsair_access_handle, INFINITE);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(buf, 0, packet_size);
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x08;
|
||||
|
|
@ -170,25 +157,28 @@ void CorsairCommanderCoreController::SendCommand(unsigned char command[2], unsig
|
|||
memcpy(&buf[4], data, data_len);
|
||||
}
|
||||
|
||||
hid_write(dev, buf, packet_size);
|
||||
do
|
||||
/*---------------------------------------------------------*\
|
||||
| HID I/O start |
|
||||
\*---------------------------------------------------------*/
|
||||
{
|
||||
hid_read(dev, buf, packet_size);
|
||||
DeviceGuardLock _ = guard_manager_ptr->AwaitExclusiveAccess();
|
||||
|
||||
hid_write(dev, buf, packet_size);
|
||||
do
|
||||
{
|
||||
hid_read(dev, buf, packet_size);
|
||||
}
|
||||
while (buf[0] != 0x00);
|
||||
}
|
||||
while (buf[0] != 0x00);
|
||||
/*---------------------------------------------------------*\
|
||||
| HID I/O end (lock released) |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
if(res != NULL)
|
||||
{
|
||||
memcpy(res, &buf[3], command_res_size);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if(global_corsair_access_handle != NULL)
|
||||
{
|
||||
ReleaseMutex(global_corsair_access_handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
|
|
@ -201,17 +191,9 @@ void CorsairCommanderCoreController::WriteData(unsigned char endpoint[2], unsign
|
|||
/*---------------------------------------------------------*\
|
||||
| Open endpoint |
|
||||
\*---------------------------------------------------------*/
|
||||
#ifdef _WIN32
|
||||
if(global_corsair_access_handle != NULL)
|
||||
{
|
||||
WaitForSingleObject(global_corsair_access_handle, INFINITE);
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned char command[2] = {0x0d, 0x00};
|
||||
SendCommand(command, endpoint, 2, NULL);
|
||||
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Write data |
|
||||
\*---------------------------------------------------------*/
|
||||
|
|
@ -271,13 +253,6 @@ void CorsairCommanderCoreController::WriteData(unsigned char endpoint[2], unsign
|
|||
command[0] = 0x05;
|
||||
command[1] = 0x01;
|
||||
SendCommand(command, NULL, 0, NULL);
|
||||
|
||||
#ifdef _WIN32
|
||||
if(global_corsair_access_handle != NULL)
|
||||
{
|
||||
ReleaseMutex(global_corsair_access_handle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CorsairCommanderCoreController::SetDirectColor
|
||||
|
|
@ -371,6 +346,6 @@ void CorsairCommanderCoreController::SetFanMode()
|
|||
}
|
||||
|
||||
WriteData(endpoint, data_type, buf, 15);
|
||||
|
||||
|
||||
controller_ready = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,15 +9,12 @@
|
|||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "DeviceGuardManager.h"
|
||||
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CORSAIR_COMMANDER_CORE_PACKET_SIZE_V1 1025 // First bit is the report bit
|
||||
|
|
@ -28,10 +25,6 @@
|
|||
#define CORSAIR_QL_FAN_ZONE_OFFSET 102
|
||||
#define CORSAIR_COMMANDER_CORE_NUM_CHANNELS 6
|
||||
|
||||
#ifdef _WIN32
|
||||
#define GLOBAL_CORSAIR_MUTEX_NAME "Global\\CorsairLinkReadWriteGuardMutex"
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_COMMANDER_CORE_MODE_DIRECT = 0x00,
|
||||
|
|
@ -56,23 +49,20 @@ public:
|
|||
void SetFanMode();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::atomic<bool> controller_ready;
|
||||
std::string location;
|
||||
std::vector<RGBColor> lastcolors;
|
||||
std::vector<zone> lastzones;
|
||||
unsigned short int version[3] = {0, 0, 0};
|
||||
int packet_size;
|
||||
int command_res_size;
|
||||
int pid;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
|
||||
hid_device* dev;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::atomic<bool> controller_ready;
|
||||
std::string location;
|
||||
std::vector<RGBColor> lastcolors;
|
||||
std::vector<zone> lastzones;
|
||||
unsigned short int version[3] = {0, 0, 0};
|
||||
int packet_size;
|
||||
int command_res_size;
|
||||
int pid;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
|
||||
DeviceGuardManager* guard_manager_ptr;
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE global_corsair_access_handle = NULL;
|
||||
#endif
|
||||
|
||||
void SendCommand(unsigned char command[2], unsigned char data[], unsigned short int data_len, unsigned char res[]);
|
||||
void WriteData(unsigned char endpoint[2], unsigned char data_type[2], unsigned char data[], unsigned short int data_len);
|
||||
|
||||
|
|
|
|||
64
Controllers/CorsairController/CorsairDeviceGuard.cpp
Normal file
64
Controllers/CorsairController/CorsairDeviceGuard.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| CorsairDeviceGuard.h |
|
||||
| |
|
||||
| A DeviceGuard implementation for Corsair devices. |
|
||||
| |
|
||||
| On Windows platforms, a global mutex is used. |
|
||||
| |
|
||||
| Evan Mulawski, 2023-09-04 |
|
||||
| |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CorsairDeviceGuard.h"
|
||||
|
||||
CorsairDeviceGuard::CorsairDeviceGuard() : DeviceGuard()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
mutex_handle = CreateWindowsMutex();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CorsairDeviceGuard::Acquire()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
while(true)
|
||||
{
|
||||
DWORD result = WaitForSingleObject(mutex_handle, INFINITE);
|
||||
|
||||
if(result == WAIT_OBJECT_0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(result == WAIT_ABANDONED)
|
||||
{
|
||||
ReleaseMutex(mutex_handle);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CorsairDeviceGuard::Release()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ReleaseMutex(mutex_handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
HANDLE CorsairDeviceGuard::CreateWindowsMutex()
|
||||
{
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
|
||||
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
|
||||
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
sa.bInheritHandle = FALSE;
|
||||
|
||||
return CreateMutex(&sa, FALSE, "Global\\CorsairLinkReadWriteGuardMutex");
|
||||
}
|
||||
|
||||
#endif
|
||||
34
Controllers/CorsairController/CorsairDeviceGuard.h
Normal file
34
Controllers/CorsairController/CorsairDeviceGuard.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| CorsairDeviceGuard.h |
|
||||
| |
|
||||
| A DeviceGuard implementation for Corsair devices. |
|
||||
| |
|
||||
| On Windows platforms, a global mutex is used. |
|
||||
| |
|
||||
| Evan Mulawski, 2023-09-04 |
|
||||
| |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DeviceGuard.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
class CorsairDeviceGuard : public DeviceGuard
|
||||
{
|
||||
public:
|
||||
CorsairDeviceGuard();
|
||||
|
||||
void Acquire() override;
|
||||
void Release() override;
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
HANDLE mutex_handle;
|
||||
|
||||
HANDLE CreateWindowsMutex();
|
||||
#endif
|
||||
};
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include "CorsairHydroPlatinumController.h"
|
||||
#include "CorsairDeviceGuard.h"
|
||||
#include <cstring>
|
||||
|
||||
static const uint8_t CRC_TABLE[256] =
|
||||
|
|
@ -86,6 +87,7 @@ CorsairHydroPlatinumController::CorsairHydroPlatinumController(hid_device* dev_h
|
|||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
guard_manager_ptr = new DeviceGuardManager(new CorsairDeviceGuard());
|
||||
|
||||
SendMagic(MAGIC_1, CORSAIR_HYDRO_PLATINUM_MAGIC_1);
|
||||
SendMagic(MAGIC_2, CORSAIR_HYDRO_PLATINUM_MAGIC_2);
|
||||
|
|
@ -95,6 +97,7 @@ CorsairHydroPlatinumController::CorsairHydroPlatinumController(hid_device* dev_h
|
|||
CorsairHydroPlatinumController::~CorsairHydroPlatinumController()
|
||||
{
|
||||
hid_close(dev);
|
||||
delete guard_manager_ptr;
|
||||
}
|
||||
|
||||
std::string CorsairHydroPlatinumController::GetLocation()
|
||||
|
|
@ -152,8 +155,18 @@ void CorsairHydroPlatinumController::SendMagic(const uint8_t* magic, unsigned in
|
|||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
|
||||
hid_read(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
|
||||
/*---------------------------------------------------------*\
|
||||
| HID I/O start |
|
||||
\*---------------------------------------------------------*/
|
||||
{
|
||||
DeviceGuardLock _ = guard_manager_ptr->AwaitExclusiveAccess();
|
||||
|
||||
hid_write(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
|
||||
hid_read(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| HID I/O end (lock released) |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
if(firmware_version.empty())
|
||||
{
|
||||
|
|
@ -204,8 +217,17 @@ void CorsairHydroPlatinumController::SendColors(std::vector<RGBColor> colors, un
|
|||
checksum_array.insert(checksum_array.begin(), std::begin(usb_buf) + 2, std::end(usb_buf) - 1);
|
||||
usb_buf[64] = ComputePEC(static_cast<void*>(checksum_array.data()), 62);
|
||||
|
||||
hid_write(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
|
||||
hid_read(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
|
||||
/*---------------------------------------------------------*\
|
||||
| HID I/O start |
|
||||
\*---------------------------------------------------------*/
|
||||
{
|
||||
DeviceGuardLock _ = guard_manager_ptr->AwaitExclusiveAccess();
|
||||
|
||||
hid_write(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| HID I/O end (lock released) |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| This delay prevents the AIO from soft-locking when |
|
||||
|
|
@ -242,4 +264,4 @@ uint8_t CorsairHydroPlatinumController::ComputePEC(const void * data, size_t siz
|
|||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "DeviceGuardManager.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
|
@ -39,11 +41,11 @@ public:
|
|||
void SetupColors(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string firmware_version;
|
||||
|
||||
std::atomic<unsigned int> sequence_number;
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string firmware_version;
|
||||
std::atomic<unsigned int> sequence_number;
|
||||
DeviceGuardManager* guard_manager_ptr;
|
||||
|
||||
void SendMagic(const uint8_t* magic, unsigned int command);
|
||||
void SendColors(std::vector<RGBColor> colors, unsigned int start, unsigned int end, unsigned int command);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CorsairLightingNodeController.h"
|
||||
#include "CorsairDeviceGuard.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
|
@ -17,6 +18,7 @@ CorsairLightingNodeController::CorsairLightingNodeController(hid_device* dev_han
|
|||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
guard_manager_ptr = new DeviceGuardManager(new CorsairDeviceGuard());
|
||||
|
||||
SendFirmwareRequest();
|
||||
|
||||
|
|
@ -37,6 +39,7 @@ CorsairLightingNodeController::~CorsairLightingNodeController()
|
|||
delete keepalive_thread;
|
||||
|
||||
hid_close(dev);
|
||||
delete guard_manager_ptr;
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::KeepaliveThread()
|
||||
|
|
@ -176,7 +179,7 @@ void CorsairLightingNodeController::SetChannelLEDs(unsigned char channel, RGBCol
|
|||
{
|
||||
pkt_size = 50;
|
||||
}
|
||||
|
||||
|
||||
for(int color_idx = 0; color_idx < pkt_size; color_idx++)
|
||||
{
|
||||
red_color_data[color_idx] = RGBGetRValue(colors[pkt_offset + color_idx]);
|
||||
|
|
@ -205,7 +208,7 @@ void CorsairLightingNodeController::SetChannelLEDs(unsigned char channel, RGBCol
|
|||
void CorsairLightingNodeController::SendFirmwareRequest()
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[65];
|
||||
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
|
|
@ -221,8 +224,7 @@ void CorsairLightingNodeController::SendFirmwareRequest()
|
|||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
actual = hid_read(dev, usb_buf, 17);
|
||||
actual = WriteAndRead(usb_buf);
|
||||
|
||||
if(actual > 0)
|
||||
{
|
||||
|
|
@ -239,7 +241,7 @@ void CorsairLightingNodeController::SendDirect
|
|||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
|
|
@ -264,13 +266,12 @@ void CorsairLightingNodeController::SendDirect
|
|||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read_timeout(dev, usb_buf, 17, 5);
|
||||
WriteAndRead(usb_buf, 5);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
|
|
@ -292,8 +293,7 @@ void CorsairLightingNodeController::SendCommit()
|
|||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read_timeout(dev, usb_buf, 17, 5);
|
||||
WriteAndRead(usb_buf, 5);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendBegin
|
||||
|
|
@ -301,7 +301,7 @@ void CorsairLightingNodeController::SendBegin
|
|||
unsigned char channel
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
|
|
@ -318,8 +318,7 @@ void CorsairLightingNodeController::SendBegin
|
|||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
WriteAndRead(usb_buf);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendEffectConfig
|
||||
|
|
@ -345,7 +344,7 @@ void CorsairLightingNodeController::SendEffectConfig
|
|||
unsigned short temperature_2
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
|
|
@ -396,8 +395,7 @@ void CorsairLightingNodeController::SendEffectConfig
|
|||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
WriteAndRead(usb_buf);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendTemperature()
|
||||
|
|
@ -410,7 +408,7 @@ void CorsairLightingNodeController::SendReset
|
|||
unsigned char channel
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
|
|
@ -427,8 +425,7 @@ void CorsairLightingNodeController::SendReset
|
|||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
WriteAndRead(usb_buf);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendPortState
|
||||
|
|
@ -437,7 +434,7 @@ void CorsairLightingNodeController::SendPortState
|
|||
unsigned char state
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
|
|
@ -455,8 +452,7 @@ void CorsairLightingNodeController::SendPortState
|
|||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read_timeout(dev, usb_buf, 17, 5);
|
||||
WriteAndRead(usb_buf, 5);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendBrightness
|
||||
|
|
@ -465,7 +461,7 @@ void CorsairLightingNodeController::SendBrightness
|
|||
unsigned char brightness
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Brightness goes from 0-100 |
|
||||
|
|
@ -491,8 +487,7 @@ void CorsairLightingNodeController::SendBrightness
|
|||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
WriteAndRead(usb_buf);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendLEDCount()
|
||||
|
|
@ -504,3 +499,34 @@ void CorsairLightingNodeController::SendProtocol()
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
int CorsairLightingNodeController::WriteAndRead
|
||||
(
|
||||
unsigned char *buf,
|
||||
int read_timeout_ms
|
||||
)
|
||||
{
|
||||
int hid_read_ret;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HID I/O start |
|
||||
\*---------------------------------------------------------*/
|
||||
{
|
||||
DeviceGuardLock _ = guard_manager_ptr->AwaitExclusiveAccess();
|
||||
|
||||
hid_write(dev, buf, CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE);
|
||||
if(read_timeout_ms > 0)
|
||||
{
|
||||
hid_read_ret = hid_read_timeout(dev, buf, CORSAIR_LIGHTING_NODE_READ_PACKET_SIZE, read_timeout_ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
hid_read_ret = hid_read(dev, buf, CORSAIR_LIGHTING_NODE_READ_PACKET_SIZE);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| HID I/O end (lock released) |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
return hid_read_ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,18 @@
|
|||
| Adam Honse (calcprogrammer1@gmail.com), 1/12/2020 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DeviceGuardManager.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE 65 /* First byte is the report number */
|
||||
#define CORSAIR_LIGHTING_NODE_READ_PACKET_SIZE 17 /* First byte is the report number */
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE = 0x02, /* Get firmware version */
|
||||
|
|
@ -89,7 +94,7 @@ public:
|
|||
unsigned int GetStripsOnChannel(unsigned int channel);
|
||||
|
||||
void SetBrightness(unsigned char brightness);
|
||||
|
||||
|
||||
void SetChannelEffect(unsigned char channel,
|
||||
unsigned char num_leds,
|
||||
unsigned char mode,
|
||||
|
|
@ -112,12 +117,13 @@ public:
|
|||
void KeepaliveThread();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string firmware_version;
|
||||
std::string location;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
|
||||
hid_device* dev;
|
||||
std::string firmware_version;
|
||||
std::string location;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
|
||||
DeviceGuardManager* guard_manager_ptr;
|
||||
|
||||
void SendFirmwareRequest();
|
||||
|
||||
|
|
@ -182,4 +188,10 @@ private:
|
|||
void SendLEDCount();
|
||||
|
||||
void SendProtocol();
|
||||
|
||||
int WriteAndRead
|
||||
(
|
||||
unsigned char *buf,
|
||||
int read_timeout_ms = -1
|
||||
);
|
||||
};
|
||||
|
|
|
|||
10
OpenRGB.pro
10
OpenRGB.pro
|
|
@ -78,6 +78,7 @@ INCLUDEPATH +=
|
|||
hidapi_wrapper/ \
|
||||
i2c_smbus/ \
|
||||
i2c_tools/ \
|
||||
interop/ \
|
||||
net_port/ \
|
||||
pci_ids/ \
|
||||
scsiapi/ \
|
||||
|
|
@ -124,6 +125,7 @@ INCLUDEPATH +=
|
|||
Controllers/AsusAuraUSBController/ \
|
||||
Controllers/CherryKeyboardController/ \
|
||||
Controllers/CoolerMasterController/ \
|
||||
Controllers/CorsairController/ \
|
||||
Controllers/CorsairCommanderCoreController/ \
|
||||
Controllers/CorsairDominatorPlatinumController/ \
|
||||
Controllers/CorsairHydroController/ \
|
||||
|
|
@ -269,6 +271,9 @@ HEADERS +=
|
|||
hidapi_wrapper/hidapi_wrapper.h \
|
||||
i2c_smbus/i2c_smbus.h \
|
||||
i2c_tools/i2c_tools.h \
|
||||
interop/DeviceGuard.h \
|
||||
interop/DeviceGuardLock.h \
|
||||
interop/DeviceGuardManager.h \
|
||||
net_port/net_port.h \
|
||||
pci_ids/pci_ids.h \
|
||||
qt/DeviceView.h \
|
||||
|
|
@ -419,6 +424,7 @@ HEADERS +=
|
|||
Controllers/CoolerMasterController/RGBController_CMSmallARGBController.h \
|
||||
Controllers/CorsairCommanderCoreController/CorsairCommanderCoreController.h \
|
||||
Controllers/CorsairCommanderCoreController/RGBController_CorsairCommanderCore.h \
|
||||
Controllers/CorsairController/CorsairDeviceGuard.h \
|
||||
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.h \
|
||||
Controllers/CorsairDominatorPlatinumController/RGBController_CorsairDominatorPlatinum.h \
|
||||
Controllers/CorsairHydroController/CorsairHydroController.h \
|
||||
|
|
@ -877,6 +883,9 @@ SOURCES +=
|
|||
qt/DetectorTableModel.cpp \
|
||||
i2c_smbus/i2c_smbus.cpp \
|
||||
i2c_tools/i2c_tools.cpp \
|
||||
interop/DeviceGuard.cpp \
|
||||
interop/DeviceGuardLock.cpp \
|
||||
interop/DeviceGuardManager.cpp \
|
||||
net_port/net_port.cpp \
|
||||
qt/DeviceView.cpp \
|
||||
qt/hsv.cpp \
|
||||
|
|
@ -1044,6 +1053,7 @@ SOURCES +=
|
|||
Controllers/CorsairCommanderCoreController/CorsairCommanderCoreController.cpp \
|
||||
Controllers/CorsairCommanderCoreController/CorsairCommanderCoreControllerDetect.cpp \
|
||||
Controllers/CorsairCommanderCoreController/RGBController_CorsairCommanderCore.cpp \
|
||||
Controllers/CorsairController/CorsairDeviceGuard.cpp \
|
||||
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.cpp \
|
||||
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumControllerDetect.cpp \
|
||||
Controllers/CorsairDominatorPlatinumController/RGBController_CorsairDominatorPlatinum.cpp \
|
||||
|
|
|
|||
22
interop/DeviceGuard.cpp
Normal file
22
interop/DeviceGuard.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| DeviceGuard.cpp |
|
||||
| |
|
||||
| An abstract interface for acquiring and releasing |
|
||||
| a guard on a device, serving as a foundation for |
|
||||
| implementing device-specific synchronization mechanisms. |
|
||||
| |
|
||||
| Evan Mulawski, 2023-09-05 |
|
||||
| |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DeviceGuard.h"
|
||||
|
||||
DeviceGuard::DeviceGuard()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DeviceGuard::~DeviceGuard()
|
||||
{
|
||||
|
||||
}
|
||||
22
interop/DeviceGuard.h
Normal file
22
interop/DeviceGuard.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| DeviceGuard.h |
|
||||
| |
|
||||
| An abstract interface for acquiring and releasing |
|
||||
| a guard on a device, serving as a foundation for |
|
||||
| implementing device-specific synchronization mechanisms. |
|
||||
| |
|
||||
| Evan Mulawski, 2023-09-05 |
|
||||
| |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class DeviceGuard
|
||||
{
|
||||
public:
|
||||
DeviceGuard();
|
||||
virtual ~DeviceGuard();
|
||||
|
||||
virtual void Acquire() = 0;
|
||||
virtual void Release() = 0;
|
||||
};
|
||||
22
interop/DeviceGuardLock.cpp
Normal file
22
interop/DeviceGuardLock.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| DeviceGuardLock.cpp |
|
||||
| |
|
||||
| Represents a lock for a device guard, ensuring |
|
||||
| exclusive access to a device when acquired |
|
||||
| and releasing it when destroyed. |
|
||||
| |
|
||||
| Evan Mulawski, 2023-09-05 |
|
||||
| |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DeviceGuardLock.h"
|
||||
|
||||
DeviceGuardLock::DeviceGuardLock(DeviceGuard& guard_ref) : guard(guard_ref)
|
||||
{
|
||||
guard.Acquire();
|
||||
}
|
||||
|
||||
DeviceGuardLock::~DeviceGuardLock()
|
||||
{
|
||||
guard.Release();
|
||||
}
|
||||
24
interop/DeviceGuardLock.h
Normal file
24
interop/DeviceGuardLock.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| DeviceGuardLock.h |
|
||||
| |
|
||||
| Represents a lock for a device guard, ensuring |
|
||||
| exclusive access to a device when acquired |
|
||||
| and releasing it when destroyed. |
|
||||
| |
|
||||
| Evan Mulawski, 2023-09-05 |
|
||||
| |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DeviceGuard.h"
|
||||
|
||||
class DeviceGuardLock
|
||||
{
|
||||
public:
|
||||
DeviceGuardLock(DeviceGuard& guard_ref);
|
||||
~DeviceGuardLock();
|
||||
|
||||
private:
|
||||
DeviceGuard& guard;
|
||||
};
|
||||
27
interop/DeviceGuardManager.cpp
Normal file
27
interop/DeviceGuardManager.cpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| DeviceGuardManager.cpp |
|
||||
| |
|
||||
| Responsible for managing a DeviceGuard implementation, |
|
||||
| allowing clients to wait for exclusive access to a |
|
||||
| device using the DeviceGuardLock it provides. |
|
||||
| |
|
||||
| Evan Mulawski, 2023-09-05 |
|
||||
| |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DeviceGuardManager.h"
|
||||
|
||||
DeviceGuardManager::DeviceGuardManager(DeviceGuard* guard_ptr) : guard(guard_ptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DeviceGuardManager::~DeviceGuardManager()
|
||||
{
|
||||
delete guard;
|
||||
}
|
||||
|
||||
DeviceGuardLock DeviceGuardManager::AwaitExclusiveAccess()
|
||||
{
|
||||
return DeviceGuardLock(*guard);
|
||||
}
|
||||
26
interop/DeviceGuardManager.h
Normal file
26
interop/DeviceGuardManager.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| DeviceGuardManager.h |
|
||||
| |
|
||||
| Responsible for managing a DeviceGuard implementation, |
|
||||
| allowing clients to wait for exclusive access to a |
|
||||
| device using the DeviceGuardLock it provides. |
|
||||
| |
|
||||
| Evan Mulawski, 2023-09-05 |
|
||||
| |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DeviceGuardLock.h"
|
||||
|
||||
class DeviceGuardManager
|
||||
{
|
||||
public:
|
||||
DeviceGuardManager(DeviceGuard* guard_ptr);
|
||||
~DeviceGuardManager();
|
||||
|
||||
DeviceGuardLock AwaitExclusiveAccess();
|
||||
|
||||
private:
|
||||
DeviceGuard* guard;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue