greatscottgadgets / facedancer

Implement your own USB device in Python, supported by a hardware peripheral such as Cynthion or GreatFET
BSD 3-Clause "New" or "Revised" License
782 stars 116 forks source link

HIDReportDescriptor fields tuple does not submit the right values #121

Closed NustyFrozen closed 3 weeks ago

NustyFrozen commented 3 weeks ago

i am trying to make a mouse emulator i've been following this HIDReportDescriptor https://docs.kernel.org/hid/hidintro.html I took some code from the keyboard example since its somewhat similar and used the same tuple method

Here is the problem: when defining the INPUT 0x?? descriptor it is always INPUT 0x01

my code: `class ReportDescriptor(HIDReportDescriptor): fields : tuple = (

                # Identify ourselves as a keyboard.
                USAGE_PAGE       (HIDUsagePage.GENERIC_DESKTOP),
                USAGE            (HIDGenericDesktopUsage.MOUSE),
                COLLECTION       (HIDCollection.APPLICATION),
                USAGE       (HIDGenericDesktopUsage.POINTER),
                COLLECTION       (HIDCollection.PHYSICAL),
                USAGE_PAGE       (HIDUsagePage.BUTTONS),

                # Modifier keys.
                # These span the full range of modifier key codes (left control to right meta),
                # and each has two possible values (0 = unpressed, 1 = pressed).
                USAGE_MINIMUM    (0x01),
                USAGE_MAXIMUM    (0x03),
                LOGICAL_MINIMUM  (0),
                LOGICAL_MAXIMUM  (1),
                REPORT_SIZE      (1),
                REPORT_COUNT     (0x03),
                INPUT            (0x02), **<-- PROBLEM HERE**

                # One byte of constant zero-padding.
                # This is required for compliance; and Windows will ignore this report
                # if the zero byte isn't present.
                REPORT_SIZE      (0x05),
                REPORT_COUNT     (0x01),
                INPUT            (0x01),

                # Capture our actual, pressed keyboard keys.
                # Support a standard, 101-key keyboard; which has
                # keycodes from 0 (NONE) to 101 (COMPOSE).
                #
                # We provide the capability to press up to eight keys
                # simultaneously. Setting the REPORT_COUNT effectively
                # sets the key rollover; so 8 reports means we can have
                # up to eight keys pressed at once.
                USAGE_PAGE    (0x01),
                USAGE    (0x30),
                USAGE  (0x31),
                USAGE  (0x38),

                LOGICAL_MINIMUM  (0x81),
                LOGICAL_MAXIMUM  (0x7f),
                REPORT_SIZE      (0x08),
                REPORT_COUNT     (0x03),
                INPUT            (0x06), **<-- PROBLEM HERE**

                # End the report.
                END_COLLECTION   (),
                END_COLLECTION   (),
            )`

expected hexdump results (like from the website mention above): 00000000 05 01 09 02 a1 01 09 01 a1 00 05 09 19 01 29 03 |..............).| 00000010 15 00 25 01 75 01 95 03 81 02 75 05 95 01 81 01 |..%.u.....u.....| 00000020 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 |...0.1.8..%.u...| 00000030 81 06 c0 c0 |....| 00000034

actually got: 0x5 0x1 0x9 0x2 0xa1 0x1 0x9 0x1 0xa1 0x0 0x5 0x9 0x19 0x1 0x29 0x3 0x15 0x0 0x25 0x1 0x75 0x1 0x95 0x3 0x81 0x1 0x75 0x5 0x95 0x1 0x81 0x1 0x5 0x1 0x9 0x30 0x9 0x31 0x9 0x38 0x15 0x81 0x25 0x7f 0x75 0x8 0x95 0x3 0x81 0x1

(bolded the problem)

I defined in the code 0X81 0X02 == INPUT (0x02) but still got 0X81 0X01 same problem with 0X81 0X06

code used to hexdump (in case its something with the way I am converting the tuple to hex struct) for tup in fields: (x,y) = tup print(hex(x) + ' ' + hex(y),end=" ")

I am not sure what is causing the issue but thought I would just point it out there and also maybe get a fix

miek commented 3 weeks ago

I think there's just a misunderstanding about how INPUT field is supposed to be used. INPUT is a wrapper around the hid_io_item function and should be called with arguments like constant=True/False or variable=True/False rather than a integer constant.

For example, if you're looking to get 0x81 0x02 then according to the description in the HID spec, that's a prefix of 0x81 to indicate an Input item with a 1-byte data item, and then the data item is 0x02 to indicate that the variable bit is set. So you'd write INPUT(variable=True).

hidspec-items

NustyFrozen commented 3 weeks ago

you are correct i misunderstood how it works works like a charm now