Author Topic: Problem with report descriptor?  (Read 10683 times)

jeffcarl1

  • Member
  • ***
  • Posts: 2
Problem with report descriptor?
« on: May 14, 2015, 11:18:31 am »
I remember seeing on a janaxelson related website about using multiple mouse in programs. Well, I am trying to get a report descriptor right but I believe I might have done something wrong. Anyone willing to take a look?
Its a really a simple report descriptor in which an intermediate device passes input down the chain to a mouse device its connected to. I have an error somewhere in the code descriptor or driver code but I believe its in the descriptor. I can post what it returns for the usage too if anyone needs it.
Here's the report descriptor:

Code: [Select]
HID_REPORT_DESCRIPTOR           G_DefaultReportDescriptor[] = {
0x06, 0x00,0xFF,     // (GLOBAL) USAGE_PAGE         0xFF00 Vendor-defined
0x09, 0x01,       // (LOCAL)  USAGE              0xFF000001
0xA1, 0x01,        //(MAIN)   COLLECTION         0x01 Application (Usage=0xFF000001: Page=Vendor-defined, Usage=, Type=)
0x85, 0x0F,         // (GLOBAL) REPORT_ID          0x0F (15)
0x09, 0x01,         // (LOCAL)  USAGE              0xFF000001
0x15, 0x00,        //  (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
0x26, 0xFF,0x00,      //  (GLOBAL) LOGICAL_MAXIMUM    0x00FF (255)
0x75, 0x08,          //(GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field
0x95, 0x09,         // go back to (GLOBAL) REPORT_COUNT       0x0009 (9) Number of fields
0xB1, 0x00,         // (MAIN)   FEATURE            0x00000000 (9 fields x 8 bits) 0=Data 0=Array 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap
0x09, 0x01,         // (LOCAL)  USAGE              0xFF000001
0x95, 0x01,       // go back to (GLOBAL) REPORT_COUNT       0x0001 (1) Number of fields
0x81, 0x00,        //  (MAIN)   INPUT              0x00000000 (1 field x 8 bits) 0=Data 0=Array 0=Absolute 0=Ignored 0=Ignored 0=PrefState 0=NoNull
0x09, 0x01,          //(LOCAL)  USAGE              0xFF000001
0x95, 0x07,     // (GLOBAL) REPORT_COUNT       0x0007 (7) Number of fields
0x91, 0x00,        //(MAIN)   OUTPUT             0x00000000 (7 fields x 8 bits) 0=Data 0=Array 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap
0xC0,          //(MAIN)   END_COLLECTION     Application
0x05, 0x01,       // (GLOBAL) USAGE_PAGE         0x0001 Generic Desktop Page
0x09, 0x02,       // (LOCAL)  USAGE              0x00010002 Mouse (CA=Application Collection)
0xA1, 0x01,       // (MAIN)   COLLECTION         0x01 Application (Usage=0x00010002: Page=Generic Desktop Page, Usage=Mouse, Type=CA)
0x09, 0x01,       // (LOCAL)  USAGE              0x00010001 Pointer (CP=Physical Collection)
0xA1, 0x02,       // (MAIN)   COLLECTION         0x02 Logical (Usage=0x00010001: Page=Generic Desktop Page, Usage=Pointer, Type=CP) <-- Warning: USAGE type should be CL (Logical)
0x05, 0x0A,       // (GLOBAL) USAGE_PAGE         0x000A Ordinal Page
0x09, 0x01,       // (LOCAL)  USAGE              0x000A0001 Instance 1 (UM=Usage Modifier)
0x85, 0x01,       // (GLOBAL) REPORT_ID          0x01 (1)
0xA1, 0x00,      //  (MAIN)   COLLECTION         0x00 Physical (Usage=0x000A0001: Page=Ordinal Page, Usage=Instance 1, Type=UM) <-- Warning: USAGE type should be CP (Physical)
0x05, 0x09,      //    (GLOBAL) USAGE_PAGE         0x0009 Button Page
0x19, 0x01,      // (LOCAL)  USAGE_MINIMUM      0x00090001 Button 1 Primary/trigger (MULTI=Selector, On/Off, Momentary, or One Shot)
0x29, 0x03,      //  (LOCAL)  USAGE_MAXIMUM      0x00090003 Button 3 Tertiary (MULTI=Selector, On/Off, Momentary, or One Shot)
0x15, 0x00,     //  (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
0x25, 0x01,     //  (GLOBAL) LOGICAL_MAXIMUM    0x01 (1)
0x75, 0x01,     //   (GLOBAL) REPORT_SIZE        0x01 (1) Number of bits per field
0x95, 0x03,      //  (GLOBAL) REPORT_COUNT       0x03 (3) Number of fields
0x81, 0x02,        // (MAIN)   INPUT              0x00000002 (3 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap
0x95, 0x05,      //   (GLOBAL)REPORT_COUNT       0x05 (5) Number of fields
0x81, 0x03,       //   (MAIN)INPUT              0x00000003 (5 fields x 1 bit) 1 = Constant 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x05, 0x01,       //       (GLOBAL)USAGE_PAGE         0x0001 Generic Desktop Page
0x09, 0x30,       //       (LOCAL)USAGE              0x00010030 X(DV = Dynamic Value)
0x09, 0x31,       //       (LOCAL)USAGE              0x00010031 Y(DV = Dynamic Value)
0x15, 0x81,       //      (GLOBAL)LOGICAL_MINIMUM    0x81 (-127)
0x25, 0x7F,       //       (GLOBAL)LOGICAL_MAXIMUM    0x7F (127)
0x75, 0x08,       //       (GLOBAL)REPORT_SIZE        0x08 (8) Number of bits per field
0x95, 0x02,       //       (GLOBAL)REPORT_COUNT       0x02 (2) Number of fields
0x81, 0x06,       //       (MAIN)INPUT              0x00000006 (2 fields x 8 bits) 0 = Data 1 = Variable 1 = Relative 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0xC0,  // END_COLLECTION     Physical
0x05, 0x0A,        //   (GLOBAL)USAGE_PAGE         0x000A Ordinal Page
0x09, 0x02,         //   (LOCAL)USAGE              0x000A0002 Instance 2 (UM = Usage Modifier)
0x85, 0x02,        //    (GLOBAL)REPORT_ID          0x02 (2)
0xA1, 0x00,        //    (MAIN)COLLECTION         0x00 Physical(Usage = 0x000A0002: Page = Ordinal Page, Usage = Instance 2, Type = UM) < --Warning: USAGE type should be CP(Physical)
0x05, 0x09,         //     (GLOBAL)USAGE_PAGE         0x0009 Button Page
0x19, 0x01,         //     (LOCAL)USAGE_MINIMUM      0x00090001 Button 1 Primary / trigger(MULTI = Selector, On / Off, Momentary, or One Shot)
0x29, 0x03,         //     (LOCAL)USAGE_MAXIMUM      0x00090003 Button 3 Tertiary(MULTI = Selector, On / Off, Momentary, or One Shot)
0x15, 0x00,       //       (GLOBAL)LOGICAL_MINIMUM    0x00 (0)
0x25, 0x01,       //       (GLOBAL)LOGICAL_MAXIMUM    0x01 (1)
0x75, 0x01,       //       (GLOBAL)REPORT_SIZE        0x01 (1) Number of bits per field
0x95, 0x03,       //       (GLOBAL)REPORT_COUNT       0x03 (3) Number of fields
0x81, 0x02,       //       (MAIN)INPUT              0x00000002 (3 fields x 1 bit) 0 = Data 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x95, 0x05,       //       (GLOBAL)REPORT_COUNT       0x05 (5) Number of fields
0x81, 0x03,       //       (MAIN)INPUT              0x00000003 (5 fields x 1 bit) 1 = Constant 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x05, 0x01,       //       (GLOBAL)USAGE_PAGE         0x0001 Generic Desktop Page
0x09, 0x30,       //       (LOCAL)USAGE              0x00010030 X(DV = Dynamic Value)
0x09, 0x31,       //       (LOCAL)USAGE              0x00010031 Y(DV = Dynamic Value)
0x15, 0x81,       //       (GLOBAL)LOGICAL_MINIMUM    0x81 (-127)
0x25, 0x7F,       //       (GLOBAL)LOGICAL_MAXIMUM    0x7F (127)
0x75, 0x08,       //       (GLOBAL)REPORT_SIZE        0x08 (8) Number of bits per field
0x95, 0x02,       //       (GLOBAL)REPORT_COUNT       0x02 (2) Number of fields
0x81, 0x06,           //   (MAIN)INPUT              0x00000006 (2 fields x 8 bits) 0 = Data 1 = Variable 1 = Relative 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0xC0,       // END_COLLECTION     Physical
0x05, 0x0A,         //   (GLOBAL)USAGE_PAGE         0x000A Ordinal Page
0x09, 0x03,         //   (LOCAL)USAGE              0x000A0003 Instance 3 (UM = Usage Modifier)
0x85, 0x03,         //   (GLOBAL)REPORT_ID          0x03 (3)
0xA1, 0x00,           // (MAIN)COLLECTION         0x00 Physical(Usage = 0x000A0003: Page = Ordinal Page, Usage = Instance 3, Type = UM) < --Warning: USAGE type should be CP(Physical)
0x05, 0x09,           //   (GLOBAL)USAGE_PAGE         0x0009 Button Page
0x19, 0x01,           //   (LOCAL)USAGE_MINIMUM      0x00090001 Button 1 Primary / trigger(MULTI = Selector, On / Off, Momentary, or One Shot)
0x29, 0x03,           //   (LOCAL)USAGE_MAXIMUM      0x00090003 Button 3 Tertiary(MULTI = Selector, On / Off, Momentary, or One Shot)
0x15, 0x00,             // (GLOBAL)LOGICAL_MINIMUM    0x00 (0)
0x25, 0x01,             // (GLOBAL)LOGICAL_MAXIMUM    0x01 (1)
0x75, 0x01,             // (GLOBAL)REPORT_SIZE        0x01 (1) Number of bits per field
0x95, 0x03,             // (GLOBAL)REPORT_COUNT       0x03 (3) Number of fields
0x81, 0x02,             // (MAIN)INPUT              0x00000002 (3 fields x 1 bit) 0 = Data 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x95, 0x05,            //  (GLOBAL)REPORT_COUNT       0x05 (5) Number of fields
0x81, 0x03,            //  (MAIN)INPUT              0x00000003 (5 fields x 1 bit) 1 = Constant 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x05, 0x01,            //  (GLOBAL)USAGE_PAGE         0x0001 Generic Desktop Page
0x09, 0x30,            //  (LOCAL)USAGE              0x00010030 X(DV = Dynamic Value)
0x09, 0x31,            //  (LOCAL)USAGE              0x00010031 Y(DV = Dynamic Value)
0x15, 0x81,            //  (GLOBAL)LOGICAL_MINIMUM    0x81 (-127)
0x25, 0x7F,            //  (GLOBAL)LOGICAL_MAXIMUM    0x7F (127)
0x75, 0x08,            //  (GLOBAL)REPORT_SIZE        0x08 (8) Number of bits per field
0x95, 0x02,           //  (GLOBAL)REPORT_COUNT       0x02 (2) Number of fields
0x81, 0x06,           //   (MAIN)INPUT              0x00000006 (2 fields x 8 bits) 0 = Data 1 = Variable 1 = Relative 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0xC0,        //   END_COLLECTION     Physical
0x05, 0x0A,           // (GLOBAL)USAGE_PAGE         0x000A Ordinal Page
0x09, 0x04,          //  (LOCAL)USAGE              0x000A0004 Instance 4 (UM = Usage Modifier)
0x85, 0x04,           // (GLOBAL)REPORT_ID          0x04 (4)
0xA1, 0x00,           // (MAIN)COLLECTION         0x00 Physical(Usage = 0x000A0004: Page = Ordinal Page, Usage = Instance 4, Type = UM) < --Warning: USAGE type should be CP(Physical)
0x05, 0x09,             // (GLOBAL)USAGE_PAGE         0x0009 Button Page
0x19, 0x01,            //  (LOCAL)USAGE_MINIMUM      0x00090001 Button 1 Primary / trigger(MULTI = Selector, On / Off, Momentary, or One Shot)
0x29, 0x03,            //  (LOCAL)USAGE_MAXIMUM      0x00090003 Button 3 Tertiary(MULTI = Selector, On / Off, Momentary, or One Shot)
0x15, 0x00,            //  (GLOBAL)LOGICAL_MINIMUM    0x00 (0)
0x25, 0x01,            //  (GLOBAL)LOGICAL_MAXIMUM    0x01 (1)
0x75, 0x01,            //  (GLOBAL)REPORT_SIZE        0x01 (1) Number of bits per field
0x95, 0x03,             // (GLOBAL)REPORT_COUNT       0x03 (3) Number of fields
0x81, 0x02,             // (MAIN)INPUT              0x00000002 (3 fields x 1 bit) 0 = Data 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x95, 0x05,             // (GLOBAL)REPORT_COUNT       0x05 (5) Number of fields
0x81, 0x03,            //  (MAIN)INPUT              0x00000003 (5 fields x 1 bit) 1 = Constant 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x05, 0x01,            //  (GLOBAL)USAGE_PAGE         0x0001 Generic Desktop Page
0x09, 0x30,            //  (LOCAL)USAGE              0x00010030 X(DV = Dynamic Value)
0x09, 0x31,            //  (LOCAL)USAGE              0x00010031 Y(DV = Dynamic Value)
0x15, 0x81,            //  (GLOBAL)LOGICAL_MINIMUM    0x81 (-127)
0x25, 0x7F,            //  (GLOBAL)LOGICAL_MAXIMUM    0x7F (127)
0x75, 0x08,            //  (GLOBAL)REPORT_SIZE        0x08 (8) Number of bits per field
0x95, 0x02,           //   (GLOBAL)REPORT_COUNT       0x02 (2) Number of fields
0x81, 0x06,           //   (MAIN)INPUT              0x00000006 (2 fields x 8 bits) 0 = Data 1 = Variable 1 = Relative 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0xC0,        //   END_COLLECTION   Physical
0xC0,  // END_COLLECTION     Logical
0xC0,  // END_COLLECTION     Application

};
Here's the code in the original program which uses the default usage for a generic vendor device (really needs to be changed to a mouse device):
Code: [Select]
BOOLEAN
CheckIfOurDevice(
    HANDLE file)
{
    PHIDP_PREPARSED_DATA Ppd; // The opaque parser info describing this device
    HIDP_CAPS                       Caps; // The Capabilities of this hid device.
    USAGE                               MyUsagePage = 0xff00;
    USAGE                               MyUsage = 0x0001;
    HIDD_ATTRIBUTES attr; // Device attributes

    if (!HidD_GetAttributes(file, &attr))
    {
        printf("Error: HidD_GetAttributes failed \n");
        return FALSE;
    }

    printf("Device Attributes - PID: 0x%x, VID: 0x%x \n", attr.ProductID, attr.VendorID);
    if ((attr.VendorID != HIDMINI_DEFAULT_VID) || (attr.ProductID != HIDMINI_DEFAULT_PID))
    {
        printf("Device attributes doesn't match the sample \n");
        return FALSE;
    }

    if (!HidD_GetPreparsedData (file, &Ppd))
    {
        printf("Error: HidD_GetPreparsedData failed \n");
        return FALSE;
    }

    if (!HidP_GetCaps (Ppd, &Caps))
    {
        printf("Error: HidP_GetCaps failed \n");
        HidD_FreePreparsedData (Ppd);
        return FALSE;
    }

    if ((Caps.UsagePage == MyUsagePage) && (Caps.Usage == MyUsage)){
        printf("Success: Found my device.. \n");
        return TRUE;

    }

    return FALSE;

}

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Problem with report descriptor?
« Reply #1 on: May 15, 2015, 09:19:48 am »
Answering these questions will help to isolate the problem:

What happens when you attach the device?

Does it complete enumeration?

If no, where does the enumeration fail?

If yes, does it appear in Device Manager without errors?

If yes, what happens when you try to use data from the device?

Also, if you have changed the descriptors and kept the same Product ID and Vendor ID, see:

http://janaxelson.com/forum/index.php?topic=1367.msg6187#msg6187