Adds support for a new G PRO X2 variant#478
Adds support for a new G PRO X2 variant#478ChrisLauinger77 wants to merge 1 commit intoSapd:masterfrom
Conversation
|
I added the deviceID as described and compiled it. |
|
after reboot - it times even out .... |
|
No other way but to capture the packets the original software sends using wireshark |
Does it really need to be wireshark on windows ? I have a macbook ... |
When I remember it right on a Mac it was difficult because of the kernel protections. Best thing there is to use a virtual machine with windows and pass through the usb device to it |
Alright - VM it is then |
|
Try again:
|
|
better ? |
|
maybe also valueable info: |
|
@ChrisLauinger77 do you know at which battery percentage you were on your latest capture? and was it loading or discharging? |
|
52% not plugged in. So discharging |
|
Not 100% sure but could be The response should be then: |
|
|
made a capture during charging - saw also in UI that it went from 52% to 54% |
|
Cant really see the battery status in there, is interrupt IN included too? You can also try repeadtly |
|
|
Looked into it but cannot find it, you probably need to run it with a loop over longer time and while opening the driver application |
|
Hmm ... I get on windows where the driver application is running (headsetcontrol is the artefact from this PR) |
|
when I use the released version of headsetcontrol I get |
|
With other versions too? Not sure what could have caused that in code |
No success on windows with 2 versions. I could also try older releases ... |
|
I checked it a bit The Windows issue is that this device variant (0x0af7) exposes completely different HID usage pages than the other G PRO variants. From your --dev --list output: But the LogitechGPro class hardcodes usagepage=0xff43, usageid=0x0202 for battery/inactive time (which doesn't exist on your device at all) On Windows, the code tries to match that usage page first, fails, then falls back to opening the first enumerated HID endpoint (the 0x000c consumer controls one), which is wrong that's why --dev --send fails with "Failed to send". On Linux it doesn't matter because all three entries resolve to the same /dev/hidraw3, so the timeout there is a separate protocol issue (probably the battery command itself being different). Could you run --dev --list on Windows too? I'd like to see what usage pages/interfaces it enumerates there they might differ from Linux. That would tell us which usagepage/usageid to set for this variant. |
|
|
Try both headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xffa0:0x0001 --send "0x06 0x0d" --receive headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 --send "0x06 0x0d" --receive |
|
Adds a new device ID for a previously unsupported variant of the Logitech G PRO X2.
|
Any enlightenment on this one ? |
|
So that receive hangs is basically "normal" it waits for input. But that also means that the send command is not the correct one. |
|
Anything else I can do ? Some setting in wireshark ? |
Systematic Battery Testing GuideBased on research into Solaar's codebase and the HID++ protocol, here are test commands to try. The goal is to identify which battery command works with your new firmware. BackgroundYour device (0x0af7) has different USB endpoints than other G PRO X2 variants:
The firmware update likely switched from HID++ 1.0 to HID++ 2.0 protocol, which is why old battery commands don't work. Test Commands (Linux)Run these sequentially and report the output for each. All commands are safe read-only operations. Test 1: Feature Discovery (HID++ 2.0)This discovers which features your headset supports: # Using 0xff13 endpoint:
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 \
--send "0x11 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
# Using 0xffa0 endpoint:
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xffa0:0x0001 \
--send "0x11 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receiveExpected: A response showing feature count or feature table. Test 2: Old Battery Command with New EndpointsTry the existing battery command ( # With 0xff13:
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 \
--send "0x11 0xFF 0x06 0x0d 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
# With 0xffa0:
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xffa0:0x0001 \
--send "0x11 0xFF 0x06 0x0d 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receiveTest 3: HID++ 2.0 Battery FeaturesThese are standard HID++ 2.0 battery commands used by Solaar: # BATTERY_STATUS (0x1000) - Try feature indices 0x01 through 0x10
# Feature index 0x01:
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 \
--send "0x11 0xFF 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
# Feature index 0x02:
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 \
--send "0x11 0xFF 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
# Feature index 0x03:
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 \
--send "0x11 0xFF 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
# Feature index 0x04:
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 \
--send "0x11 0xFF 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
# Feature index 0x05:
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 \
--send "0x11 0xFF 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receiveTest 4: Alternative Battery CommandsTry other known Logitech battery commands: # Battery command variant 1 (0x08 0x0a):
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 \
--send "0x11 0xFF 0x08 0x0a 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
# Battery command variant 2 (0x08 0x11):
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 \
--send "0x11 0xFF 0x08 0x11 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
# Short message format (0x10 instead of 0x11):
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 \
--send "0x10 0xFF 0x06 0x0d 0x00 0x00 0x00" --receiveTest 5: Listen for Asynchronous Battery UpdatesBattery might be sent automatically by the device: # Just listen for incoming data (run for 30 seconds while battery % changes):
timeout 30 headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 --receiveTry this while:
What to ReportFor each command, please share:
Also note your current battery % from G Hub when testing. Next StepsOnce we identify a working command, I'll update the HeadsetControl code to use the correct protocol for your variant. Related Research: |
Windows Version of Test CommandsSince you mentioned Windows issues, here are the same commands formatted for Windows Command Prompt: Test 1: Feature Discoveryheadsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 --send "0x11 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receiveTest 2: Old Battery Command with New Endpointheadsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 --send "0x11 0xFF 0x06 0x0d 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receiveTest 3: Try Feature Indices 0x01-0x05REM Feature index 0x01
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 --send "0x11 0xFF 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
REM Feature index 0x02
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 --send "0x11 0xFF 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
REM Feature index 0x03
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 --send "0x11 0xFF 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
REM Feature index 0x04
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 --send "0x11 0xFF 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
REM Feature index 0x05
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 --send "0x11 0xFF 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receiveTest 4: Alternative Battery CommandsREM Battery variant 0x08 0x0a
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 --send "0x11 0xFF 0x08 0x0a 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive
REM Short message format
headsetcontrol --dev -- --device 0x046d:0x0af7 --interface 3 --usage 0xff13:0x0001 --send "0x10 0xFF 0x06 0x0d 0x00 0x00 0x00" --receiveImportant Note for WindowsIf you see "Failed to send: WriteFile" errors, it means the usage page is wrong. The If all commands fail on Windows, try:
The G Hub software might be holding an exclusive lock on the HID device. |
Automated Test ScriptTo make testing easier, here's a script that runs all commands and saves results to a file. Linux/macOS ScriptSave as #\!/bin/bash
DEVICE="0x046d:0x0af7"
INTERFACE="3"
USAGE="0xff13:0x0001"
OUTPUT="battery_test_results.txt"
echo "HeadsetControl Battery Test Results" > $OUTPUT
echo "Device: $DEVICE" >> $OUTPUT
echo "Date: $(date)" >> $OUTPUT
echo "Battery level from G Hub: [PLEASE FILL IN]" >> $OUTPUT
echo "========================================" >> $OUTPUT
echo "" >> $OUTPUT
run_test() {
local name="$1"
local cmd="$2"
echo "Testing: $name" | tee -a $OUTPUT
echo "Command: $cmd" >> $OUTPUT
timeout 5s bash -c "$cmd" >> $OUTPUT 2>&1
local result=$?
if [ $result -eq 0 ]; then
echo "✅ SUCCESS" | tee -a $OUTPUT
elif [ $result -eq 124 ]; then
echo "⏱️ TIMEOUT" | tee -a $OUTPUT
else
echo "❌ ERROR (code $result)" | tee -a $OUTPUT
fi
echo "" >> $OUTPUT
echo "----------------------------------------" >> $OUTPUT
echo "" >> $OUTPUT
}
echo "Running battery tests... (this will take ~2 minutes)"
echo ""
# Test 1: Feature Discovery
run_test "Feature Discovery (0xff13)" \
"headsetcontrol --dev -- --device $DEVICE --interface $INTERFACE --usage $USAGE --send '0x11 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00' --receive"
# Test 2: Old battery command
run_test "Old Battery Command (0x06 0x0d)" \
"headsetcontrol --dev -- --device $DEVICE --interface $INTERFACE --usage $USAGE --send '0x11 0xFF 0x06 0x0d 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00' --receive"
# Test 3: Try feature indices
for idx in 01 02 03 04 05 06 07 08; do
run_test "Feature Index 0x$idx" \
"headsetcontrol --dev -- --device $DEVICE --interface $INTERFACE --usage $USAGE --send '0x11 0xFF 0x$idx 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00' --receive"
done
# Test 4: Alternative commands
run_test "Battery Variant (0x08 0x0a)" \
"headsetcontrol --dev -- --device $DEVICE --interface $INTERFACE --usage $USAGE --send '0x11 0xFF 0x08 0x0a 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00' --receive"
run_test "Short Message Format" \
"headsetcontrol --dev -- --device $DEVICE --interface $INTERFACE --usage $USAGE --send '0x10 0xFF 0x06 0x0d 0x00 0x00 0x00' --receive"
# Test with 0xffa0 endpoint
USAGE2="0xffa0:0x0001"
run_test "Feature Discovery (0xffa0)" \
"headsetcontrol --dev -- --device $DEVICE --interface $INTERFACE --usage $USAGE2 --send '0x11 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00' --receive"
echo ""
echo "Testing complete\! Results saved to: $OUTPUT"
echo "Please attach this file to the PR."Usage: chmod +x test_battery.sh
./test_battery.sh
# Wait ~2 minutes, then upload battery_test_results.txtWindows Batch ScriptSave as @echo off
setlocal enabledelayedexpansion
set DEVICE=0x046d:0x0af7
set INTERFACE=3
set USAGE=0xff13:0x0001
set OUTPUT=battery_test_results.txt
echo HeadsetControl Battery Test Results > %OUTPUT%
echo Device: %DEVICE% >> %OUTPUT%
echo Date: %DATE% %TIME% >> %OUTPUT%
echo Battery level from G Hub: [PLEASE FILL IN] >> %OUTPUT%
echo ======================================== >> %OUTPUT%
echo. >> %OUTPUT%
echo Running battery tests...
echo.
REM Test 1: Feature Discovery
echo Testing: Feature Discovery >> %OUTPUT%
headsetcontrol --dev -- --device %DEVICE% --interface %INTERFACE% --usage %USAGE% --send "0x11 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive >> %OUTPUT% 2>&1
echo. >> %OUTPUT%
echo ---------------------------------------- >> %OUTPUT%
echo. >> %OUTPUT%
REM Test 2: Old battery command
echo Testing: Old Battery Command >> %OUTPUT%
headsetcontrol --dev -- --device %DEVICE% --interface %INTERFACE% --usage %USAGE% --send "0x11 0xFF 0x06 0x0d 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive >> %OUTPUT% 2>&1
echo. >> %OUTPUT%
echo ---------------------------------------- >> %OUTPUT%
echo. >> %OUTPUT%
REM Test 3: Feature indices
for %%i in (01 02 03 04 05 06 07 08) do (
echo Testing: Feature Index 0x%%i >> %OUTPUT%
headsetcontrol --dev -- --device %DEVICE% --interface %INTERFACE% --usage %USAGE% --send "0x11 0xFF 0x%%i 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00" --receive >> %OUTPUT% 2>&1
echo. >> %OUTPUT%
echo ---------------------------------------- >> %OUTPUT%
echo. >> %OUTPUT%
)
echo.
echo Testing complete\! Results saved to: %OUTPUT%
echo Please attach this file to the PR.
pauseUsage: test_battery.bat
REM Wait for completion, then upload battery_test_results.txtBoth scripts will create a file with all test results that you can easily attach to this PR for analysis. |
Summary: Why These Tests?@ChrisLauinger77 I've posted a comprehensive testing guide above based on research into Solaar (the Linux Logitech device manager) and the official HID++ protocol. The Core IssueYour device variant (
What ChangedIssue #477 confirms that your exact device used to work but stopped after a firmware update. This strongly suggests Logitech switched the battery protocol from HID++ 1.0 to HID++ 2.0 in newer firmware. The Solution PathHID++ 2.0 uses feature-based commands instead of direct register access:
The test commands I provided systematically try:
What Success Looks LikeWhen you find the right command, you'll get a response like: Once we identify the working command, I can help update the code to:
Research SourcesThis testing approach is based on:
@Sapd Let me know if you'd like me to start implementing HID++ 2.0 support in HeadsetControl while we wait for Christian's test results. It could benefit other Logitech devices too. |
|
Thx you so much - I start working on that today after work. |
|
Test best on Linux first. To be fully transparent, I used Claude AI for comment and research. But the steps make completely sense |
|
win.zip |
|
On windows I have the wrong exe - I fix it and retry ... |
|
win.zip |
|
On mac timeout needs to be gtimeout |





Adds a new device ID for a previously unsupported variant
of the Logitech G PRO X2.