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 ***/