redragon-lights.py: fix USB reset errors

This commit is contained in:
Timothy Allen 2024-04-22 09:05:14 +02:00
parent adc87c0908
commit 33107098f3

View File

@ -8,8 +8,8 @@ import gi.repository.GLib
import pprint
import sys
import time
import traceback
import usb.core
#import traceback
# Redragon K621 Horus
vendor=0x258a
@ -168,17 +168,60 @@ def send_packets(kbd, switch):
try:
ret = kbd.ctrl_transfer(0x21, 0x09, 0x0306, 1, msg)
assert ret == len(msg)
# Prevent [Errno 32] Pipe error
#time.sleep(0.25)
# Prevent [Errno 32] Pipe error when running multiple commands, if we add any more ctrl_transfer()s after this one
time.sleep(0.25)
except usb.core.USBError as e:
print(e)
if e.errno == 16:
print("This issue needs more investigation... it may simply be previous invalid commands")
# The issue seems to be that the device configuration loses the report descriptors for interface 1 (the second interface)
# May need to reconfigure the device, or detach/reattach kernel driver, either for interface 0 or 0 _and_ 1
# if detaching/reattaching, swallow errors with try/except
reset_driver(kbd)
elif e.errno == 2:
print("Try unplugging and replugging the keyboard...")
sys.exit()
def reset_driver(kbd):
global debug
interfaces = list()
for cfg in kbd:
for intf in cfg:
interfaces.append(intf.bInterfaceNumber)
# Remove the driver
for intfNum in interfaces:
if kbd.is_kernel_driver_active(intfNum) is False:
print("kernel driver already detached")
else:
print("detaching kernel driver for interface {}".format(intfNum), flush=True)
try:
kbd.detach_kernel_driver(intfNum)
except usb.core.USBError as e:
print('Could not detach kernel driver: %s' % str(e), flush=True)
print(traceback.format_exc(), flush=True)
# Send a command (I think this is a short command to get the current keyboard state)
# This seems to reset things
msg = [ 0x05, 0x83, 0xc6, 0x00, 0x00, 0x00 ]
try:
print("trying to get kbd state")
ret = kbd.ctrl_transfer(0x21, 0x09, 0x0305, 1, msg)
#print(len(msg))
#print(ret)
assert ret == len(msg)
except:
pass
# Re-add driver
for intfNum in interfaces:
if kbd.is_kernel_driver_active(intfNum):
print("kernel driver already attached")
else:
print("reattaching kernel driver for interface {}".format(intfNum), flush=True)
try:
kbd.attach_kernel_driver(intfNum)
except usb.core.USBError as e:
print('Could not reattach kernel driver: %s' % str(e), flush=True)
if __name__ == '__main__':