def xac_compatible_gamepad_hid_descriptor(report_id):
    data = HID_DEVICE_DATA["XAC_COMPATIBLE_GAMEPAD"]
    return hid.ReportDescriptor(
        description="XAC",
        report_descriptor=bytes(
            # This descriptor mimics the simple joystick from PDP that the XBox likes
            (0x05, data.usage_page,  #  Usage Page (Desktop),
             0x09, data.usage,       #  Usage (Gamepad),
             0xA1, 0x01,             #  Collection (Application),
            ) +
            ((0x85, report_id) if report_id != 0 else ()) +
            (0x15, 0x00,         #      Logical Minimum (0),
             0x25, 0x01,         #      Logical Maximum (1),
             0x35, 0x00,         #      Physical Minimum (0),
             0x45, 0x01,         #      Physical Maximum (1),
             0x75, 0x01,         #      Report Size (1),
             0x95, 0x08,         #      Report Count (8),
             0x05, 0x09,         #      Usage Page (Button),
             0x19, 0x01,         #      Usage Minimum (01h),
             0x29, 0x08,         #      Usage Maximum (08h),
             0x81, 0x02,         #      Input (Variable),
             0x05, 0x01,         #      Usage Page (Desktop),
             0x26, 0xFF, 0x00,   #      Logical Maximum (255),
             0x46, 0xFF, 0x00,   #      Physical Maximum (255),
             0x09, 0x30,         #      Usage (X),
             0x09, 0x31,         #      Usage (Y),
             0x75, 0x08,         #      Report Size (8),
             0x95, 0x02,         #      Report Count (2),
             0x81, 0x02,         #      Input (Variable),
             0xC0                #  End Collection
            )))
def consumer_hid_descriptor(report_id):
    data = HID_DEVICE_DATA["CONSUMER"]
    return hid.ReportDescriptor(
        description="CONSUMER",
        report_descriptor=bytes(
            # Consumer ("multimedia") keys
            (
                0x05,
                data.usage_page,  # Usage Page (Consumer)
                0x09,
                data.usage,  # Usage (Consumer Control)
                0xA1,
                0x01,  # Collection (Application)
            ) + ((0x85, report_id) if report_id != 0 else ()) + (
                0x75,
                0x10,  #   Report Size (16)
                0x95,
                0x01,  #   Report Count (1)
                0x15,
                0x01,  #   Logical Minimum (1)
                0x26,
                0x8C,
                0x02,  #   Logical Maximum (652)
                0x19,
                0x01,  #   Usage Minimum (Consumer Control)
                0x2A,
                0x8C,
                0x02,  #   Usage Maximum (AC Send)
                0x81,
                0x00,  #   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
                0xC0,  # End Collection
            )))
def gamepad_hid_descriptor(report_id):
    data = HID_DEVICE_DATA["GAMEPAD"]
    return hid.ReportDescriptor(
        description="GAMEPAD",
        report_descriptor=bytes(
            # Gamepad with 16 buttons and two joysticks
            (0x05, data.usage_page, # Usage Page (Generic Desktop Ctrls)
             0x09, data.usage,  # Usage (Game Pad)
             0xA1, 0x01,        # Collection (Application)
            ) +
            ((0x85, report_id) if report_id != 0 else ()) +
            (0x05, 0x09,        #   Usage Page (Button)
             0x19, 0x01,        #   Usage Minimum (Button 1)
             0x29, 0x10,        #   Usage Maximum (Button 16)
             0x15, 0x00,        #   Logical Minimum (0)
             0x25, 0x01,        #   Logical Maximum (1)
             0x75, 0x01,        #   Report Size (1)
             0x95, 0x10,        #   Report Count (16)
             0x81, 0x02,        #   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
             0x05, 0x01,        #   Usage Page (Generic Desktop Ctrls)
             0x15, 0x81,        #   Logical Minimum (-127)
             0x25, 0x7F,        #   Logical Maximum (127)
             0x09, 0x30,        #   Usage (X)
             0x09, 0x31,        #   Usage (Y)
             0x09, 0x32,        #   Usage (Z)
             0x09, 0x35,        #   Usage (Rz)
             0x75, 0x08,        #   Report Size (8)
             0x95, 0x04,        #   Report Count (4)
             0x81, 0x02,        #   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
             0xC0,              # End Collection
            )))
