This is some code to interface with the ASUS ROG STRIX IMPACT Mouse on Linux. Attempts were made to perform DPI adjustment as well. These commands were inferred by using a USB packet sniffer on Windows. Please use at your own risk. This code may only work for the following device; please check before running!
Bus 001 Device 002: ID 0b05:1847 ASUSTek Computer, Inc.
Compile:
gcc -o main main.c `pkg-config --cflags --libs libusb-1.0` -Wall
#include <stdio.h>
#include <string.h>
#include "libusb.h"
/** search for:
Bus 001 Device 002: ID 0b05:1847 ASUSTek Computer, Inc.
ROG STRIX IMPACT
**/
#define VEN_ID 0x0b05
#define DEV_ID 0x1847
#define IF_NUM 2 /* IF2 */
#define EP_NUM 4 /* EP4 OUT */
static libusb_device * find_dev(libusb_device **devs)
{
libusb_device *dev;
int i = 0, j = 0;
uint8_t path[8];
while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(dev, &desc);
if (r < 0) {
fprintf(stderr, "failed to get device descriptor");
return NULL;
}
/*printf("%04x:%04x (bus %d, device %d)",
desc.idVendor, desc.idProduct,
libusb_get_bus_number(dev), libusb_get_device_address(dev));
r = libusb_get_port_numbers(dev, path, sizeof(path));
if (r > 0) {
printf(" path: %d", path[0]);
for (j = 1; j < r; j++)
printf(".%d", path[j]);
}*/
if (desc.idVendor == VEN_ID && desc.idProduct == DEV_ID)
{
printf("Found ASUS Mouse\n");
return dev;
}
//printf("\n");
}
return NULL;
}
int main(void)
{
libusb_device **devs;
libusb_device *asus = NULL;
int res;
ssize_t cnt;
int numBytes = 0; /* Actual bytes transferred. */
uint8_t buffer[64]; /* 64 byte transfer buffer */
int kernelDriverDetached = 0; /* Set to 1 if kernel driver detached */
struct libusb_config_descriptor *conf;
libusb_device_handle *handle;
res = libusb_init(NULL);
if (res < 0)
return res;
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0)
return (int) cnt;
asus = find_dev(devs);
if (asus == NULL)
{
fprintf(stderr, "Could not find ASUS mouse.\n");
goto exit;
}
res = libusb_get_active_config_descriptor(asus, &conf);
if (res != 0)
{
fprintf(stderr, "Error %d getting active config descriptor.\n", res);
return 1;
}
res = libusb_open(asus, &handle);
if (res != 0)
{
fprintf(stderr, "Error %d opening USB device.\n", res);
return 1;
}
/* Check whether a kernel driver is attached to interface #2. If so, we'll
* need to detach it.
*/
if (libusb_kernel_driver_active(handle, IF_NUM))
{
res = libusb_detach_kernel_driver(handle, IF_NUM);
if (res == 0)
{
kernelDriverDetached = 1;
printf("Detached kernel driver from interface %d\n", IF_NUM);
}
else
{
fprintf(stderr, "Error %d detaching kernel driver.\n", res);
return 1;
}
}
/* Claim interface #2. */
res = libusb_claim_interface(handle, IF_NUM);
if (res != 0)
{
fprintf(stderr, "Error %d claiming interface.\n", res);
return 1;
}
printf("Set colors...\n");
/* We can now send and receive messages. For example, set normal mode. */
memset(buffer, 0, 64);
// no color (0x04): 51:28:00:00:04: 04: ff:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
// static color(0x00): 51:28:00:00:00: 04: 90:d1:8a:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
// rgb(144,209,138)=rgb(0x90, 0xd1, 0x8a)
buffer[0] = 0x51; /* reserved */
buffer[1] = 0x28; /* reserved */
buffer[2] = 0x00; /* reserved */
buffer[3] = 0x00; /* reserved */
buffer[4] = 0x04; /* 0: static color, 1: breathing, 2: cycle, 4: no color */
buffer[5] = 0x04; /* reserved */
buffer[6] = 0xff; /* R */
buffer[7] = 0x00; /* G */
buffer[8] = 0x00; /* B */
/* Send the message to endpoint 4 with a 1000ms timeout. */
res = libusb_interrupt_transfer(handle, EP_NUM, buffer, 64, &numBytes, 1000);
if (res == 0)
{
printf("%d bytes transmitted successfully.\n", numBytes);
}
else
{
fprintf(stderr, "Error %d sending 64 byte message to device EP#%d.\n", res, EP_NUM);
}
printf("\nSet DPI...\n");
memset(buffer, 0, 64);
// LED OFF-1800DPI: 51:31:00:00:23:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
// LED ON -1800DPI: 51:31:01:00:23:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
buffer[0] = 0x51; /* reserved */
buffer[1] = 0x31; /* reserved */
buffer[2] = 0x00; /* 0: control primary dpi (LED off), 1: control secondary dpi (LED on) */
buffer[3] = 0x00; /* reserved */
buffer[4] = 0x1f; /* DPI in increments of 50 {50=0x00, 400=0x07, 1600=0x1f, ..., 5000=0x63} */
/* Send the message to endpoint 4 with a 1000ms timeout. */
res = libusb_interrupt_transfer(handle, EP_NUM, buffer, 64, &numBytes, 1000);
if (res == 0)
{
printf("%d bytes transmitted successfully.\n", numBytes);
}
else
{
fprintf(stderr, "Error %d sending 64 byte message to device EP#%d.\n", res, EP_NUM);
}
/* Listen for a message. Note that for a normal application you'll need
* to use asynchronous mode because we can't predict when messages will be
* available. This involves setting up a callback function to handle incoming
* messages - refer to libusb documentation. */
/* Wait up to 5 seconds for a message to arrive on endpoint 0x81. */
/*res = libusb_interrupt_transfer(handle, 0x81, buffer, 64, &numBytes, 5000);
if (0 == res)
{
printf("Received %d bytes, expected 64.\n", numBytes);
}
else
{
fprintf(stderr, "Error receiving message.\n");
}*/
res = libusb_release_interface(handle, IF_NUM);
if (res != 0)
{
fprintf(stderr, "Error %d releasing interface.\n", res);
return 1;
}
if (kernelDriverDetached)
{
res = libusb_attach_kernel_driver(handle, IF_NUM);
if (res != 0)
{
fprintf(stderr, "Error %d reattaching driver.\n", res);
return 1;
}
printf("Reattached kernel driver to interface %d\n", IF_NUM);
}
exit:
libusb_free_device_list(devs, 1);
libusb_exit(NULL);
return 0;
}
/***
RoG Armoury
Frame 38633: 91 bytes on wire (728 bits), 91 bytes captured (728 bits) on interface 0
USB URB
[Source: host]
[Destination: 1.1.4]
USBPcap pseudoheader length: 27
IRP ID: 0xffffe001622479d0
IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
IRP information: 0x00, Direction: FDO -> PDO
URB bus id: 1
Device address: 1
Endpoint: 0x04, Direction: OUT
URB transfer type: URB_INTERRUPT (0x01)
Packet Data Length: 64
[bInterfaceClass: Unknown (0xffff)]
Leftover Capture Data: 512800000404ff0000000000000000000000000000000000...
** lighting:
Type B(brightness),R,G,B
static color(0x00): 51:28:00:00:00: 04: 90:d1:8a:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
rgb(144,209,138)=rgb(0x90, 0xd1, 0x8a)
breathing (0x01): 51:28:00:00:01: 04: ff:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
cycle (0x02): 51:28:00:00:02: 04: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
no color (0x04): 51:28:00:00:04: 04: ff:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
** dpi indicator
off: (0x00): 70:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
on (0x01): 70:00:01:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
DPI{1600=0x1f, 1650=0x20, 1800=0x23, 5000=0x63} increments of 50
DPI 1600-LED off / DPI 400-LED on / 12ms response / 500 polling rate / basic:
51:31:00:00:1f:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
51:31:01:00:07:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
51:31:02:00:02:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
51:31:03:00:02:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
51:31:05:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
51:31:06:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
DPI 1650-LED off / DPI 400-LED on / 12ms response / 500 polling rate / basic:
51:31:00:00:20:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
51:31:01:00:07:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
51:31:02:00:02:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
51:31:03:00:02:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
51:31:05:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
51:31:06:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
DPI 1800-LED off
51:31:00:00:23:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
DPI 5000- LED off
51:31:00:00:63:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
LED off control settings header 51:31:00:00:
LED on control settings header 51:31:01:00:
polling rate settings header 51:31:02:00: (0x00=125, 0x01=250, 0x02=500, 0x03=1000)
brightness settings@static:
0: 51:28:00:00:00:00:ff:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
25: 51:28:00:00:00:01:ff:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
50: 51:28:00:00:00:02:ff:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
75: 51:28:00:00:00:03:ff:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
100: 51:28:00:00:00:04:ff:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
***/