Files
Tools/fake-wheel/debug_uhid.py
T
2026-06-01 01:25:58 +01:00

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")