def throttlecontroller_hid_descriptor(report_id):
    data = HID_DEVICE_DATA["QUADRANT"]
    return hid.ReportDescriptor(
        description="QUADRANT",
        report_descriptor=bytes(
            # Gamepad with 16 buttons and two joysticks
            (0x05, data.usage_page, # Usage Page (Desktop Ctrls)
             0x09, data.usage,  # Usage (Joystick)
             0xA1, 0x01,        # Collection (Application)
            ) +
            ((0x85, report_id) if report_id != 0 else ()) +
            (0x09, 0x01, # Usage (Pointer)
            0xA1, 0x00, # Collection (Physical)
            0x09, 0x30, # Usage (X)
            0x09, 0x31, # Usage (Y)
            0x09, 0x32, # Usage (Z)
            0x15, 0x00, # Logical Minimum (0)
            0x26, 0xFF, 0x00, # Logical Maximum (255)
            0x75, 0x08, # Report Size (8)
            0x95, 0x03, # Report Count (3)
            0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0x05, 0x09, # Usage Page (Button)
            0x19, 0x01, # Usage Minimum (0x01)
            0x29, 0x09, # Usage Maximum (0x09)
            0x15, 0x00, # Logical Minimum (0)
            0x25, 0x01, # Logical Maximum (1)
            0x75, 0x01, # Report Size (1)
            0x95, 0x09, # Report Count (9)
            0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0x75, 0x07, # Report Size (7)
            0x95, 0x01, # Report Count (1)
            0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0xC0, # End Collection
            0xC0, # End Collection
            )))
def joystick_hid_descriptor(report_id):
    data = HID_DEVICE_DATA["JOYSTICK"]
    return hid.ReportDescriptor(
        description="JOYSTICK",
        report_descriptor=bytes(
            # Joystick with 3 buttons and 3 joysticks
            (0x05, data.usage_page, # Usage Page (Generic Desktop Ctrls)
             0x09, data.usage,  # Usage (Joystick)
             0xA1, 0x01,        # Collection (Application)
            ) +
            ((0x85, report_id) if report_id != 0 else ()) +
            (0x09, 0x01,        #   Usage (Pointer)
            0xA1, 0x00,        #   Collection (Physical)
            0x09, 0x30,        #     Usage (X)
            0x09, 0x31,        #     Usage (Y)
            0x15, 0x00,        #     Logical Minimum (0)
            0x26, 0xFF, 0x00,  #     Logical Maximum (255)
            0x35, 0x00,        #     Physical Minimum (0)
            0x46, 0xFF, 0x00,  #     Physical Maximum (255)
            0x75, 0x08,        #     Report Size (8)
            0x95, 0x02,        #     Report Count (2)
            0x81, 0x02,        #     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0x09, 0x32,        #     Usage (Z)
            0x15, 0x00,        #     Logical Minimum (0)
            0x26, 0xFF, 0x00,  #     Logical Maximum (255)
            0x35, 0x00,        #     Physical Minimum (0)
            0x46, 0x00, 0xFF,  #     Physical Maximum (-256)
            0x75, 0x08,        #     Report Size (8)
            0x95, 0x01,        #     Report Count (1)
            0x81, 0x02,        #     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0xC0,              #   End Collection
            0x05, 0x09,        #   Usage Page (Button)
            0x19, 0x01,        #   Usage Minimum (0x01)
            0x29, 0x03,        #   Usage Maximum (0x03)
            0x15, 0x00,        #   Logical Minimum (0)
            0x25, 0x01,        #   Logical Maximum (1)
            0x75, 0x01,        #   Report Size (1)
            0x95, 0x03,        #   Report Count (3)
            0x81, 0x02,        #   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0x75, 0x05,        #   Report Size (5)
            0x95, 0x01,        #   Report Count (1)
            0x81, 0x01,        #   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0xC0,              # End Collection
            )))
