Files
OpenRGB/Controllers/SteelSeriesController/SteelSeriesApexBaseController.h

169 lines
5.6 KiB
C++

/*-----------------------------------------*\
| SteelSeriesApexBaseController.h |
| |
| Base controller for SteelSeries Apex |
| Keyboard lighting controllers |
| |
| Florian Heilmann (FHeilmann) 19/10/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include "SteelSeriesGeneric.h"
#include <string>
#include <cstring>
#pragma once
#define STEELSERIES_PACKET_IN_SIZE 64
#define STEELSERIES_PACKET_OUT_SIZE STEELSERIES_PACKET_IN_SIZE + 1
class SteelSeriesApexBaseController
{
public:
virtual ~SteelSeriesApexBaseController()
{
}
std::string GetDeviceLocation()
{
return("HID: " + location);
};
steelseries_type proto_type;
/*----------------------------------------*\
| The serial number of the keyboard is |
| acquired by sending an output report |
| to address 0xFF and reading the result. |
| The HID capability table is not used. |
| The serial number also contains the model|
| number which can be used to determine |
| the physical layout of different region |
| keyboards throughout the product stack. |
\*----------------------------------------*/
std::string GetSerialString()
{
std::string return_string = "";
if(proto_type == APEX)
{
unsigned char obuf[STEELSERIES_PACKET_OUT_SIZE];
unsigned char ibuf[STEELSERIES_PACKET_IN_SIZE];
int result;
memset(obuf, 0x00, sizeof(obuf));
obuf[0x00] = 0;
obuf[0x01] = 0xFF;
hid_write(dev, obuf, STEELSERIES_PACKET_OUT_SIZE);
result = hid_read_timeout(dev, ibuf, STEELSERIES_PACKET_IN_SIZE, 2);
/*---------------------------------------*\
| Only the first 19 bytes are of value |
\*---------------------------------------*/
if( result > 0)
{
std::string serialnum(ibuf, ibuf+19);
return_string = serialnum;
}
}
return(return_string);
}
std::string GetVersionString()
{
std::string return_string = "Unsupported protocol";
if(proto_type == APEX)
{
/*--------------------------------------------*\
| For the Apex Pro there are two firmware |
| versions which can be acquired, KBD and LED. |
| We know where both are located, we do not |
| know which is what. For now we'll make an |
| assumption and fix if proven wrong. |
\*--------------------------------------------*/
unsigned char obuf[STEELSERIES_PACKET_OUT_SIZE];
unsigned char ibuf[STEELSERIES_PACKET_IN_SIZE];
int result;
memset(obuf, 0x00, sizeof(obuf));
obuf[0x00] = 0;
obuf[0x01] = 0x90;
hid_write(dev, obuf, STEELSERIES_PACKET_OUT_SIZE);
result = hid_read_timeout(dev, ibuf, STEELSERIES_PACKET_IN_SIZE, 2);
if(result > 0)
{
std::string fwver(ibuf, ibuf+STEELSERIES_PACKET_IN_SIZE);
fwver = fwver.c_str();
/*---------------------------------------*\
| Find 2 periods in string, if found we |
| can form a X.Y.Z revision. |
\*---------------------------------------*/
std::size_t majorp = fwver.find('.');
if(majorp != std::string::npos)
{
std::size_t minorp = fwver.find('.', majorp+1);
if(minorp != std::string::npos)
{
std::string major = fwver.substr(0, majorp);
std::string minor = fwver.substr(majorp+1, (minorp-majorp-1));
std::string build = fwver.substr(minorp+1);
return_string = "KBD: " + major + "." + minor + "." + build;
}
}
}
/*---------------------------------------*\
| Clear and reuse buffer |
\*---------------------------------------*/
memset(ibuf, 0x00, sizeof(ibuf));
obuf[0x02] = 0x01;
hid_write(dev, obuf, STEELSERIES_PACKET_OUT_SIZE);
result = hid_read_timeout(dev, ibuf, STEELSERIES_PACKET_IN_SIZE, 10);
if(result > 0)
{
std::string fwver(ibuf, ibuf+STEELSERIES_PACKET_IN_SIZE);
fwver = fwver.c_str();
std::size_t majorp = fwver.find('.');
if(majorp != std::string::npos)
{
std::size_t minorp = fwver.find('.', majorp+1);
if(minorp != std::string::npos)
{
std::string major = fwver.substr(0, majorp);
std::string minor = fwver.substr(majorp+1, (minorp-majorp-1));
std::string build = fwver.substr(minorp+1);
return_string = return_string + " / LED: " + major + "." + minor + "." + build;
}
}
}
}
return(return_string);
}
virtual void SetMode
(
unsigned char mode,
std::vector<RGBColor> colors
) = 0;
virtual void SetLEDsDirect(std::vector<RGBColor> colors) = 0;
protected:
std::string location;
hid_device* dev;
unsigned char active_mode;
};