parse_hid.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. #include "parse_hid.h"
  2. #include <stdio.h>
  3. #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
  4. #include "esp32-hal-log.h"
  5. #else
  6. #include "esp_log.h"
  7. #endif
  8. static uint8_t global_item = 0;
  9. static uint8_t local_item = 0;
  10. static uint8_t usage_page_item = 0;
  11. static uint8_t usage_item = 0;
  12. static uint8_t report_count = 0;
  13. static uint8_t report_size = 0;
  14. static uint8_t reportID = 0;
  15. static uint16_t report_bits = 0;
  16. static hid_mouse_t mouse;
  17. static bool set_x, set_y, set_wheel, set_buttons;
  18. static void setup_buttons()
  19. {
  20. mouse.buttons.bits_start = report_bits;
  21. mouse.buttons.count += report_count * report_size;
  22. mouse.buttons.size = report_size;
  23. ets_printf("buttons => start bits: %d, count: %d, size: %d\n", report_bits, report_count, report_size);
  24. report_bits += report_count * report_size;
  25. set_buttons = false;
  26. }
  27. static void setup_x_axis()
  28. {
  29. mouse.axes.bits_start = report_bits;
  30. mouse.axes.count = report_count;
  31. mouse.axes.size = report_size;
  32. ets_printf("X => start bits: %d, count: %d, size: %d\n", report_bits, report_count, report_size);
  33. report_bits += report_size * report_count;
  34. set_x = false;
  35. }
  36. static void setup_y_axis()
  37. {
  38. mouse.axes.bits_start = report_bits;
  39. mouse.axes.count = report_count;
  40. mouse.axes.size = report_size;
  41. ets_printf("Y => start bits: %d, count: %d, size: %d\n", report_bits, report_count, report_size);
  42. report_bits += report_size;
  43. set_y = false;
  44. }
  45. static void setup_wheel()
  46. {
  47. mouse.wheel.bits_start = report_bits;
  48. mouse.wheel.count = report_count;
  49. mouse.wheel.size = report_size;
  50. ets_printf("wheel => start bits: %d, count: %d, size: %d\n", report_bits, report_count, report_size);
  51. report_bits += report_size;
  52. set_wheel = false;
  53. }
  54. static void setup_input_device()
  55. {
  56. switch (usage_page_item)
  57. {
  58. case GENERIC_DESKTOP_POINTER:
  59. ets_printf("generic desktop pointer\n");
  60. if(set_x) setup_x_axis();
  61. // if(set_y) setup_y_axis();
  62. if(set_buttons) setup_buttons();
  63. if(set_wheel) setup_wheel();
  64. break;
  65. case GENERIC_DESKTOP_MOUSE:
  66. ets_printf("generic desktop mouse\n");
  67. // setup_mouse();
  68. break;
  69. case GENERIC_DESKTOP_JOYSTICK:
  70. ets_printf("generic desktop joystick\n");
  71. break;
  72. case GENERIC_DESKTOP_GAMEPAD:
  73. ets_printf("generic desktop gamepad\n");
  74. break;
  75. case GENERIC_DESKTOP_KEYBAORD:
  76. ets_printf("generic desktop keyboard\n");
  77. break;
  78. case GENERIC_DESKTOP_KEYPAD:
  79. ets_printf("generic desktop keypad\n");
  80. break;
  81. case GENERIC_DESKTOP_MULTIAXIS:
  82. ets_printf("generic desktop multi-axis\n");
  83. break;
  84. case GENERIC_DESKTOP_BUTTON:
  85. ets_printf("generic desktop button\n");
  86. set_buttons = true;
  87. setup_buttons();
  88. break;
  89. default:
  90. break;
  91. }
  92. }
  93. inline void parse_usage_page(uint32_t item)
  94. {
  95. usage_page_item = item;
  96. }
  97. inline void parse_usage(uint32_t item)
  98. {
  99. usage_item = item;
  100. switch (usage_item)
  101. {
  102. case GENERIC_DESKTOP_X:
  103. ets_printf("generic desktop X axis\n");
  104. set_x = true;
  105. break;
  106. case GENERIC_DESKTOP_Y:
  107. ets_printf("generic desktop Y axis\n");
  108. set_y = true;
  109. break;
  110. case GENERIC_DESKTOP_WHEEL:
  111. ets_printf("generic desktop wheel\n");
  112. set_wheel = true;
  113. break;
  114. default:
  115. break;
  116. }
  117. }
  118. static void parse_global_item(uint8_t type, uint8_t len, uint8_t *val)
  119. {
  120. uint32_t value = 0;
  121. for (size_t i = 0; i < len; i++)
  122. {
  123. value += val[i] << (i * 8);
  124. }
  125. // ets_printf("global type: %02x, len: %d, value: %d\n", type, len, value);
  126. switch (type)
  127. {
  128. case USAGE_PAGE(0):
  129. parse_usage_page(value);
  130. break;
  131. case LOGICAL_MINIMUM(0):
  132. break;
  133. case LOGICAL_MAXIMUM(0):
  134. break;
  135. case 0x34:
  136. break;
  137. case 0x44:
  138. break;
  139. case 0x54:
  140. break;
  141. case 0x64:
  142. break;
  143. case 0x74:
  144. report_size = value;
  145. break;
  146. case 0x84:
  147. reportID = *val;
  148. break;
  149. case 0x94:
  150. report_count = value;
  151. break;
  152. case 0xa4:
  153. break;
  154. case 0xb4:
  155. break;
  156. default:
  157. break;
  158. }
  159. }
  160. static void parse_local_item(uint8_t type, uint8_t len, uint8_t *val)
  161. {
  162. uint32_t value = 0;
  163. for (size_t i = 0; i < len; i++)
  164. {
  165. value += val[i] << (i * 8);
  166. }
  167. // ets_printf("local type: %02x, len: %d, value: %d\n", type, len, value);
  168. switch (type)
  169. {
  170. case 0x08:
  171. parse_usage(value);
  172. break;
  173. case 0x18:
  174. break;
  175. case 0x28:
  176. break;
  177. case 0x38:
  178. break;
  179. case 0x48:
  180. break;
  181. case 0x58:
  182. break;
  183. case 0x68:
  184. break;
  185. case 0x78:
  186. break;
  187. case 0x88:
  188. break;
  189. case 0x98:
  190. break;
  191. case 0xA8:
  192. break;
  193. default:
  194. break;
  195. }
  196. }
  197. inline void parse_feature_item(uint8_t type, uint8_t len, uint8_t *val)
  198. {
  199. uint32_t value = 0;
  200. for (size_t i = 0; i < len; i++)
  201. {
  202. value += val[i] << (i * 8);
  203. }
  204. // ets_printf("feature type: %02x, len: %d, value: %d\n", type, len, value);
  205. switch (type)
  206. {
  207. case 0x80:
  208. setup_input_device();
  209. break;
  210. case 0x90:
  211. break;
  212. case 0xA0:
  213. break;
  214. case 0xB0:
  215. break;
  216. case 0xC0:
  217. break;
  218. default:
  219. break;
  220. }
  221. }
  222. void parse_hid_report_map(uint8_t *map, size_t size)
  223. {
  224. ESP_LOGI("", "size: %d", size);
  225. for (size_t i = 0; i < size; i++)
  226. {
  227. uint8_t type = map[i] & 0xfc;
  228. uint8_t len = map[i] & 0x03;
  229. uint8_t *value = &map[i + 1];
  230. if (type & (1 << 2))
  231. {
  232. parse_global_item(type, len, value);
  233. }
  234. else if (type & (1 << 3))
  235. {
  236. parse_local_item(type, len, value);
  237. }
  238. else
  239. {
  240. parse_feature_item(type, len, value);
  241. }
  242. i += len;
  243. }
  244. }
  245. hid_mouse_t *get_mouse_struct()
  246. {
  247. return &mouse;
  248. }
  249. uint16_t bitmask(uint8_t i, uint8_t count)
  250. {
  251. uint16_t val = 0;
  252. for (i = 0; i < count; i++)
  253. {
  254. val |= 1<<i;
  255. }
  256. return val;
  257. }
  258. // always add 1 bytes, is byte is always reportID
  259. uint8_t get_buttons(uint8_t *data)
  260. {
  261. uint8_t start = 1 + mouse.buttons.bits_start / 8;
  262. return data[start];
  263. }
  264. int16_t get_x_axis(uint8_t *data)
  265. {
  266. uint16_t value = 0;
  267. uint8_t start = 1 + mouse.axes.bits_start / 8;
  268. uint8_t bits = mouse.axes.count * mouse.axes.size; // 2 * 12 = 24
  269. uint8_t n = bits / 8;
  270. for (size_t i = 0; i < n; i++)
  271. {
  272. value += data[start + i] << ((n-i-1) * 8);
  273. }
  274. ets_printf("X => start: %d, bits: %d, n: %d, value: %d\n", start, bits, n, value);
  275. return ((value >> (bits - mouse.axes.size)) | (value & 1<<(mouse.axes.size-1)));
  276. }
  277. int16_t get_y_axis(uint8_t *data)
  278. {
  279. uint16_t value = 0;
  280. uint8_t start = 1 + mouse.axes.bits_start / 8;
  281. uint8_t bits = mouse.axes.count * mouse.axes.size; // 3 * 8 = 24
  282. uint8_t n = bits / 8;
  283. for (size_t i = 0; i < n; i++)
  284. {
  285. value += data[start + i] << ((n-i-1) * 8);
  286. }
  287. ets_printf("Y => start: %d, bits: %d, n: %d, value: %d\n", start, bits, n, value);
  288. return (((value & (1<< mouse.axes.size)) >> (bits - mouse.axes.size * 2)) | (value & 1<<(mouse.axes.size-1)));
  289. }
  290. int8_t get_wheel(uint8_t *data)
  291. {
  292. uint16_t value = 0;
  293. uint8_t start = 1 + mouse.wheel.bits_start / 8;
  294. uint8_t bits = mouse.wheel.count * mouse.wheel.size; // 3 * 8 = 24
  295. uint8_t n = bits / 8;
  296. for (size_t i = 0; i < n; i++)
  297. {
  298. value += data[start + i] << ((n-i-1) * 8);
  299. }
  300. ets_printf("wheel => start: %d, bits: %d, n: %d, value: %d\n", start, bits, n, value);
  301. return ((value >> (bits - mouse.wheel.size)) | (value & 1<<(mouse.wheel.size-1)));
  302. }