Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

G935 support #52

Closed
coxaka opened this issue Jul 27, 2023 · 20 comments
Closed

G935 support #52

coxaka opened this issue Jul 27, 2023 · 20 comments
Labels
new device support for new device

Comments

@coxaka
Copy link

coxaka commented Jul 27, 2023

I am trying to get output from a G935.
G935 is a headset that has buttons on the side which can be remapped in the Logitech software just like any other G-Key.

Unfortunately the newDeviceDebugger just throws an error:

usbVendor = 0x046d
usbProduct = 0x0a87
DEBUG: Searching for keyboard...
DEBUG: Keyboard found! :)
DEBUG: requesting USB endpoint...
Traceback (most recent call last):
  File "/tmp//keyboard-center/src/newDeviceDebugger.py", line 222, in <module>
    main()
  File "/tmp//keyboard-center/src/newDeviceDebugger.py", line 183, in main
    keyboardEndpoint: core.Endpoint = keyboard\
                                      ^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/usb/core.py", line 534, in __getitem__
    return Endpoint(
           ^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/usb/core.py", line 347, in __init__
    desc = backend.get_endpoint_descriptor(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/usb/backend/libusb1.py", line 798, in get_endpoint_descriptor
    ep_desc = i.endpoint[ep]
              ~~~~~~~~~~^^^^
ValueError: NULL pointer access

same output for --info
I also tested with my G815 which works without issues.

To me it seems like the G935 connects just like a keyboard since volume up and volume down "keypresses" are correctly being recognized in other software

Event: time 1690496964.584296, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00ea
Event: time 1690496964.584296, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 1
Event: time 1690496964.584296, -------------- SYN_REPORT ------------
Event: time 1690496964.783341, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00ea
Event: time 1690496964.783341, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 0
Event: time 1690496964.783341, -------------- SYN_REPORT ------------
Event: time 1690496965.985354, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e9
Event: time 1690496965.985354, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 1
Event: time 1690496965.985354, -------------- SYN_REPORT ------------
Event: time 1690496966.134346, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e9
Event: time 1690496966.134346, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 0
Event: time 1690496966.134346, -------------- SYN_REPORT ------------

@zocker-160 zocker-160 added the new device support for new device label Jul 28, 2023
@zocker-160
Copy link
Owner

Is your G935 connected wirelessly?

Getting this to work is going to be tricky. The error you see is because the script tries to find the USB endpoint of the device, which if connected via Bluetooth is not going to exist.

This issue is similar to the G915 (wireless version of G815), because the USB endpoint registered in the system is not actually the one of the keyboard, but it is the one of the USB dongle doing the connection.

Is it possible to connect the headphones via USB cable?

If yes it would be interesting if the USB endpoint can be found correctly or not.
If not, then could you give me the dmesg output when connecting your headphones?

You can do it like this:

  • make sure headphones are disconnected
  • run sudo dmesg -w
  • connect the headphones

It should show some output of the headphones registering in the kernel.

In general it is sadly quite tricky to add support for devices "remotely" since so far I have always needed to also reverse engineer the Windows driver in order to get command sequences needed to switch the device into host mode.

@coxaka
Copy link
Author

coxaka commented Jul 28, 2023

It is connected wireless with a dongle.
As far as I know you can only connect USB for charging

dmesg output:

[ 1344.560923] usb 1-5: new full-speed USB device number 9 using xhci_hcd
[ 1344.728220] usb 1-5: New USB device found, idVendor=046d, idProduct=0a87, bcdDevice= 1.12
[ 1344.728233] usb 1-5: New USB device strings: Mfr=3, Product=4, SerialNumber=0
[ 1344.728237] usb 1-5: Product: G935 Gaming Headset
[ 1344.728241] usb 1-5: Manufacturer: Logitech
[ 1345.069799] input: Logitech G935 Gaming Headset Consumer Control as /devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5:1.3/0003:046D:0A87.0009/input/input32
[ 1345.124631] input: Logitech G935 Gaming Headset as /devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5:1.3/0003:046D:0A87.0009/input/input33
[ 1345.124746] input: Logitech G935 Gaming Headset as /devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5:1.3/0003:046D:0A87.0009/input/input35
[ 1345.125116] hid-generic 0003:046D:0A87.0009: input,hiddev96,hidraw0: USB HID v1.11 Device [Logitech G935 Gaming Headset] on usb-0000:00:14.0-5/input3

@zocker-160
Copy link
Owner

Thank you for the dmesg, it is sadly the exact same problem / situation as with the G915 (#25).

Connecting to the USB dongle probably fails, because one or more of these parameters at the start of the script are not correct:

usbConfiguration = 0
usbInterface = (1, 0)
usbEndpoint = 0
disableGKeysInterface = 1
usbUseWrite = True

Sadly I cannot tell you which ones are needed for your device, every device is different, it is essentially a guessing game.

Once that works, it should be possible to find the correct HID endpoint and connect to it.

If you are lucky, the headphones will directly send raw data to that endpoint. If not (like it is the case with the G915) then I usually have to send one or more commands to the device to make it send the raw commands. Sadly as I already mentioned above, I had to find those out by reversing the Windows driver as Logitech does not document them publicly.

@coxaka
Copy link
Author

coxaka commented Jul 28, 2023

I managed to get the USB info by running

import usb.core
print(usb.core.find(idVendor=0x046d, idProduct=0x0a87))
Output
DEVICE ID 046d:0a87 on Bus 001 Address 010 =================
 bLength                :   0x12 (18 bytes)
 bDescriptorType        :    0x1 Device
 bcdUSB                 :  0x110 USB 1.1
 bDeviceClass           :    0x0 Specified at interface
 bDeviceSubClass        :    0x0
 bDeviceProtocol        :    0x0
 bMaxPacketSize0        :   0x40 (64 bytes)
 idVendor               : 0x046d
 idProduct              : 0x0a87
 bcdDevice              :  0x112 Device 1.12
 iManufacturer          :    0x3 Logitech
 iProduct               :    0x4 G935 Gaming Headset
 iSerialNumber          :    0x0 
 bNumConfigurations     :    0x1
  CONFIGURATION 1: 100 mA ==================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :  0x10d (269 bytes)
   bNumInterfaces       :    0x4
   bConfigurationValue  :    0x1
   iConfiguration       :    0x0 
   bmAttributes         :   0x80 Bus Powered
   bMaxPower            :   0x32 (100 mA)
    INTERFACE 0: Audio =====================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x0
     bInterfaceClass    :    0x1 Audio
     bInterfaceSubClass :    0x1
     bInterfaceProtocol :    0x0
     iInterface         :    0x1 G935 Gaming Headset
    INTERFACE 1: Audio =====================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x1
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x0
     bInterfaceClass    :    0x1 Audio
     bInterfaceSubClass :    0x2
     bInterfaceProtocol :    0x0
     iInterface         :    0x0 
    INTERFACE 1, 1: Audio ==================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x1
     bAlternateSetting  :    0x1
     bNumEndpoints      :    0x1
     bInterfaceClass    :    0x1 Audio
     bInterfaceSubClass :    0x2
     bInterfaceProtocol :    0x0
     iInterface         :    0x0 
      ENDPOINT 0x81: Isochronous IN ========================
       bLength          :    0x9 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x81 IN
       bmAttributes     :    0xd Isochronous
       wMaxPacketSize   :   0x90 (144 bytes)
       bInterval        :    0x1
    INTERFACE 2: Audio =====================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x2
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x0
     bInterfaceClass    :    0x1 Audio
     bInterfaceSubClass :    0x2
     bInterfaceProtocol :    0x0
     iInterface         :    0x0 
    INTERFACE 2, 1: Audio ==================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x2
     bAlternateSetting  :    0x1
     bNumEndpoints      :    0x0
     bInterfaceClass    :    0x1 Audio
     bInterfaceSubClass :    0x2
     bInterfaceProtocol :    0x0
     iInterface         :    0x0 
    INTERFACE 2, 2: Audio ==================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x2
     bAlternateSetting  :    0x2
     bNumEndpoints      :    0x1
     bInterfaceClass    :    0x1 Audio
     bInterfaceSubClass :    0x2
     bInterfaceProtocol :    0x0
     iInterface         :    0x0 
      ENDPOINT 0x2: Isochronous OUT ========================
       bLength          :    0x9 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x2 OUT
       bmAttributes     :    0xd Isochronous
       wMaxPacketSize   :  0x120 (288 bytes)
       bInterval        :    0x1
    INTERFACE 3: Human Interface Device ====================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x3
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x1
     bInterfaceClass    :    0x3 Human Interface Device
     bInterfaceSubClass :    0x0
     bInterfaceProtocol :    0x0
     iInterface         :    0x2 G935 Gaming Headset
      ENDPOINT 0x83: Interrupt IN ==========================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x83 IN
       bmAttributes     :    0x3 Interrupt
       wMaxPacketSize   :   0x20 (32 bytes)
       bInterval        :    0x1

Using interface 3 seems to work

usbConfiguration = 0
usbInterface = (3, 0)
usbEndpoint = 0
disableGKeysInterface = 3
usbUseWrite = True

DEBUG: Searching for keyboard...
DEBUG: Keyboard found! :)
DEBUG: requesting USB endpoint...
DEBUG: HIDraw read endpoint found: /dev/hidraw0
DEBUG: HIDraw disable endpoint found: /dev/hidraw0
DEBUG: HIDraw read endpoint found: /dev/hidraw0
DEBUG: HIDraw disable endpoint found: /dev/hidraw0
[...]
DEBUG: Checking for HID availability...
DEBUG: Connected to /dev/hidraw0
INFO: starting listener...
DEBUG: Using selector: EpollSelector
DEBUG: Connection using HIDAPI...
DEBUG: Sending sequence to disable G keys
0: b'\x11\xff\x10>\x00\x04\x00\x00\x00\x00\x00\x00\xd0\x01d\x07\x00\x00\x00\x00'
1: b'\x11\xff\x08.\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
DEBUG: listening to USB Interface (3, 0) | b'/dev/hidraw0'

Unfortunately only the mute and volume controls seem to be picked up.
I tried all known disableGKey commands but they dont seem to change anything


vol up
got data from keyboard: b'\x01\x01\x00\x00\x00'
got data from keyboard: b'\x01\x00\x00\x00\x00'
vol down
got data from keyboard: b'\x01\x02\x00\x00\x00'
got data from keyboard: b'\x01\x00\x00\x00\x00'
mute/unmute
got data from keyboard: b'\x01\x00\x00\x00\x00'

Oddly when toggling the LEDs or changing sidetone settings with other software like HeadsetControl the headset sends something back:

leds off
got data from keyboard: b'\x11\xff\x04<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
leds on
got data from keyboard: b'\x11\xff\x04<\x00\x02\x00\xb6\xff\x0f\xa0\x00d\x00\x00\x00\x00\x00\x00\x00'
sidetone off
got data from keyboard: b'\x11\xff\x07\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
sidetone max
got data from keyboard: b'\x11\xff\x07\x1ad\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

is there a method to finding the correct commands? or just poking around in a debugger?

@zocker-160
Copy link
Owner

zocker-160 commented Jul 28, 2023

Oh this is interesting, so Interfaces 0 - 2 are Audio, which makes sense and 3 is a HID device.

Does anything happen when you press the GKeys? In the case of the G915 the GKeys are mapped to F1-Fn by default is that also the case for you?

is there a method to finding the correct commands? or just poking around in a debugger?

Depends on the device. If your headset is supported by Logitech Ghub (not LGS), then my setup was a Windows VM with Logitech Ghub installed in it and Wireshark with the USB plugin (you have to check the USB thingy in the installer).

Then you have to listen on the USB port of the device and launch Ghub.

It will then send a bunch of data back and forth. Most important is the launch sequence and when you press any of the GKeys.

You can copy the bytes sent directly into the debugger script and check if it is working.

EDIT: how does the headset get listed in sudo evtest ? When listening to it, which buttons does it trigger when you press any of the GKeys?

@coxaka
Copy link
Author

coxaka commented Jul 30, 2023

evtest only triggers when using the volume wheel while newDeviceDebugger additionally shows mic mute events.

/dev/input/event3:      Logitech G935 Gaming Headset Consumer Control
/dev/input/event4:      Logitech G935 Gaming Headset
/dev/input/event5:      Logitech G935 Gaming Headset
3
Event: time 1690760103.022618, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e9
Event: time 1690760103.022618, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 1
Event: time 1690760103.022618, -------------- SYN_REPORT ------------
Event: time 1690760103.072615, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e9
Event: time 1690760103.072615, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 0
Event: time 1690760103.072615, -------------- SYN_REPORT ------------
Event: time 1690760105.924779, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00ea
Event: time 1690760105.924779, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 1
Event: time 1690760105.924779, -------------- SYN_REPORT ------------
Event: time 1690760105.974727, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00ea
Event: time 1690760105.974727, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 0

I'll check later if I can see something with wireshark

@coxaka
Copy link
Author

coxaka commented Jul 31, 2023

Progress :)

Using wireshark I found commands being sent from the host

Traffic
b'\x11\xff\x02\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x08\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x08\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x08\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x2a\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x2a\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x2a\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x1a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x2a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x2a\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x2a\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x2a\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\xca\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\xca\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x08\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x05\x2a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x7a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x8a\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x07\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\xca\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\xca\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x4a\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x07\x1a\x46\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x08\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x3a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x3a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x06\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x04\x4a\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x08\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x11\xff\x06\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',

putting these into the newDeviceDebugger actually seems to work and I can see the G buttons being pressed

from my testing only this packet seems to be required:

disableGKeys = [
    b'\x11\xff\x05\x2a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
]

which leads to these results:

G3 pressed
got data from keyboard: b'\x11\xff\x05\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
unpressed
got data from keyboard: b'\x11\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'


G2 pressed/unpressed
got data from keyboard: b'\x11\xff\x05\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
got data from keyboard: b'\x11\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

G1 pressed/unpressed
got data from keyboard: b'\x11\xff\x05\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
got data from keyboard: b'\x11\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

Mute button pressed
got data from keyboard: b'\x08\x01'

flick up microphone (mute)
got data from keyboard: b'\x08\x10'

flick down microphone (unmute)
got data from keyboard: b'\x08 '

lost connection to headset (turned off)
got data from keyboard: b'\x11\xff\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

headset connected
got data from keyboard: b'\x11\xff\x08\x00\x0ec\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
got data from keyboard: b'\x01\x00\x00\x00\x00'
got data from keyboard: b'\x01\x00\x00\x00\x00'

@zocker-160
Copy link
Owner

zocker-160 commented Jul 31, 2023

oh nice good job, this is exactly what I need!

Does mute / unmute actually work, as in does it trigger the mute / unmute system wide? If not, this could be added quite easily.

EDIT: does the mute button not send two packages? Usually there is a "pressed" and a "release" package

zocker-160 added a commit that referenced this issue Jul 31, 2023
@zocker-160
Copy link
Owner

I have pushed the initial implementation to the G935 branch, could you give it a try and see how far you can get?

@coxaka
Copy link
Author

coxaka commented Jul 31, 2023

I tested the G935 branch and it works like a charm.

Mute/unmute doesnt work, flicking up the microphone mutes it but there is no way to unmute it after that.
The mute button only sends one packet no matter if the microphone is muted or unmuted or if the button is pressed released or held.
I think it would be best to make the mute button also configurable since you mainly mute yourself by moving the microphone up.

Also if its not too hard to implement it would be great if the disableGKeys command can be sent everytime the headset connects (in case you turn the headset off or change batteries)

@coxaka
Copy link
Author

coxaka commented Jul 31, 2023

Another small nitpick: The order of the G buttons does not represent the physical layout, it should be G3, G2, G1, Mute

@zocker-160
Copy link
Owner

Mute/unmute doesnt work
I think it would be best to make the mute button also configurable since you mainly mute yourself by moving the microphone up.

Sorry this might be a dumb question, but are you talking about the headphone mute or the microphone mute?
You make it sound like they are the same thing and both mute the microphone?

flicking up the microphone mutes it but there is no way to unmute it after that.

This seems to be a known issue since forever and it looks like only hacky solutions exist. (see here for reference).
My hope is that uinput.KEY_MICMUTE does also unmute it, but it could get really messy as it would just toggle each time and not actually set on or off.

The mute button only sends one packet no matter if the microphone is muted or unmuted or if the button is pressed released or held.

Ok understood not a big issue, but weird given that all their keyboards do it.

Also if its not too hard to implement it would be great if the disableGKeys command can be sent everytime the headset connects (in case you turn the headset off or change batteries)

Sadly tricky to implement in the current codebase as this behavior does not exist with wired keyboard. A quick hack could be doable, but I fear that it might cause issues with existing users, so the proper way would be to implement an alternative mode for headphones (where I then could also treat the mute / unmute separately as currently mute is done by the kernel driver for all supported keyboard.

Another small nitpick: The order of the G buttons does not represent the physical layout, it should be G3, G2, G1, Mute

Do you mean just the order of the buttons in the UI or does G1 in the UI not map to the physical G1 button?

@coxaka
Copy link
Author

coxaka commented Jul 31, 2023

Sorry this might be a dumb question, but are you talking about the headphone mute or the microphone mute?
You make it sound like they are the same thing and both mute the microphone?

They both mute the microphone which is why I suggested making the button configurable.

This seems to be a known issue since forever and it looks like only hacky solutions exist. (see here for reference).
My hope is that uinput.KEY_MICMUTE does also unmute it, but it could get really messy as it would just toggle each time and not actually set on or off.

Actually it all works as expected until you disable G keys.
And when G keys are disabled and the microphone is stuck you can fix it by muting and unmuting e.g. by sending XF86AudioMicMute twice

Do you mean just the order of the buttons in the UI or does G1 in the UI not map to the physical G1 button?

It is mapped correctly, just the order in the UI is wrong

@zocker-160
Copy link
Owner

They both mute the microphone which is why I suggested making the button configurable.

Alright ok now I understand.

And when G keys are disabled and the microphone is stuck you can fix it by muting and unmuting e.g. by sending XF86AudioMicMute twice

Does mute / unmute after G keys disabled work at all? If yes, then that is the kernel driver doing it, which means remapping those buttons is not trivial. if no, then it should be fixable.

It is mapped correctly, just the order in the UI is wrong

Understood, well that is currently hard coded. :V

@coxaka
Copy link
Author

coxaka commented Jul 31, 2023

Does mute / unmute after G keys disabled work at all? If yes, then that is the kernel driver doing it, which means remapping those buttons is not trivial. if no, then it should be fixable.

with G keys disabled unmute doesnt work at all, mute only works when moving the microphone up, which is probably a firmware thing

@zocker-160
Copy link
Owner

ok one last question, does the mute button (the one you would like to remap) do anything after sending disableGKeys?

@coxaka
Copy link
Author

coxaka commented Aug 1, 2023

no it just sends data but doesnt mute or unmute the microphone
got data from keyboard: b'\x08\x01'

@zocker-160
Copy link
Owner

zocker-160 commented Aug 1, 2023

Alright understood, I will add the mute button as G4 then so you can remap it. (the names are hard coded for now, renaming them will require implementing a separate mode for that, which I currently don't have the time to do)

EDIT: ah damn I just realized that I cannot do that with the current logic, because there is no releaseEvent, so the moment you press the button it will get registered as you holding down the button all the time.

@zocker-160
Copy link
Owner

I pushed version 1.0.5 with initial support. For full support you will have to be a bit patient as I currently don't have the time to do it.

@coxaka
Copy link
Author

coxaka commented Aug 2, 2023

Awesome.
Take your time, the features you added already help a lot, the rest are just nice to haves.
Thanks for helping and thanks for writing this software!

@coxaka coxaka closed this as completed Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new device support for new device
Projects
None yet
Development

No branches or pull requests

2 participants