def mouse_hid_descriptor(report_id):
    data = HID_DEVICE_DATA["MOUSE"]
    return hid.ReportDescriptor(
        description="MOUSE",
        report_descriptor=bytes(
            # Regular mouse
            (0x05, data.usage_page, # Usage Page (Generic Desktop)
             0x09, data.usage,  # Usage (Mouse)
             0xA1, 0x01,        # Collection (Application)
             0x09, 0x01,        #   Usage (Pointer)
             0xA1, 0x00,        #   Collection (Physical)
            ) +
            ((0x85, report_id) if report_id != 0 else ()) +
            (0x05, 0x09,        #     Usage Page (Button)
             0x19, 0x01,        #     Usage Minimum (0x01)
             0x29, 0x05,        #     Usage Maximum (0x05)
             0x15, 0x00,        #     Logical Minimum (0)
             0x25, 0x01,        #     Logical Maximum (1)
             0x95, 0x05,        #     Report Count (5)
             0x75, 0x01,        #     Report Size (1)
             0x81, 0x02,        #     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
             0x95, 0x01,        #     Report Count (1)
             0x75, 0x03,        #     Report Size (3)
             0x81, 0x01,        #     Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
             0x05, 0x01,        #     Usage Page (Generic Desktop Ctrls)
             0x09, 0x30,        #     Usage (X)
             0x09, 0x31,        #     Usage (Y)
             0x15, 0x81,        #     Logical Minimum (-127)
             0x25, 0x7F,        #     Logical Maximum (127)
             0x75, 0x08,        #     Report Size (8)
             0x95, 0x02,        #     Report Count (2)
             0x81, 0x06,        #     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
             0x09, 0x38,        #     Usage (Wheel)
             0x15, 0x81,        #     Logical Minimum (-127)
             0x25, 0x7F,        #     Logical Maximum (127)
             0x75, 0x08,        #     Report Size (8)
             0x95, 0x01,        #     Report Count (1)
             0x81, 0x06,        #     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
             0xC0,              #   End Collection
             0xC0,              # End Collection
            )))
def raw_hid_descriptor(report_id):
    if report_id != 0:
        raise ValueError("raw hid must not have a report id")
    data = HID_DEVICE_DATA["RAW"]
    return hid.ReportDescriptor(
        description="RAW",
        report_descriptor=bytes(
            # Provide vendor-defined
            # This is a two-byte page value.
            (
                0x06,
                data.usage_page & 0xff,
                (data.usage_page >> 8)
                & 0xff,  #  Usage Page (Vendor 0xFFAF "Adafruit"),
                0x09,
                data.usage,  #  Usage (AF),
                0xA1,
                0x01,  #  Collection (Application),
                0x75,
                0x08,  #      Report Size (8),
                0x15,
                0x00,  #      Logical Minimum (0),
                0x26,
                0xFF,
                0x00,  #      Logical Maximum (255),
                0x95,
                0x08,  #      Report Count (8),
                0x09,
                0x01,  #      Usage(xxx)
                0x81,
                0x02,  #      Input (Variable)
                0x95,
                0x08,  #      Report Count (8),
                0x09,
                0x02,  #      Usage(xxx)
                0x91,
                0x02,  #      Input (Variable)
                0xC0  #  End Collection
            )))
def keyboard_hid_descriptor(report_id):
    data = HID_DEVICE_DATA["KEYBOARD"]
    return hid.ReportDescriptor(
        description="KEYBOARD",
        report_descriptor=bytes(
            # Regular keyboard
            (0x05, data.usage_page,      # Usage Page (Generic Desktop)
             0x09, data.usage,           # Usage (Keyboard)
             0xA1, 0x01,                 # Collection (Application)
            ) +
            ((0x85, report_id) if report_id != 0 else ()) +
            (0x05, 0x07,                 #   Usage Page (Keyboard)
             0x19, 224,                  #   Usage Minimum (224)
             0x29, 231,                  #   Usage Maximum (231)
             0x15, 0x00,                 #   Logical Minimum (0)
             0x25, 0x01,                 #   Logical Maximum (1)
             0x75, 0x01,                 #   Report Size (1)
             0x95, 0x08,                 #   Report Count (8)
             0x81, 0x02,                 #   Input (Data, Variable, Absolute)
             0x81, 0x01,                 #   Input (Constant)
             0x19, 0x00,                 #   Usage Minimum (0)
             0x29, 0xDD,                 #   Usage Maximum (221)
             0x15, 0x00,                 #   Logical Minimum (0)
             0x25, 0xDD,                 #   Logical Maximum (221)
             0x75, 0x08,                 #   Report Size (8)
             0x95, 0x06,                 #   Report Count (6)
             0x81, 0x00,                 #   Input (Data, Array)
             0x05, 0x08,                 #   Usage Page (LED)
             0x19, 0x01,                 #   Usage Minimum (1)
             0x29, 0x05,                 #   Usage Maximum (5)
             0x15, 0x00,                 #   Logical Minimum (0)
             0x25, 0x01,                 #   Logical Maximum (1)
             0x75, 0x01,                 #   Report Size (1)
             0x95, 0x05,                 #   Report Count (5)
             0x91, 0x02,                 #   Output (Data, Variable, Absolute)
             0x95, 0x03,                 #   Report Count (3)
             0x91, 0x01,                 #   Output (Constant)
             0xC0,                       # End Collection
            )))
