Disable light on ASUS ROG STRIX IMPACT Mouse under Linux

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

 

Leave a Reply

Your email address will not be published. Required fields are marked *