mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
在usb设备的hid path中寻找给定的节点(存在问题,以后再解决) (#67)
This commit is contained in:
parent
e56c10c7b6
commit
0385e0324e
@ -5,6 +5,73 @@
|
||||
#define HID_MAX_REPORT 300 // 最大允许的hid report数目(包括feature、input、output)
|
||||
#define HID_MAX_PATH_SIZE 16 // maximum depth for path
|
||||
|
||||
// 这部分请参考hid_1_11.pdf Section 6.2.2.4
|
||||
|
||||
#define HID_ITEM_COLLECTION 0xA0
|
||||
#define HID_ITEM_END_COLLECTION 0xC0
|
||||
#define HID_ITEM_FEATURE 0xB0
|
||||
#define HID_ITEM_INPUT 0x80
|
||||
#define HID_ITEM_OUTPUT 0x90
|
||||
|
||||
/**
|
||||
* @brief 枚举hid的usage page列表。
|
||||
* 原始数据请见<HID Usage Tables FOR Universal Serial Bus (USB)>。
|
||||
* 该文件可从usb.org下载
|
||||
*/
|
||||
enum HID_USAGE_PAGE_TYPES
|
||||
{
|
||||
HID_USAGE_PAGE_GEN_DESKTOP = 0x1,
|
||||
HID_USAGE_PAGE_SIMU_CTRL, // simulation controls
|
||||
HID_USAGE_PAGE_VR_CTRL, // vr controls page
|
||||
HID_USAGE_PAGE_SPORT_CTRL, // sport controls
|
||||
HID_USAGE_PAGE_GAME_CTRL, // game controls
|
||||
HID_USAGE_PAGE_GEN_DEVICE_CTRL, // general device controls
|
||||
HID_USAGE_PAGE_KBD_KPD, // keyboard/ keypad page
|
||||
HID_USAGE_PAGE_LED, // LED
|
||||
HID_USAGE_PAGE_BUTTON, // button page
|
||||
HID_USAGE_PAGE_ORDINAL, // ordinal page
|
||||
HID_USAGE_PAGE_TEL_DEVICE, // telephony device
|
||||
HID_USAGE_PAGE_CONSUMER, // consumer page
|
||||
HID_USAGE_PAGE_DIGITIZER, // digitizers page
|
||||
HID_USAGE_PAGE_HAPTICS, // haptics page
|
||||
HID_USAGE_PAGE_PHY_INPUT_DEVICE, // physical input device page
|
||||
HID_USAGE_PAGE_UNICODE = 0x10, // unicode page
|
||||
HID_USAGE_PAGE_EYE_HEAD_TRACKER = 0x12, // eye and head trackers page
|
||||
HID_USAGE_PAGE_AUX_DISPLAY = 0x14, // auxiliary display page
|
||||
HID_USAGE_PAGE_SENSORS = 0x20, // sensors page
|
||||
HID_USAGE_PAGE_MEDICAL = 0x40, // medical instruments
|
||||
HID_USAGE_PAGE_BRAILLE_DISPLAY, // barille display
|
||||
HID_USAGE_PAGE_LIGHTNING_ILLU = 0x59, // lighting and illumination page
|
||||
HID_USAGE_PAGE_MONITOR = 0x80, // monitor page
|
||||
HID_USAGE_PAGE_MONITOR_ENUMERATED, // monitor enumerated page
|
||||
HID_USAGE_PAGE_VESA_VIRT_CTRL, // VESA virtual controls page
|
||||
HID_USAGE_PAGE_POWER = 0x84, // power page
|
||||
HID_USAGE_PAGE_BATTERY_SYSTEM, // battery system page
|
||||
HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, // barcode scanner page
|
||||
HID_USAGE_PAGE_SCALES, // scales page
|
||||
HID_USAGE_PAGE_MAGNET_STRIPE_READER, // magnetic stript reader page
|
||||
HID_USAGE_PAGE_CAMERA_CONTROL = 0x90, // camera control page
|
||||
HID_USAGE_PAGE_ARCADE, // arcade page
|
||||
HID_USAGE_PAGE_GAMING_DEVICE, // gaming device page
|
||||
HID_USAGE_PAGE_FIDO_ALLIANCE = 0xf1d0, // FIDO alliance page
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief usage type for HID_USAGE_PAGE_GEN_DESKTOP page
|
||||
*
|
||||
*/
|
||||
enum USAGE_TYPE_GENDESK
|
||||
{
|
||||
HID_USAGE_GENDESK_UNDEF = 0, // undefined
|
||||
HID_USAGE_GENDESK_POINTER,
|
||||
HID_USAGE_GENDESK_MOUSE,
|
||||
HID_USAGE_GENDESK_KEYBOARD = 0x6,
|
||||
HID_USAGE_GENDESK_POINTER_X = 0x30,
|
||||
HID_USAGE_GENDESK_POINTER_Y,
|
||||
HID_USAGE_GENDESK_WHEEL = 0x38,
|
||||
HID_USAGE_GENDESK_NOTHING = 0xff,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 描述hid path中的一个节点
|
||||
*
|
||||
@ -79,10 +146,8 @@ struct hid_parser
|
||||
int cnt_objects; // report descriptor中的对象数目
|
||||
|
||||
int cnt_report; // report desc中的report数目
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct hid_usage_types_string
|
||||
{
|
||||
int value;
|
||||
@ -97,3 +162,5 @@ struct hid_usage_pages_string
|
||||
};
|
||||
|
||||
int hid_parse_report(const void *report_data, const int len);
|
||||
|
||||
bool hid_parse_find_object(const void *hid_report, const int report_size, struct hid_data_t *data);
|
@ -44,21 +44,13 @@ static __always_inline const struct hid_usage_types_string *hid_get_usage_type(
|
||||
#define HID_ITEM_REP_ID 0x84
|
||||
#define HID_ITEM_REP_COUNT 0x94
|
||||
|
||||
// 这部分请参考hid_1_11.pdf Section 6.2.2.4
|
||||
|
||||
#define HID_ITEM_COLLECTION 0xA0
|
||||
#define HID_ITEM_END_COLLECTION 0xC0
|
||||
#define HID_ITEM_FEATURE 0xB0
|
||||
#define HID_ITEM_INPUT 0x80
|
||||
#define HID_ITEM_OUTPUT 0x90
|
||||
|
||||
static char __spaces_buf[33];
|
||||
char *__spaces(uint8_t cnt)
|
||||
{
|
||||
static char __space_overflow_str[] = "**";
|
||||
if (cnt > 32)
|
||||
{
|
||||
return &__space_overflow_str;
|
||||
return __space_overflow_str;
|
||||
}
|
||||
|
||||
memset(__spaces_buf, ' ', 32);
|
||||
@ -111,6 +103,7 @@ static __always_inline void __pop_usage_stack(struct hid_parser *parser)
|
||||
|
||||
/**
|
||||
* @brief 解析hid report,并获取下一个数据到data字段中
|
||||
* todo:(不知道为什么,在qemu上面,发现键盘的usage都是0xff)
|
||||
*
|
||||
* @param parser 解析器
|
||||
* @param data 返回的数据
|
||||
@ -345,7 +338,7 @@ static bool hid_parse(struct hid_parser *parser, struct hid_data_t *data)
|
||||
break;
|
||||
default:
|
||||
printk("\n Found unknown item %#02X\n", parser->item & HID_ITEM_MASK);
|
||||
return false;
|
||||
return found;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
@ -509,7 +502,7 @@ static int *__get_report_offset(struct hid_parser *parser, const uint8_t report_
|
||||
while ((pos < HID_MAX_REPORT) && (parser->offset_table[pos][0] != 0)) // 当offset的id不为0时
|
||||
{
|
||||
if ((parser->offset_table[pos][0] == report_id) && (parser->offset_table[pos][1] == report_type))
|
||||
return &parser->offset_table[2];
|
||||
return &parser->offset_table[pos][2];
|
||||
++pos;
|
||||
}
|
||||
// 在offset table中占用一个新的表项来存储这个report的offset
|
||||
@ -524,3 +517,67 @@ static int *__get_report_offset(struct hid_parser *parser, const uint8_t report_
|
||||
// 当offset table满了,且未找到结果的时候,返回NULL
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static __always_inline bool __find_object(struct hid_parser *parser, struct hid_data_t *data)
|
||||
{
|
||||
kdebug("target_type=%d report_id=%d, offset=%d, size=%d", data->type, data->report_id, data->offset, data->size);
|
||||
struct hid_data_t found_data = {0};
|
||||
|
||||
while (hid_parse(parser, &found_data))
|
||||
{
|
||||
kdebug("size=%d, type=%d, report_id=%d, u_page=%d, usage=%d", found_data.size, found_data.type,
|
||||
found_data.report_id, found_data.path.node[0].u_page, found_data.path.node[0].usage);
|
||||
// 按照路径完整匹配data
|
||||
if ((data->path.size > 0) && (found_data.type == data->type) &&
|
||||
(memcmp(found_data.path.node, data->path.node, data->path.size * sizeof(struct hid_node_t)) == 0))
|
||||
{
|
||||
goto found;
|
||||
}
|
||||
// 通过report id以及offset匹配成功
|
||||
else if ((found_data.report_id == data->report_id) && (found_data.type == data->type) &&
|
||||
(found_data.offset == data->offset))
|
||||
{
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
found:;
|
||||
memcpy(data, &found_data, sizeof(struct hid_data_t));
|
||||
data->report_count = parser->report_count;
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @brief 在hid report中寻找参数data给定的节点数据,并将结果写入到data中
|
||||
*
|
||||
* @param hid_report hid report 数据
|
||||
* @param report_size report_data的大小(字节)
|
||||
* @param data 要寻找的节点数据。
|
||||
* @return true 找到指定的节点
|
||||
* @return false 未找到指定的节点
|
||||
*/
|
||||
bool hid_parse_find_object(const void *hid_report, const int report_size, struct hid_data_t *data)
|
||||
{
|
||||
struct hid_parser parser = {0};
|
||||
hid_reset_parser(&parser);
|
||||
parser.report_desc = hid_report;
|
||||
parser.report_desc_size = report_size;
|
||||
// HID_PARSE_OUTPUT = false;
|
||||
|
||||
printk("\nFinding Coordinate value:");
|
||||
if (__find_object(&parser, data))
|
||||
{
|
||||
printk(" size: %i (in bits)\n"
|
||||
" offset: %i (in bits)\n"
|
||||
" min: %i\n"
|
||||
" max: %i\n"
|
||||
" attrib: 0x%02X (input, output, or feature, etc.)\n",
|
||||
data->size, data->offset, data->logical_min, data->logical_max, data->attribute);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
printk(" Did not find Coordinate value.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1863,9 +1863,20 @@ static int xhci_configure_port(const int id, const int port_id)
|
||||
}
|
||||
|
||||
kdebug("to parse hid report");
|
||||
// todo: parse hid report
|
||||
hid_parse_report(hid_report_data, hid_desc->report_desc_len);
|
||||
// todo:这里的parse有问题,详见hid_parse函数的注释
|
||||
// hid_parse_report(hid_report_data, hid_desc->report_desc_len);
|
||||
kdebug("parse hid report done");
|
||||
|
||||
// kdebug("to find object from hid path");
|
||||
// struct hid_data_t data = {0};
|
||||
// data.type = HID_ITEM_INPUT;
|
||||
// data.path.node[0].u_page = HID_USAGE_PAGE_GEN_DESKTOP;
|
||||
// data.path.node[0].usage = 0xff;
|
||||
// data.path.node[2].usage = USAGE_POINTER_Y; // to get the Y Coordinate, comment X above and uncomment this
|
||||
// line data.path.node[2].usage = USAGE_POINTER_WHEEL; // to get the Wheel Coordinate, comment X above and
|
||||
// uncomment this line
|
||||
// data.path.size = 1;
|
||||
// hid_parse_find_object(hid_report_data, hid_desc->report_desc_len, &data);
|
||||
kfree(hid_report_data);
|
||||
}
|
||||
goto out;
|
||||
|
Loading…
x
Reference in New Issue
Block a user