def sys_control_hid_descriptor(report_id):
    data = HID_DEVICE_DATA["SYS_CONTROL"]
    return hid.ReportDescriptor(
        description="SYS_CONTROL",
        report_descriptor=bytes(
            # Power controls
            (0x05, data.usage_page, # Usage Page (Generic Desktop Ctrls)
             0x09, data.usage,  # Usage (Sys Control)
             0xA1, 0x01,        # Collection (Application)
            ) +
            ((0x85, report_id) if report_id != 0 else ()) +
            (0x75, 0x02,        #   Report Size (2)
             0x95, 0x01,        #   Report Count (1)
             0x15, 0x01,        #   Logical Minimum (1)
             0x25, 0x03,        #   Logical Maximum (3)
             0x09, 0x82,        #   Usage (Sys Sleep)
             0x09, 0x81,        #   Usage (Sys Power Down)
             0x09, 0x83,        #   Usage (Sys Wake Up)
             0x81, 0x60,        #   Input (Data,Array,Abs,No Wrap,Linear,No Preferred State,Null State)
             0x75, 0x06,        #   Report Size (6)
             0x81, 0x03,        #   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
             0xC0,              # End Collection
            )))
def digitizer_hid_descriptor(report_id):
    data = HID_DEVICE_DATA["DIGITIZER"]
    return hid.ReportDescriptor(
        description="DIGITIZER",
        report_descriptor=bytes(
            # Digitizer (used as an absolute pointer)
            (0x05, data.usage_page, # Usage Page (Digitizers)
             0x09, data.usage,  # Usage (Pen)
             0xA1, 0x01,        # Collection (Application)
            ) +
            ((0x85, report_id) if report_id != 0 else ()) +
            (0x09, 0x01,        #   Usage (Stylus)
             0xA1, 0x00,        #   Collection (Physical)
             0x09, 0x32,        #     Usage (In-Range)
             0x09, 0x42,        #     Usage (Tip Switch)
             0x09, 0x44,        #     Usage (Barrel Switch)
             0x09, 0x45,        #     Usage (Eraser Switch)
             0x15, 0x00,        #     Logical Minimum (0)
             0x25, 0x01,        #     Logical Maximum (1)
             0x75, 0x01,        #     Report Size (1)
             0x95, 0x04,        #     Report Count (4)
             0x81, 0x02,        #     Input (Data,Var,Abs)
             0x75, 0x04,        #     Report Size (4) -- Filler
             0x95, 0x01,        #     Report Count (1) -- Filler
             0x81, 0x01,        #     Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
             0x05, 0x01,        #     Usage Page (Generic Desktop Ctrls)
             0x15, 0x00,        #     Logical Minimum (0)
             0x26, 0xff, 0x7f,  #     Logical Maximum (32767)
             0x09, 0x30,        #     Usage (X)
             0x09, 0x31,        #     Usage (Y)
             0x75, 0x10,        #     Report Size (16)
             0x95, 0x02,        #     Report Count (2)
             0x81, 0x02,        #     Input (Data,Var,Abs)
             0xC0,              #   End Collection
             0xC0,              # End Collection
            )))
Beispiel #11
0
                bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
                bInterval=0)
        ]
    )
]

# When there's only one hid_device, it shouldn't have a report id.
# Otherwise, report ids are assigned sequentially:
# args.hid_devices[0] has report_id 1
# args.hid_devices[1] has report_id 2
# etc.

