HID报告描述符主项InputReport、OutputReport,FeatureReport
2022-05-16
1762
1
HID报告描述符主项除过COLLECTION项,就是输入报告InputReport,输出报告OutputReport和特性报告FeatureReport。
ITEM_PREFIX的BIT2,BIT3为00,bit4-7的值为:
#define ITEM_TAG_MAIN_INPUT 0x8
#define ITEM_TAG_MAIN_OUTPUT 0x9
#define ITEM_TAG_MAIN_FEATURE 0xb
InputReport、OutputReport,FeatureReport示例
INPUT (Data,Var,Abs) 81 02
OUTPUT (Data,Var,Abs) 91 02
FEATURE (Data,Var,Abs) B1 02
这里各个后面的报告数据MainItemData为0x02,代表(Data,Var,Abs),不过其具有多种配置,更多详见:HID主条目input item、output item和feature item详解http://www.usbzh.com/article/detail-527.html
UCHAR Size:2 | UCHAR Type:2 | UCHAR Tag:4 | |
---|---|---|---|
ITEM_TAG_MAIN_INPUT | XX | ITEM_TYPE_MAIN=00 | 0x08 |
ITEM_TAG_MAIN_OUTPUT | XX | ITEM_TYPE_MAIN=00 | 0x09 |
ITEM_TAG_MAIN_FEATURE | XX | ITEM_TYPE_MAIN=00 | 0x0B |
ITEM_TAG_MAIN_COLLECTION | XX | ITEM_TYPE_MAIN=00 | 0x0A |
ITEM_TAG_MAIN_END_COLLECTION | XX | ITEM_TYPE_MAIN=00 | 0x0C |
MainItemData的结构可根据上面的定义如下结构体:
typedef struct
{
USHORT DataConstant:1;
USHORT ArrayVariable:1;
USHORT Relative:1;
USHORT Wrap:1;
USHORT NonLinear:1;
USHORT NoPreferred:1;
USHORT NullState:1;
USHORT IsVolatile:1;
USHORT BitsBytes:1;
UCHAR reserved[2];
}
MAIN_ITEM_DATA, *PMAIN_ITEM_DATA;
在parser.sys中,一个报告就是一个HID_REPORT结构体,存于HID_COLLECTION的Reports指针数组中,其总数由ReportCount决定。
typedef struct _HID_REPORT
{
UCHAR Type;
UCHAR ReportID;
ULONG ReportSize;
ULONG ItemCount;
ULONG ItemAllocated;
HID_REPORT_ITEM Items[1];
}HID_REPORT, *PHID_REPORT;
而HID_REPORT_ITEM是在InputReport、OutputReport,FeatureReport各个USAGE使用的size和count。
typedef struct
{
ULONG ByteOffset;
UCHAR Shift;
ULONG Mask;
UCHAR BitCount;
UCHAR HasData;
UCHAR Array;
UCHAR Relative;
ULONG Minimum;
ULONG Maximum;
ULONG UsageMinimum;
ULONG UsageMaximum;
ULONG Data;
UCHAR Valid;
}HID_REPORT_ITEM, *PHID_REPORT_ITEM;
HID_RPORT中的HID_REPORT_ITEM成员通过HidParser_AddMainItem初始化。
ReportType = HID_REPORT_TYPE_ANY;
switch (CurrentItem->Tag) {
case ITEM_TAG_MAIN_INPUT:
ReportType = HID_REPORT_TYPE_INPUT;
break;
case ITEM_TAG_MAIN_OUTPUT:
ReportType = HID_REPORT_TYPE_OUTPUT;
break;
case ITEM_TAG_MAIN_FEATURE:
ReportType = HID_REPORT_TYPE_FEATURE;
break;
default:
Parser->Debug("[HIDPARSE] Unknown ReportType Tag %x Type %x Size %x CurrentItemSize %x\n", CurrentItem->Tag, CurrentItem->Type, CurrentItem->Size, CurrentItemSize);
ASSERT(FALSE);
break;
}
if (ReportType == HID_REPORT_TYPE_ANY)
break;
//
// get report
//
Status = HidParser_GetReport(Parser, ParserContext, CurrentCollection, ReportType, ParserContext->GlobalItemState.ReportId, TRUE, &Report);
ASSERT(Status == HIDPARSER_STATUS_SUCCESS);
// fill in a sensible default if the index isn't set
if (!ParserContext->LocalItemState.DesignatorIndexSet) {
ParserContext->LocalItemState.DesignatorIndex
= ParserContext->LocalItemState.DesignatorMinimum;
}
if (!ParserContext->LocalItemState.StringIndexSet)
ParserContext->LocalItemState.StringIndex = ParserContext->LocalItemState.StringMinimum;
//
// get main item data
//
MainItemData = (PMAIN_ITEM_DATA)&Data;
//
// add states & data to the report
//
Status = HidParser_AddMainItem(Parser, ParserContext, Report, &ParserContext->GlobalItemState, &ParserContext->LocalItemState, MainItemData, CurrentCollection);
ASSERT(Status == HIDPARSER_STATUS_SUCCESS);
}
//
// backup stack
//
Index = ParserContext->LocalItemState.UsageStackAllocated;
NewUsageStack = ParserContext->LocalItemState.UsageStack;
//
// reset the local item state and clear the usage stack
//
Parser->Zero(&ParserContext->LocalItemState, sizeof(LOCAL_ITEM_STATE));
//
// restore stack
//
ParserContext->LocalItemState.UsageStack = NewUsageStack;
ParserContext->LocalItemState.UsageStackAllocated = Index;
这里涉及到LOCAL_ITEM_STATE LocalItemState和GLOBAL_ITEM_STATE GlobalItemState的处理,后续通过LOCAL和GLOABL项来进行分析。
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936