You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
5.6 KiB
196 lines
5.6 KiB
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <libusb.h>
|
|
#include <wchar.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
#include <assert.h>
|
|
|
|
// Devices
|
|
#include "devices/htx.h"
|
|
#include "devices/hts_plus.h"
|
|
#include "devices/hsk_pro.h"
|
|
|
|
#define VENDOR_ID 0x33e4
|
|
|
|
#define REPORT_MAX_SIZE 0x40 // 64 Bytes
|
|
|
|
#define REPORT_UNKNOWN_0_SIZE 0x2
|
|
#define REPORT_DPI_SETTINGS_SIZE 0x39 // 2b with old software, 5 profiles to 7 ?
|
|
#define REPORT_UNKNOWN_1_SIZE 0x2
|
|
#define REPORT_UNKNOWN_2_SIZE 0x24
|
|
#define REPORT_CLICK_DEBOUNCE_SETTINGS_SIZE 0x4
|
|
#define REPORT_LIFT_OFF_SIZE 0x1
|
|
#define REPORT_ANGLE_SNAP_SIZE 0x1
|
|
#define REPORT_MOTION_SYNC_SIZE 0x1
|
|
#define REPORT_UNKNOWN_6_SIZE 0x5
|
|
#define REPORT_BATTERY_SIZE 0x2
|
|
#define REPORT_WIRELESS_MOUSE_SIZE 0x1
|
|
#define REPORT_WIRELESS_FIRMWARE_VERSION_SIZE 0x4 // -> 0x7
|
|
|
|
#define COMMAND_UNKNOWN_0 0x82
|
|
#define COMMAND_DPI_SETTINGS 0x83
|
|
#define COMMAND_UNKNOWN_1 0x92
|
|
#define COMMAND_UNKNOWN_2 0x84
|
|
#define COMMAND_CLICK_DEBOUNCE_SETTINGS 0x85
|
|
#define COMMAND_LIFT_OFF 0x86
|
|
#define COMMAND_ANGLE_SNAP 0x87
|
|
#define COMMAND_MOTION_SYNC 0x91
|
|
#define COMMAND_UNKNOWN_6 0x98
|
|
#define COMMAND_BATTERY 0x8F
|
|
#define COMMAND_WIRELESS_MOUSE 0x90 // -> send the next report to mouse, checking if mouse is connected
|
|
#define COMMAND_WIRELESS_FIRMWARE_VERSION 0x81
|
|
|
|
typedef struct DPI_LEVEL
|
|
{
|
|
uint8_t dpi_x_high;
|
|
uint8_t dpi_x_low;
|
|
|
|
uint8_t dpi_y_high;
|
|
uint8_t dpi_y_low;
|
|
|
|
// LED color when this dpi level is selected
|
|
uint8_t led_r;
|
|
uint8_t led_g;
|
|
uint8_t led_b;
|
|
} __attribute__((packed)) dpi_level_t;
|
|
|
|
typedef struct REPORT_HEADER
|
|
{
|
|
uint8_t a1; // 0xa1: request_type on receive, 0x00 on set
|
|
|
|
uint8_t report_size; // report size, after header
|
|
uint8_t command; // COMMAND
|
|
uint8_t wireless; // 0 on wired, 1 on wireless
|
|
} __attribute__((packed)) report_header_t;
|
|
|
|
struct REPORT_DPI_SETTINGS
|
|
{
|
|
report_header_t header;
|
|
|
|
uint8_t level_current; // current dpi level
|
|
uint8_t level_count; // count of dpi levels
|
|
|
|
dpi_level_t levels[5];
|
|
uint8_t zeros[23];
|
|
} __attribute__((packed));
|
|
static_assert(sizeof(struct REPORT_DPI_SETTINGS) == REPORT_MAX_SIZE, "Report DPI_SETTINGS not of right size");
|
|
|
|
struct REPORT_UNKNOWN_0
|
|
{
|
|
report_header_t header;
|
|
|
|
uint8_t value0;
|
|
uint8_t value1;
|
|
|
|
uint8_t zeros[REPORT_MAX_SIZE - sizeof(report_header_t) - 2];
|
|
} __attribute__((packed));
|
|
static_assert(sizeof(struct REPORT_UNKNOWN_0) == REPORT_MAX_SIZE, "Report UNKNOWN_0 not of right size");
|
|
|
|
struct REPORT_UNKNOWN_1
|
|
{
|
|
report_header_t header;
|
|
|
|
uint8_t value0;
|
|
uint8_t value1;
|
|
|
|
uint8_t zeros[REPORT_MAX_SIZE - sizeof(report_header_t) - 2];
|
|
} __attribute__((packed));
|
|
static_assert(sizeof(struct REPORT_UNKNOWN_1) == REPORT_MAX_SIZE, "Report UNKNOWN_1 not of right size");
|
|
|
|
struct REPORT_CLICK_DEBOUNCE_SETTINGS
|
|
{
|
|
report_header_t header;
|
|
|
|
// A = 0ms B = 1 ms C = 2 ms D = 3 ms E = 4 ms
|
|
uint8_t debounce_preset; // 0x00 = A, 0x01 = B, 0x02 = C, 0x03 = D, 0x04 = E, AUTO = 0x00
|
|
uint8_t unknown_value; // 30d, 40d, or 50d (30 for A/B/C/AUTO) (40 for D) (50 for E)
|
|
uint8_t auto_high; // 0x23 for manual, 0x3C for auto
|
|
uint8_t auto_low; // 0x14 for manual, 0x28 for auto
|
|
|
|
uint8_t zeros[REPORT_MAX_SIZE - 8];
|
|
} __attribute__((packed));
|
|
static_assert(sizeof(struct REPORT_CLICK_DEBOUNCE_SETTINGS) == REPORT_MAX_SIZE, "Report CLICK_DEBOUNCE_SETTINGS not of right size");
|
|
|
|
struct REPORT_LIFT_OFF
|
|
{
|
|
report_header_t header;
|
|
|
|
// 1 = Low, 2 = High
|
|
uint8_t lift_off;
|
|
|
|
uint8_t zeros[REPORT_MAX_SIZE - sizeof(report_header_t) - 1];
|
|
} __attribute__((packed));
|
|
static_assert(sizeof(struct REPORT_LIFT_OFF) == REPORT_MAX_SIZE, "Report LIFT_OFF not of right size");
|
|
|
|
struct REPORT_ANGLE_SNAP
|
|
{
|
|
report_header_t header;
|
|
|
|
// 0 = disabled, 1 = enabled
|
|
uint8_t angle_snap;
|
|
|
|
uint8_t zeros[REPORT_MAX_SIZE - sizeof(report_header_t) - 1];
|
|
} __attribute__((packed));
|
|
static_assert(sizeof(struct REPORT_ANGLE_SNAP) == REPORT_MAX_SIZE, "Report ANGLE_SNAP not of right size");
|
|
|
|
struct REPORT_MOTION_SYNC
|
|
{
|
|
report_header_t header;
|
|
|
|
uint8_t motion_sync;
|
|
|
|
uint8_t zeros[REPORT_MAX_SIZE - sizeof(report_header_t) - 1];
|
|
} __attribute__((packed));
|
|
static_assert(sizeof(struct REPORT_MOTION_SYNC) == REPORT_MAX_SIZE, "Report MOTION_SYNC not of right size");
|
|
|
|
struct REPORT_UNKNOWN_6
|
|
{
|
|
report_header_t header;
|
|
|
|
uint8_t value0;
|
|
uint8_t value1;
|
|
uint8_t value2;
|
|
uint8_t value3;
|
|
uint8_t value4;
|
|
uint8_t value5;
|
|
|
|
uint8_t zeros[REPORT_MAX_SIZE - sizeof(report_header_t) - 6];
|
|
} __attribute__((packed));
|
|
static_assert(sizeof(struct REPORT_UNKNOWN_6) == REPORT_MAX_SIZE, "Report UNKNOWN_6 not of right size");
|
|
|
|
struct REPORT_BATTERY
|
|
{
|
|
report_header_t header;
|
|
|
|
uint8_t battery_status; // 0 : not charging, 1 : charging
|
|
uint8_t battery_level; // in %
|
|
|
|
uint8_t zeros[REPORT_MAX_SIZE - sizeof(report_header_t) - 2];
|
|
} __attribute__((packed));
|
|
static_assert(sizeof(struct REPORT_BATTERY) == REPORT_MAX_SIZE, "Report BATTERY not of right size");
|
|
|
|
struct REPORT_WIRELESS
|
|
{
|
|
report_header_t header;
|
|
|
|
uint8_t mouse_connected; // 0 if disconnected, else 1
|
|
uint8_t zeros[REPORT_MAX_SIZE - sizeof(report_header_t) - 1];
|
|
} __attribute__((packed));
|
|
static_assert(sizeof(struct REPORT_WIRELESS) == REPORT_MAX_SIZE, "Report WIRELESS not of right size");
|
|
|
|
struct REPORT_WIRELESS_FIRMWARE_VERSION
|
|
{
|
|
report_header_t header;
|
|
|
|
uint8_t version_major;
|
|
uint8_t version_med;
|
|
uint8_t version_minor;
|
|
|
|
uint8_t values[4];
|
|
|
|
uint8_t zeros[REPORT_MAX_SIZE - sizeof(report_header_t) - 7];
|
|
} __attribute__((packed));
|
|
static_assert(sizeof(struct REPORT_WIRELESS_FIRMWARE_VERSION) == REPORT_MAX_SIZE, "Report WIRELESS_FIRMWARE_VERSION not of right size");
|
|
|