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_REPORT 300 // 最大允许的hid report数目(包括feature、input、output)
|
||||||
#define HID_MAX_PATH_SIZE 16 // maximum depth for path
|
#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中的一个节点
|
* @brief 描述hid path中的一个节点
|
||||||
*
|
*
|
||||||
@ -40,7 +107,7 @@ struct hid_data_t
|
|||||||
|
|
||||||
uint8_t report_id; // report id(from incoming report)
|
uint8_t report_id; // report id(from incoming report)
|
||||||
uint8_t type; // 数据类型:FEATURE / INPUT / OUTPUT
|
uint8_t type; // 数据类型:FEATURE / INPUT / OUTPUT
|
||||||
uint8_t attribute; // report field attribute. (2 = (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position))
|
uint8_t attribute; // report field attribute. (2 = (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position))
|
||||||
// (6 = (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position))
|
// (6 = (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position))
|
||||||
int8_t unit_exp; // unit exponent;
|
int8_t unit_exp; // unit exponent;
|
||||||
|
|
||||||
@ -78,11 +145,9 @@ struct hid_parser
|
|||||||
|
|
||||||
int cnt_objects; // report descriptor中的对象数目
|
int cnt_objects; // report descriptor中的对象数目
|
||||||
|
|
||||||
int cnt_report; // report desc中的report数目
|
int cnt_report; // report desc中的report数目
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct hid_usage_types_string
|
struct hid_usage_types_string
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
@ -92,8 +157,10 @@ struct hid_usage_types_string
|
|||||||
struct hid_usage_pages_string
|
struct hid_usage_pages_string
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
struct hid_usage_types_string * types;
|
struct hid_usage_types_string *types;
|
||||||
const char * string;
|
const char *string;
|
||||||
};
|
};
|
||||||
|
|
||||||
int hid_parse_report(const void *report_data, const int len);
|
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_ID 0x84
|
||||||
#define HID_ITEM_REP_COUNT 0x94
|
#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];
|
static char __spaces_buf[33];
|
||||||
char *__spaces(uint8_t cnt)
|
char *__spaces(uint8_t cnt)
|
||||||
{
|
{
|
||||||
static char __space_overflow_str[] = "**";
|
static char __space_overflow_str[] = "**";
|
||||||
if (cnt > 32)
|
if (cnt > 32)
|
||||||
{
|
{
|
||||||
return &__space_overflow_str;
|
return __space_overflow_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(__spaces_buf, ' ', 32);
|
memset(__spaces_buf, ' ', 32);
|
||||||
@ -111,6 +103,7 @@ static __always_inline void __pop_usage_stack(struct hid_parser *parser)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 解析hid report,并获取下一个数据到data字段中
|
* @brief 解析hid report,并获取下一个数据到data字段中
|
||||||
|
* todo:(不知道为什么,在qemu上面,发现键盘的usage都是0xff)
|
||||||
*
|
*
|
||||||
* @param parser 解析器
|
* @param parser 解析器
|
||||||
* @param data 返回的数据
|
* @param data 返回的数据
|
||||||
@ -345,7 +338,7 @@ static bool hid_parse(struct hid_parser *parser, struct hid_data_t *data)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk("\n Found unknown item %#02X\n", parser->item & HID_ITEM_MASK);
|
printk("\n Found unknown item %#02X\n", parser->item & HID_ITEM_MASK);
|
||||||
return false;
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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时
|
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))
|
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;
|
++pos;
|
||||||
}
|
}
|
||||||
// 在offset table中占用一个新的表项来存储这个report的offset
|
// 在offset table中占用一个新的表项来存储这个report的offset
|
||||||
@ -524,3 +517,67 @@ static int *__get_report_offset(struct hid_parser *parser, const uint8_t report_
|
|||||||
// 当offset table满了,且未找到结果的时候,返回NULL
|
// 当offset table满了,且未找到结果的时候,返回NULL
|
||||||
return 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");
|
kdebug("to parse hid report");
|
||||||
// todo: parse hid report
|
// todo:这里的parse有问题,详见hid_parse函数的注释
|
||||||
hid_parse_report(hid_report_data, hid_desc->report_desc_len);
|
// hid_parse_report(hid_report_data, hid_desc->report_desc_len);
|
||||||
kdebug("parse hid report done");
|
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);
|
kfree(hid_report_data);
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user