C
C#15mo ago
Vеrsette

❔ ✅ Trying to understand HID device response data

I have a wireless mouse that I'm trying to make my own software for. So far, it has been quite straightforward, and I have made most of the functions work as in the original software, but I can't seem to understand the format of the battery percentage response, or how it's converted to the numbers that the original software then shows.
46 Replies
Vеrsette
Vеrsette15mo ago
This is the data that I'm getting Initially, I thought that the bytes that change were the battery percentage, but that doesn't seem accurate, as they are different from the displayed number in the original software What kind of conversion could be done with this data to get the right values?
Alan Tas 𓆏
Alan Tas 𓆏15mo ago
With only these values is hard to know for sure, looking at 76%, 78%, 80% and 82%, that go up by two while the hex only goes up by one, makes me think the mouse doesn't report every single battery status value. Maybe with more values, specially having what represents 100%, this could be easier to guess
Vеrsette
Vеrsette15mo ago
I was thinking the same... I will wait until it discharges until ~20%, get the data, and then charge and get the data of 100%
JakenVeina
JakenVeina15mo ago
my only thought is that maybe it's a 7-bit scale? 0 to 127? even that doesn't quite line up with what you're seeing, but it's kinda close
Vеrsette
Vеrsette15mo ago
I figured it out!
int batteryPercentage;
if (resultValue > 85)
batteryPercentage = (resultValue - 85) * 30 / 15 + 60;
else
batteryPercentage = resultValue * 60 / 85;
int batteryPercentage;
if (resultValue > 85)
batteryPercentage = (resultValue - 85) * 30 / 15 + 60;
else
batteryPercentage = resultValue * 60 / 85;
Not sure why they would do it like this, but I got many other questions about their software anyway... Thanks for trying to help, I also haven't expected it to be this weird
Jester
Jester15mo ago
im interested in how you are directly communicating with a mouse, how did you do that?
Vеrsette
Vеrsette15mo ago
I'm really sorry for not answering earlier, I didn't get a notification of your message... I sort of reverse engineered the original program, to be able to understand how it works and requests/sends data to and from the mouse. I found that the original program was using a pretty common HID library for communication, https://github.com/libusb/hidapi, and that the command and response byte arrays always were 65 bytes long (requirement of the mouse, I think). First I send the command with hid_send_feature_report, then I wait 70ms for the mouse to process everything and prepare a response (it's possible to use a lower value, but I found that it works best with about 70ms), and then I get the answer with hid_get_feature_report
private byte[] SendCommand(byte[] commandBytes)
{
if (commandBytes.Length != 65)
throw new ArgumentException("Wrong command length. Array has to be 65 bytes long.");

_hidMouseDevice.WriteFeatureData(commandBytes);
Thread.Sleep(70);
_hidMouseDevice.ReadFeatureData(out var result);

if (result == null || result.Length == 0)
throw new Exception("Received empty response. Likely wrong device or the mouse didn't respond.");
if (result[1] != 0xA1)
throw new Exception("Received empty response. Maybe transferring data too quickly...");

return result;
}
private byte[] SendCommand(byte[] commandBytes)
{
if (commandBytes.Length != 65)
throw new ArgumentException("Wrong command length. Array has to be 65 bytes long.");

_hidMouseDevice.WriteFeatureData(commandBytes);
Thread.Sleep(70);
_hidMouseDevice.ReadFeatureData(out var result);

if (result == null || result.Length == 0)
throw new Exception("Received empty response. Likely wrong device or the mouse didn't respond.");
if (result[1] != 0xA1)
throw new Exception("Received empty response. Maybe transferring data too quickly...");

return result;
}
Vеrsette
Vеrsette15mo ago
For testing, I'm using https://github.com/mikeobrien/HidLibrary (that's why the function names are different, I had some issues with my hidapi wrapper that I am too lazy to fix for now), but I will switch back to hidapi after I get everything working and port to Avalonia UI for cross platform compatibility
GitHub
GitHub - mikeobrien/HidLibrary: This library enables you to enumera...
This library enables you to enumerate and communicate with Hid compatible USB devices in .NET. - GitHub - mikeobrien/HidLibrary: This library enables you to enumerate and communicate with Hid compa...
Jester
Jester15mo ago
nice, ill take a look
Accord
Accord15mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Jester
Jester15mo ago
@V3rzеT thank you so much to tell me about https://github.com/libusb/hidapi. now i can use my little drawing tablet without the bloated shitty drivers! it only sends 10 bytes at a time and it was pretty easy to figure out what each byte means peepoHappyHug
Buddy
Buddy15mo ago
You can also use this, https://freeusbanalyzer.com/ But very much uncertain how well it works. It's made by the same people who made Hex Editor Neo
Jester
Jester15mo ago
i can use my pen as a mouse now, not much but its something. nor does it work perfectly it worked yesterday but it doesnt today Shrugeg
Vеrsette
Vеrsette15mo ago
Are you still getting the same data output from it? I have had an issue with there being different paths available for opening the same device after enumerating it And only one of those paths is the right one (at least in the case of my mouse)
Jester
Jester15mo ago
it doesnt want to open the device anymore
Vеrsette
Vеrsette15mo ago
Are you on Linux or Windows? Does running your program as admin/superuser change anything?
Jester
Jester15mo ago
windows. idk id have to do some more experimenting
Vеrsette
Vеrsette15mo ago
Maybe also try to close the device first before opening it again, I'm not quite sure if it can be "left open" somehow, but it might work
Jester
Jester15mo ago
now it works again for some reason? Shrugeg
Vеrsette
Vеrsette15mo ago
Weird...
Accord
Accord15mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
senhor vilas bôas
@Vеrsette I'm interested in a simple script that communicates with my mouse and returns the battery level. Would you mind sharing this part of your code? I can't get mine to work
Vеrsette
Vеrsette9mo ago
What mouse are you using? There's no universal code for this, and my mouse is from a pretty small Chinese brand, so my code will for sure not work for yours You will need to read data from the original software and compare the values to see what changes in the mouse's response to indicate battery level, like I did here
Jester
Jester9mo ago
oh hi now this thread became back alive that reminded me i came back to my HID project to use my Wacom tablet as a mouse and its working great now. I didnt use the HID library this time but instead I open the device as a file with the win32 function CreateFile. then make a SafeFileHandle of the returned HANDLE and then a FileStream of that. now i have a loop where i ReadExact 10 bytes from the FileStream and it works great. Im planning on putting the project on github
Jester
Jester9mo ago
GitHub
ArduinoHidForWindows/examples/LampArray at main · microsoft/Arduino...
A public Arduino library with implementations for various Windows-compatible Human-Interface-Devices - microsoft/ArduinoHidForWindows
senhor vilas bôas
I'm using a chinese mouse as well: Delux M800 did you use a decompiler to get the original software code?
Vеrsette
Vеrsette9mo ago
I guess that's one way to do it)
senhor vilas bôas
I'm just willing to get a Windows notification whether my mouse is low battery
Vеrsette
Vеrsette9mo ago
I used a debugger and watched for calls to hidapi.dll (the library that the original program used)
Jester
Jester9mo ago
its surprisingly hard to create a window notification for some reason. ive been strugling with it
senhor vilas bôas
oh my lord...
Jester
Jester9mo ago
it should be simple in theory
Vеrsette
Vеrsette9mo ago
I think I used ToastManager from Windows.UI.Notifications previously with success
senhor vilas bôas
well, the first step is only to get the battery level at the terminal log, so I'll do further configurations gonna take a look
Jester
Jester9mo ago
yeah a very simple way to read from a device
senhor vilas bôas
I've seen some GitHub repositories where the code makes a task bar icon with the battery of the mouse, like a laptop battery indicator thanks for that! definitely gonna try out this
Vеrsette
Vеrsette9mo ago
I took a quick look, and if this is your mouse program, then it doesn't use hidapi.dll It uses hid.dll, which you can hook with something like Frida
No description
No description
senhor vilas bôas
which program did you use for hooking the api calls? oh, nice! so I was looking to the wrong way
Vеrsette
Vеrsette9mo ago
Frida • A world-class dynamic instrumentation toolkit
Frida • A world-class dynamic instrumentation toolkit
Observe and reprogram running programs on Windows, macOS, GNU/Linux, iOS, watchOS, tvOS, Android, FreeBSD, and QNX
Vеrsette
Vеrsette9mo ago
Attaching Interceptor to it with Module.findExportByName("hid.dll", 'HidD_GetFeature')
Accord
Accord9mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
senhor vilas bôas
I ended up giving up on this project. I've been trying for a while but I just can't get it to work... but I am very grateful for your help, @Vеrsette!
Jester
Jester9mo ago
here is my HID project with a different approach https://github.com/QubitTooLate/RawWacom
GitHub
GitHub - QubitTooLate/RawWacom: Small app to use a Wacom tablet as ...
Small app to use a Wacom tablet as a mouse. Contribute to QubitTooLate/RawWacom development by creating an account on GitHub.
Accord
Accord9mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
senhor vilas bôas
thanks for sharing this! I have a drawing tablet as well, so I'm gonna take a look
Accord
Accord8mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.