if len(args.hid_devices) == 1:
    name = args.hid_devices[0]
    combined_hid_report_descriptor = hid.ReportDescriptor(
        description=name,
        report_descriptor=bytes(hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](0)))
else:
    report_id = 1
    concatenated_descriptors = bytearray()
    for name in args.hid_devices:
        concatenated_descriptors.extend(
            bytes(hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](report_id)))
        report_id += 1
    combined_hid_report_descriptor = hid.ReportDescriptor(
        description="MULTIDEVICE",
        report_descriptor=bytes(concatenated_descriptors))

# ASF4 expects keyboard and generic devices to have both in and out endpoints,
# and will fail (possibly silently) if both are not supplied.
hid_endpoint_in_descriptor = standard.EndpointDescriptor(
KEYBOARD_WITH_ID = hid.ReportDescriptor(
    description="KEYBOARD",
    report_descriptor=bytes([
        # Regular keyboard
        0x05,
        0x01,  # Usage Page (Generic Desktop)
        0x09,
        0x06,  # Usage (Keyboard)
        0xA1,
        0x01,  # Collection (Application)
        0x85,
        REPORT_IDS["KEYBOARD"],  #   Report ID (1)
        0x05,
        0x07,  #   Usage Page (Keyboard)
        0x19,
        224,  #   Usage Minimum (224)
        0x29,
        231,  #   Usage Maximum (231)
        0x15,
        0x00,  #   Logical Minimum (0)
        0x25,
        0x01,  #   Logical Maximum (1)
        0x75,
        0x01,  #   Report Size (1)
        0x95,
        0x08,  #   Report Count (8)
        0x81,
        0x02,  #   Input (Data, Variable, Absolute)
        0x81,
        0x01,  #   Input (Constant)
        0x19,
        0x00,  #   Usage Minimum (0)
        0x29,
        101,  #   Usage Maximum (101)
        0x15,
        0x00,  #   Logical Minimum (0)
        0x25,
        101,  #   Logical Maximum (101)
        0x75,
        0x08,  #   Report Size (8)
        0x95,
        0x06,  #   Report Count (6)
        0x81,
        0x00,  #   Input (Data, Array)
        0x05,
        0x08,  #   Usage Page (LED)
        0x19,
        0x01,  #   Usage Minimum (1)
        0x29,
        0x05,  #   Usage Maximum (5)
        0x15,
        0x00,  #   Logical Minimum (0)
        0x25,
        0x01,  #   Logical Maximum (1)
        0x75,
        0x01,  #   Report Size (1)
        0x95,
        0x05,  #   Report Count (5)
        0x91,
        0x02,  #   Output (Data, Variable, Absolute)
        0x95,
        0x03,  #   Report Count (3)
        0x91,
        0x01,  #   Output (Constant)
        0xC0,  # End Collection
    ]))
Beispiel #13
0
                bInterval=0),
            standard.EndpointDescriptor(
                description="MSC out",
                bEndpointAddress=0x1 | standard.EndpointDescriptor.DIRECTION_OUT,
                bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
                bInterval=0)
        ]
    )
]

# Include only these HID devices.
# DIGITIZER works on Linux but conflicts with MOUSE, so leave it out for now.
hid_devices = ("KEYBOARD", "MOUSE", "CONSUMER", "GAMEPAD")

combined_hid_report_descriptor = hid.ReportDescriptor(
    description="MULTIDEVICE",
    report_descriptor=b''.join(
        hid_report_descriptors.REPORT_DESCRIPTORS[name].report_descriptor for name in hid_devices ))

hid_report_ids_dict = { name: hid_report_descriptors.REPORT_IDS[name] for name in hid_devices }
hid_report_lengths_dict = { name: hid_report_descriptors.REPORT_LENGTHS[name] for name in hid_devices }
hid_max_report_length = max(hid_report_lengths_dict.values())

# ASF4 expects keyboard and generic devices to have both in and out endpoints,
# and will fail (possibly silently) if both are not supplied.
hid_endpoint_in_descriptor = standard.EndpointDescriptor(
    description="HID in",
    bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
    bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
    bInterval=10)

hid_interfaces = [