Shop online at ASDA Groceries Home Shopping. The same great prices as in store, delivered to your door with free click and collect! Mouse mats help to deliver smoother mouse performance. For serious gamers, the right gaming surface can actually improve performance and allow you to play more successfully wherever you are. As well as protecting your desk, table or work surface, a good mouse mat can also prevent discomfort and wrist strain.
This week my Zalman optical computer mouse died on me, I’ve had it for almost 4 years, so it did last a good while. The scroll wheel started to slip causing a very annoying issue of documents rolling about by themselves, so i threw it in the bin and went out and purchased a new one.
I ended up getting a new mouse from the local ASDA supermarket, sold under the name of ‘BlackWeb AYA gaming mouse’. Mostly because i thought it looked rather cool with it’s LED colour changing feature, as well as the fact that it was only £21.
(If you’re just looking for the software to control the BlackWeb AYA mouse LED from Linux, scroll to the bottom of the article and you’ll find the links to my github repository.)
The device features are advertised as;
What interested me is that the box didn’t mention any specific OS support (not even a mention of Windows), so i took a gamble hoping it might just have full Linux support. I was obviously wrong.
Upon first connecting it to the computer, the mouse immediately lit up red as the default colour, and it worked like any other generic HID device, requiring no special drivers to function. This is what appears in `dmesg‘
The device listed under `lsusb‘
As you can see it is using the generic HID driver. The first thing i wondered, was how to change the LED colour, because the mouse only came with a CD containing software for a windows driver.
I searched through /sys and /dev for a while trying to find something representative of the colour red, hoping i may just be able to “echo” an RGB colour value to the mouse, but had no success.
I ended up finding a solution to manually set the mouse polling speed through the usbhid module,
/etc/modprobe.d/usbhid.conf
Where 0=default, 1=1000Hz, 2=750Hz, 4=500Hz, 8=250Hz
So that was that out of the way.
Next i went ahead and had a look at the Windows software by setting up a Windows 10 virtual machine. After enabling USB pass through for the mouse, i installed the driver and opened the driver software, setting the mouse LED to a custom colour, and this set the LED as expected. The interesting thing was that after closing the virtual machine (and even powering off the host system), the mouse continued to stick to the same colour. So the mouse stored the colour value on the hardware itself as a persistent setting.
I left it at that for a day, being a simple solution, until i came across a forum post mentioning Wireshark has USB sniffing capabilities. After alot of searching i realised it might be possible to reverse engineer the device to control it from Linux natively. Despite having never done anything like this before.
The first thing to do was check which USB Bus the mouse was connected on, `lsusb‘ provides that information, and in my case it was Bus 009. So heading into Wireshark, i set the sniffer interface to usbmon9.
To avoid getting alot of spam information in the packet capture from other devices, i used a second connected mouse to perform any clicking whilst the packet capture was running, and also setting a filter rule within Wireshark like so:
The first step was to open the driver software, set a new colour for the LED, and then stop the packet capture. To my surprise i spotted the RGB colour value of the newly set colour in a datastream heading from the host to the USB mouse.
The colour i had set (as hexadecimal RGB) was FF8041
The relevant part of this datastream is:
The next step is to understand what the other information does. The colour value is surrounded by 00’s, assuming these are separators/padding. We then have 3 bytes left at the beginning, which i could only assume is a command to set the LED to the colour that follows.
I managed to whip up a small python script using PyUSB to interface with the mouse, that allowed this command to be sent to the mouse from within Linux natively.
Here’s an example showing how the request/command can be replayed, to tell the mouse to turn the LED blue:
The values for bmRequestType, bRequest, wValue and wIndex were all present in Wireshark for the captured frame. So simply filling them in the same here appeared to work.
To my amazement the mouse LED instantly turned blue! But there was a small issue. Upon rebooting / powering off the machine, or simply hotplugging the device, meant the mouse would reset to its default colour each time (or the last colour that was set from within the virtual machine).
I realised there must be another command which tells the mouse to store a persistent colour. So going through the packet capture log once again, trying anything that contained a datastream seemed like a logical approach.
Under Windows when setting the LED colour, the mouse flashes 5 times momentarily, and i hadn’t seen this from setting the LED colour through a PyUSB script.
I’d almost given up, after several hours of trying absolutely everything in the packet capture, but eventually found it:
Sending these 8 bytes to the mouse, triggered the LED to flash 5 times!
Hotplugging the mouse, now kept the colour persistent. Simply adjusting the ‘data’ variable to contain these 8 bytes worked flawlessly to store the colour onto the hardware as a persistent setting. I suppose it is like a “save” command.
I ended up putting together a slightly better script to set and store the LED colour of the mouse. You can get the code from my github repository here:
Or by cloning the repository directly from a terminal:
It’s as simple as running the below command, where each argument is the RGB value to set.
UPDATE:
I have since started working on a PyQt based interface to control more features easily, which includes a colorpicker widget, after cloning the git repository you can launch this by running:
It still needs some improvements, but should be useful for changing the settings more easily (including profile slots and polling rate!).
If this helped you with the BlackWeb AYA mouse on Linux (or helped with you reversing a different USB mouse) I’d love to hear about it! Cheers.