HID报告描述符ITEM的数据结构及代码分析过程
2022-05-16
1050
0
HID报告描述符是数据流的形式,其中最小单位是项英文ITEM,根据定义分为4种。分别为GLOBA,LOCAK和MAIN。
项分为长项和短项,这里我们只介绍短项。
短项头的一字节定义为:
typedef struct
{
UCHAR Size:2;
UCHAR Type:2;
UCHAR Tag:4;
}ITEM_PREFIX, *PITEM_PREFIX;
BIT0,BIT1代表的后续数据的个数:
- 0 = 0 bytes
- 1 = 1 byte
- 2 = 2 bytes
- 3 = 4 bytes
BIT2,BIT3代表项的类型,其中:
#define ITEM_TYPE_MAIN 0x0
#define ITEM_TYPE_GLOBAL 0x1
#define ITEM_TYPE_LOCAL 0x2
#define ITEM_TYPE_LONG 0x3
而BIT4-7代表着功能号。
HID项的分析
这里使用C语言来分析,其中ReportDescriptor是报告描述符指针,ReportLength中长度。
CurrentOffset = ReportDescriptor; //报告描述符指针
ReportEnd = ReportDescriptor + ReportLength;//报告描述符的指针结尾
do
{
//
// get current item
//
CurrentItem = (PITEM_PREFIX)CurrentOffset;
//
// get item size
//
CurrentItemSize = ItemSize[CurrentItem->Size];
Data = 0;
if (CurrentItem->Type == ITEM_TYPE_LONG)
{
//
// increment item size with size of data item
//
CurrentLongItem = (PLONG_ITEM)CurrentItem;
CurrentItemSize += CurrentLongItem->DataSize;
}
else
{
//
// get short item
//
CurrentShortItem = (PSHORT_ITEM)CurrentItem;
//
// get associated data
//
//ASSERT(CurrentItemSize == 1 || CurrentItemSize == 2 || CurrentItemSize == 4);
if (CurrentItemSize == 1)
Data = CurrentShortItem->Data.UData8[0];
else if (CurrentItemSize == 2)
Data = CurrentShortItem->Data.UData16[0];
else if (CurrentItemSize == 4)
Data = CurrentShortItem->Data.UData32;
else
{
//
// invalid item size
//
//Parser->Debug("CurrentItem invalid item size %lu\n", CurrentItemSize);
}
}
CurrentOffset += CurrentItemSize + sizeof(ITEM_PREFIX);
}while (CurrentOffset < ReportEnd);
其中短项和长项的结构定义如下:
typedef struct
{
ITEM_PREFIX Prefix;
union
{
UCHAR UData8[4];
CHAR SData8[4];
USHORT UData16[2];
SHORT SData16[2];
ULONG UData32;
LONG SData32;
}Data;
}SHORT_ITEM, *PSHORT_ITEM;
typedef struct
{
ITEM_PREFIX Prefix;
UCHAR DataSize;
UCHAR LongItemTag;
UCHAR Data[0];
}LONG_ITEM,*PLONG_ITEM;
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936