117 lines
3.2 KiB
Python
Executable File
117 lines
3.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Debug script to test uhid communication
|
|
"""
|
|
import os
|
|
import sys
|
|
import struct
|
|
import time
|
|
|
|
UHID_CREATE2 = 11
|
|
|
|
# Simple HID descriptor for testing - just a joystick with X/Y
|
|
hid_descriptor = bytes([
|
|
0x05, 0x01, # Usage Page (Generic Desktop)
|
|
0x09, 0x04, # Usage (Joystick)
|
|
0xA1, 0x01, # Collection (Application)
|
|
0x09, 0x30, # Usage (X)
|
|
0x09, 0x31, # Usage (Y)
|
|
0x15, 0x00, # Logical Minimum (0)
|
|
0x26, 0xFF, 0x00, # Logical Maximum (255)
|
|
0x75, 0x08, # Report Size (8 bits)
|
|
0x95, 0x02, # Report Count (2)
|
|
0x81, 0x02, # Input (Data, Variable, Absolute)
|
|
0xC0 # End Collection
|
|
])
|
|
|
|
print("Testing UHID device creation...")
|
|
print(f"HID descriptor size: {len(hid_descriptor)} bytes")
|
|
|
|
try:
|
|
fd = os.open('/dev/uhid', os.O_RDWR | os.O_NONBLOCK)
|
|
print("✓ Opened /dev/uhid")
|
|
except PermissionError:
|
|
print("✗ Permission denied. Run with sudo.")
|
|
sys.exit(1)
|
|
except FileNotFoundError:
|
|
print("✗ /dev/uhid not found")
|
|
sys.exit(1)
|
|
|
|
# Build event according to kernel structure
|
|
name = b"Test Fake Wheel"
|
|
phys = b"fake-test"
|
|
uniq = b"test-001"
|
|
|
|
# Pack the create2 structure
|
|
# struct uhid_create2_req {
|
|
# __u8 name[128];
|
|
# __u8 phys[64];
|
|
# __u8 uniq[64];
|
|
# __u16 rd_size;
|
|
# __u16 bus;
|
|
# __u32 vendor;
|
|
# __u32 product;
|
|
# __u32 version;
|
|
# __u32 country;
|
|
# __u8 rd_data[HID_MAX_DESCRIPTOR_SIZE];
|
|
# }
|
|
|
|
event_data = struct.pack('<I', UHID_CREATE2) # Event type
|
|
|
|
create2_struct = (
|
|
name.ljust(128, b'\x00') +
|
|
phys.ljust(64, b'\x00') +
|
|
uniq.ljust(64, b'\x00') +
|
|
struct.pack('<HHIIII',
|
|
len(hid_descriptor), # rd_size (u16)
|
|
0x03, # bus (u16) - USB
|
|
0x046d, # vendor (u32) - Logitech
|
|
0xc24f, # product (u32) - G29
|
|
0x0111, # version (u32)
|
|
0x00 # country (u32)
|
|
) +
|
|
hid_descriptor.ljust(4096, b'\x00') # rd_data padded
|
|
)
|
|
|
|
print(f"Create2 struct size: {len(create2_struct)} bytes")
|
|
print(f"Event type: {UHID_CREATE2}")
|
|
|
|
# The full event needs to be 4096 bytes
|
|
full_event = event_data + create2_struct
|
|
if len(full_event) < 4096:
|
|
full_event = full_event.ljust(4096, b'\x00')
|
|
|
|
print(f"Full event size: {len(full_event)} bytes")
|
|
|
|
# Write to uhid
|
|
try:
|
|
bytes_written = os.write(fd, full_event)
|
|
print(f"✓ Wrote {bytes_written} bytes to /dev/uhid")
|
|
except Exception as e:
|
|
print(f"✗ Write failed: {e}")
|
|
os.close(fd)
|
|
sys.exit(1)
|
|
|
|
# Wait for kernel to process
|
|
print("Waiting for kernel to create device...")
|
|
time.sleep(1)
|
|
|
|
# Check if device appeared
|
|
print("\nChecking /proc/bus/input/devices:")
|
|
os.system("cat /proc/bus/input/devices | grep -A 5 'Test Fake' || echo 'Device not found'")
|
|
|
|
print("\nChecking dmesg for errors:")
|
|
os.system("sudo dmesg | tail -10 | grep -i 'uhid\|hid' || echo 'No relevant kernel messages'")
|
|
|
|
print("\nPress Ctrl+C to destroy device...")
|
|
try:
|
|
time.sleep(10)
|
|
except KeyboardInterrupt:
|
|
pass
|
|
|
|
# Cleanup
|
|
destroy_event = struct.pack('<I', 1).ljust(4096, b'\x00') # UHID_DESTROY = 1
|
|
os.write(fd, destroy_event)
|
|
os.close(fd)
|
|
print("✓ Device destroyed")
|