esp_hidh.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. /*
  2. * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "sys/queue.h"
  7. #include "esp_hidh_private.h"
  8. #include "bt_hidh.h"
  9. #include "ble_hidh.h"
  10. #include <string.h>
  11. #include <stdbool.h>
  12. #include "esp_event_base.h"
  13. #if CONFIG_BT_HID_HOST_ENABLED
  14. #include "esp_hidh_api.h"
  15. #endif /* CONFIG_BT_HID_HOST_ENABLED */
  16. ESP_EVENT_DEFINE_BASE(ESP_HIDH_EVENTS);
  17. #define ESP_HIDH_DELAY_FREE_TO 100000 // us
  18. static const char *TAG = "ESP_HIDH";
  19. static esp_hidh_dev_head_t s_esp_hidh_devices;
  20. static SemaphoreHandle_t s_esp_hidh_devices_semaphore = NULL;
  21. static inline void lock_devices(void)
  22. {
  23. if (s_esp_hidh_devices_semaphore != NULL) {
  24. xSemaphoreTake(s_esp_hidh_devices_semaphore, portMAX_DELAY);
  25. }
  26. }
  27. static inline void unlock_devices(void)
  28. {
  29. if (s_esp_hidh_devices_semaphore != NULL) {
  30. xSemaphoreGive(s_esp_hidh_devices_semaphore);
  31. }
  32. }
  33. /*
  34. * Public Functions
  35. * */
  36. bool esp_hidh_dev_exists(esp_hidh_dev_t *dev)
  37. {
  38. if (dev == NULL) {
  39. return false;
  40. }
  41. esp_hidh_dev_t * d = NULL;
  42. lock_devices();
  43. TAILQ_FOREACH(d, &s_esp_hidh_devices, devices) {
  44. if (d == dev) {
  45. unlock_devices();
  46. return true;
  47. }
  48. }
  49. unlock_devices();
  50. return false;
  51. }
  52. esp_err_t esp_hidh_init(const esp_hidh_config_t *config)
  53. {
  54. esp_err_t err = ESP_FAIL;
  55. if (config == NULL) {
  56. ESP_LOGE(TAG, "Config is NULL");
  57. return err;
  58. }
  59. if (s_esp_hidh_devices_semaphore != NULL) {
  60. ESP_LOGE(TAG, "Already initialized");
  61. return err;
  62. }
  63. TAILQ_INIT(&s_esp_hidh_devices);
  64. s_esp_hidh_devices_semaphore = xSemaphoreCreateMutex();
  65. if (s_esp_hidh_devices_semaphore == NULL) {
  66. ESP_LOGE(TAG, "xSemaphoreCreateMutex failed!");
  67. return err;
  68. }
  69. // unlock_devices();
  70. err = ESP_OK;
  71. #if CONFIG_BT_HID_HOST_ENABLED
  72. if (err == ESP_OK) {
  73. err = esp_bt_hidh_init(config);
  74. }
  75. #endif /* CONFIG_BT_HID_HOST_ENABLED */
  76. #if CONFIG_GATTC_ENABLE
  77. if (err == ESP_OK) {
  78. err = esp_ble_hidh_init(config);
  79. }
  80. #endif /* CONFIG_GATTC_ENABLE */
  81. if (err != ESP_OK) {
  82. vSemaphoreDelete(s_esp_hidh_devices_semaphore);
  83. s_esp_hidh_devices_semaphore = NULL;
  84. }
  85. return err;
  86. }
  87. esp_err_t esp_hidh_deinit(void)
  88. {
  89. esp_err_t err = ESP_FAIL;
  90. if (s_esp_hidh_devices_semaphore == NULL) {
  91. ESP_LOGE(TAG, "Already uninitialized");
  92. return err;
  93. }
  94. if (!TAILQ_EMPTY(&s_esp_hidh_devices)) {
  95. ESP_LOGE(TAG, "Please disconnect all devices first!");
  96. return err;
  97. }
  98. err = ESP_OK;
  99. #if CONFIG_BT_HID_HOST_ENABLED
  100. if (err == ESP_OK) {
  101. err = esp_bt_hidh_deinit();
  102. }
  103. #endif /* CONFIG_BT_HID_HOST_ENABLED */
  104. #if CONFIG_GATTC_ENABLE
  105. if (err == ESP_OK) {
  106. err = esp_ble_hidh_deinit();
  107. }
  108. #endif /* CONFIG_GATTC_ENABLE */
  109. if (err == ESP_OK) {
  110. TAILQ_INIT(&s_esp_hidh_devices);
  111. vSemaphoreDelete(s_esp_hidh_devices_semaphore);
  112. s_esp_hidh_devices_semaphore = NULL;
  113. }
  114. return err;
  115. }
  116. #if CONFIG_BLUEDROID_ENABLED
  117. esp_hidh_dev_t *esp_hidh_dev_open(esp_bd_addr_t bda, esp_hid_transport_t transport, uint8_t remote_addr_type)
  118. {
  119. if (esp_hidh_dev_get_by_bda(bda) != NULL) {
  120. ESP_LOGE(TAG, "Already Connected");
  121. return NULL;
  122. }
  123. esp_hidh_dev_t *dev = NULL;
  124. #if CONFIG_GATTC_ENABLE
  125. if (transport == ESP_HID_TRANSPORT_BLE) {
  126. dev = esp_ble_hidh_dev_open(bda, (esp_ble_addr_type_t)remote_addr_type);
  127. }
  128. #endif /* CONFIG_GATTC_ENABLE */
  129. #if CONFIG_BT_HID_HOST_ENABLED
  130. if (transport == ESP_HID_TRANSPORT_BT) {
  131. dev = esp_bt_hidh_dev_open(bda);
  132. }
  133. #endif /* CONFIG_BT_HID_HOST_ENABLED */
  134. return dev;
  135. }
  136. #endif /* CONFIG_BLUEDROID_ENABLED */
  137. esp_err_t esp_hidh_dev_close(esp_hidh_dev_t *dev)
  138. {
  139. esp_err_t ret = ESP_OK;
  140. if (esp_hidh_dev_exists(dev)) {
  141. esp_hidh_dev_lock(dev);
  142. ret = dev->close(dev);
  143. esp_hidh_dev_unlock(dev);
  144. } else {
  145. ret = ESP_FAIL;
  146. }
  147. return ret;
  148. }
  149. void esp_hidh_dev_dump(esp_hidh_dev_t *dev, FILE *fp)
  150. {
  151. if (esp_hidh_dev_exists(dev)) {
  152. esp_hidh_dev_lock(dev);
  153. dev->dump(dev, fp);
  154. esp_hidh_dev_unlock(dev);
  155. }
  156. }
  157. esp_err_t esp_hidh_dev_output_set(esp_hidh_dev_t *dev, size_t map_index, size_t report_id, uint8_t *value, size_t value_len)
  158. {
  159. esp_err_t ret = ESP_OK;
  160. if (esp_hidh_dev_exists(dev)) {
  161. esp_hidh_dev_lock(dev);
  162. ret = dev->report_write(dev, map_index, report_id, ESP_HID_REPORT_TYPE_OUTPUT, value, value_len);
  163. esp_hidh_dev_unlock(dev);
  164. } else {
  165. ret = ESP_FAIL;
  166. }
  167. return ret;
  168. }
  169. esp_err_t esp_hidh_dev_feature_set(esp_hidh_dev_t *dev, size_t map_index, size_t report_id, uint8_t *value, size_t value_len)
  170. {
  171. esp_err_t ret = ESP_OK;
  172. if (esp_hidh_dev_exists(dev)) {
  173. esp_hidh_dev_lock(dev);
  174. ret = dev->report_write(dev, map_index, report_id, ESP_HID_REPORT_TYPE_FEATURE, value, value_len);
  175. esp_hidh_dev_unlock(dev);
  176. } else {
  177. ret = ESP_FAIL;
  178. }
  179. return ret;
  180. }
  181. esp_err_t esp_hidh_dev_feature_get(esp_hidh_dev_t *dev, size_t map_index, size_t report_id, size_t max_length, uint8_t *value, size_t *value_len)
  182. {
  183. esp_err_t ret = ESP_OK;
  184. if (esp_hidh_dev_exists(dev)) {
  185. esp_hidh_dev_lock(dev);
  186. ret = dev->report_read(dev, map_index, report_id, ESP_HID_REPORT_TYPE_FEATURE, max_length, value, value_len);
  187. esp_hidh_dev_unlock(dev);
  188. } else {
  189. ret = ESP_FAIL;
  190. }
  191. return ret;
  192. }
  193. esp_err_t esp_hidh_dev_set_report(esp_hidh_dev_t *dev, size_t map_index, size_t report_id, int report_type, uint8_t *data, size_t length)
  194. {
  195. esp_err_t ret = ESP_OK;
  196. if (esp_hidh_dev_exists(dev)) {
  197. esp_hidh_dev_lock(dev);
  198. if (dev->set_report) {
  199. ret = dev->set_report(dev, map_index, report_id, report_type, data, length);
  200. } else {
  201. ret = ESP_ERR_NOT_SUPPORTED;
  202. }
  203. esp_hidh_dev_unlock(dev);
  204. } else {
  205. ret = ESP_FAIL;
  206. }
  207. return ret;
  208. }
  209. esp_err_t esp_hidh_dev_get_report(esp_hidh_dev_t *dev, size_t map_index, size_t report_id, int report_type,
  210. size_t max_len)
  211. {
  212. esp_err_t ret = ESP_OK;
  213. if (esp_hidh_dev_exists(dev)) {
  214. esp_hidh_dev_lock(dev);
  215. ret = dev->report_read(dev, map_index, report_id, report_type, max_len, NULL, NULL);
  216. esp_hidh_dev_unlock(dev);
  217. } else {
  218. ret = ESP_FAIL;
  219. }
  220. return ret;
  221. }
  222. esp_err_t esp_hidh_dev_get_idle(esp_hidh_dev_t *dev)
  223. {
  224. esp_err_t ret = ESP_OK;
  225. if (esp_hidh_dev_exists(dev)) {
  226. esp_hidh_dev_lock(dev);
  227. if (dev->get_idle) {
  228. ret = dev->get_idle(dev);
  229. } else {
  230. ret = ESP_ERR_NOT_SUPPORTED;
  231. }
  232. esp_hidh_dev_unlock(dev);
  233. } else {
  234. ret = ESP_FAIL;
  235. }
  236. return ret;
  237. }
  238. esp_err_t esp_hidh_dev_set_idle(esp_hidh_dev_t *dev, uint8_t idle_time)
  239. {
  240. esp_err_t ret = ESP_OK;
  241. if (esp_hidh_dev_exists(dev)) {
  242. esp_hidh_dev_lock(dev);
  243. if (dev->set_idle) {
  244. ret = dev->set_idle(dev, idle_time);
  245. } else {
  246. ret = ESP_ERR_NOT_SUPPORTED;
  247. }
  248. esp_hidh_dev_unlock(dev);
  249. } else {
  250. ret = ESP_FAIL;
  251. }
  252. return ret;
  253. }
  254. esp_err_t esp_hidh_dev_get_protocol(esp_hidh_dev_t *dev)
  255. {
  256. esp_err_t ret = ESP_OK;
  257. if (esp_hidh_dev_exists(dev)) {
  258. esp_hidh_dev_lock(dev);
  259. if (dev->get_protocol) {
  260. ret = dev->get_protocol(dev);
  261. } else {
  262. ret = ESP_ERR_NOT_SUPPORTED;
  263. }
  264. esp_hidh_dev_unlock(dev);
  265. } else {
  266. ret = ESP_FAIL;
  267. }
  268. return ret;
  269. }
  270. esp_err_t esp_hidh_dev_set_protocol(esp_hidh_dev_t *dev, uint8_t protocol_mode)
  271. {
  272. esp_err_t ret = ESP_OK;
  273. if (esp_hidh_dev_exists(dev)) {
  274. esp_hidh_dev_lock(dev);
  275. if (dev->set_protocol) {
  276. ret = dev->set_protocol(dev, protocol_mode);
  277. } else {
  278. ret = ESP_ERR_NOT_SUPPORTED;
  279. }
  280. esp_hidh_dev_unlock(dev);
  281. } else {
  282. ret = ESP_FAIL;
  283. }
  284. return ret;
  285. }
  286. const uint8_t *esp_hidh_dev_bda_get(esp_hidh_dev_t *dev)
  287. {
  288. uint8_t *ret = NULL;
  289. #if CONFIG_BLUEDROID_ENABLED
  290. if (esp_hidh_dev_exists(dev)) {
  291. esp_hidh_dev_lock(dev);
  292. ret = dev->bda;
  293. esp_hidh_dev_unlock(dev);
  294. }
  295. #endif /* CONFIG_BLUEDROID_ENABLED */
  296. return ret;
  297. }
  298. esp_hid_transport_t esp_hidh_dev_transport_get(esp_hidh_dev_t *dev)
  299. {
  300. esp_hid_transport_t ret = ESP_HID_TRANSPORT_MAX;
  301. if (esp_hidh_dev_exists(dev)) {
  302. esp_hidh_dev_lock(dev);
  303. ret = dev->transport;
  304. esp_hidh_dev_unlock(dev);
  305. }
  306. return ret;
  307. }
  308. const esp_hid_device_config_t *esp_hidh_dev_config_get(esp_hidh_dev_t *dev)
  309. {
  310. esp_hid_device_config_t *ret = NULL;
  311. if (esp_hidh_dev_exists(dev)) {
  312. esp_hidh_dev_lock(dev);
  313. ret = &dev->config;
  314. esp_hidh_dev_unlock(dev);
  315. }
  316. return ret;
  317. }
  318. const char *esp_hidh_dev_name_get(esp_hidh_dev_t *dev)
  319. {
  320. const char * ret = NULL;
  321. if (esp_hidh_dev_exists(dev)) {
  322. esp_hidh_dev_lock(dev);
  323. ret = dev->config.device_name ? dev->config.device_name : "";
  324. esp_hidh_dev_unlock(dev);
  325. }
  326. return ret;
  327. }
  328. const char *esp_hidh_dev_manufacturer_get(esp_hidh_dev_t *dev)
  329. {
  330. const char *ret = NULL;
  331. if (esp_hidh_dev_exists(dev)) {
  332. esp_hidh_dev_lock(dev);
  333. ret = dev->config.manufacturer_name ? dev->config.manufacturer_name : "";
  334. esp_hidh_dev_unlock(dev);
  335. }
  336. return ret;
  337. }
  338. const char *esp_hidh_dev_serial_get(esp_hidh_dev_t *dev)
  339. {
  340. const char *ret = NULL;
  341. if (esp_hidh_dev_exists(dev)) {
  342. esp_hidh_dev_lock(dev);
  343. ret = dev->config.serial_number ? dev->config.serial_number : "";
  344. esp_hidh_dev_unlock(dev);
  345. }
  346. return ret;
  347. }
  348. uint16_t esp_hidh_dev_vendor_id_get(esp_hidh_dev_t *dev)
  349. {
  350. uint16_t ret = 0;
  351. if (esp_hidh_dev_exists(dev)) {
  352. esp_hidh_dev_lock(dev);
  353. ret = dev->config.vendor_id;
  354. esp_hidh_dev_unlock(dev);
  355. }
  356. return ret;
  357. }
  358. uint16_t esp_hidh_dev_product_id_get(esp_hidh_dev_t *dev)
  359. {
  360. uint16_t ret = 0;
  361. if (esp_hidh_dev_exists(dev)) {
  362. esp_hidh_dev_lock(dev);
  363. ret = dev->config.product_id;
  364. esp_hidh_dev_unlock(dev);
  365. }
  366. return ret;
  367. }
  368. uint16_t esp_hidh_dev_version_get(esp_hidh_dev_t *dev)
  369. {
  370. uint16_t ret = 0;
  371. if (!esp_hidh_dev_exists(dev)) {
  372. esp_hidh_dev_lock(dev);
  373. ret = dev->config.version;
  374. esp_hidh_dev_unlock(dev);
  375. }
  376. return ret;
  377. }
  378. esp_hid_usage_t esp_hidh_dev_usage_get(esp_hidh_dev_t *dev)
  379. {
  380. esp_hid_usage_t ret = ESP_HID_USAGE_GENERIC;
  381. if (esp_hidh_dev_exists(dev)) {
  382. esp_hidh_dev_lock(dev);
  383. ret = dev->usage;
  384. esp_hidh_dev_unlock(dev);
  385. }
  386. return ret;
  387. }
  388. esp_err_t esp_hidh_dev_reports_get(esp_hidh_dev_t *dev, size_t *num_reports, esp_hid_report_item_t **reports)
  389. {
  390. esp_err_t ret = 0;
  391. esp_hid_report_item_t *r = NULL;
  392. if (!esp_hidh_dev_exists(dev)) {
  393. return ESP_FAIL;
  394. }
  395. esp_hidh_dev_lock(dev);
  396. do {
  397. r = (esp_hid_report_item_t *)malloc(sizeof(esp_hid_report_item_t) * dev->reports_len);
  398. if (r == NULL) {
  399. ret = ESP_FAIL;
  400. break;
  401. }
  402. esp_hidh_dev_report_t *dr = dev->reports;
  403. for (uint8_t i = 0; i < dev->reports_len; i++) {
  404. if (dr == NULL) {
  405. // error
  406. free(r);
  407. ret = ESP_FAIL;
  408. goto error_;
  409. }
  410. r[i].map_index = dr->map_index;
  411. r[i].protocol_mode = dr->protocol_mode;
  412. r[i].usage = dr->usage;
  413. r[i].report_id = dr->report_id;
  414. r[i].report_type = dr->report_type;
  415. r[i].value_len = dr->value_len;
  416. dr = dr->next;
  417. }
  418. *reports = r;
  419. *num_reports = dev->reports_len;
  420. } while (0);
  421. error_:;
  422. esp_hidh_dev_unlock(dev);
  423. return ret;
  424. }
  425. esp_err_t esp_hidh_dev_report_maps_get(esp_hidh_dev_t *dev, size_t *num_maps, esp_hid_raw_report_map_t **maps)
  426. {
  427. if (!esp_hidh_dev_exists(dev)) {
  428. return ESP_FAIL;
  429. }
  430. esp_hidh_dev_lock(dev);
  431. *num_maps = dev->config.report_maps_len;
  432. *maps = dev->config.report_maps;
  433. esp_hidh_dev_unlock(dev);
  434. return ESP_OK;
  435. }
  436. /*
  437. * Private Functions
  438. * */
  439. /**
  440. * `lock_devices()` only protect the devices list, this mutex protect the single deivce instance.
  441. */
  442. inline void esp_hidh_dev_lock(esp_hidh_dev_t *dev)
  443. {
  444. if (dev && dev->mutex != NULL) {
  445. xSemaphoreTake(dev->mutex, portMAX_DELAY);
  446. }
  447. }
  448. inline void esp_hidh_dev_unlock(esp_hidh_dev_t *dev)
  449. {
  450. if (dev && dev->mutex != NULL) {
  451. xSemaphoreGive(dev->mutex);
  452. }
  453. }
  454. inline void esp_hidh_dev_wait(esp_hidh_dev_t *dev)
  455. {
  456. if (dev && dev->semaphore != NULL) {
  457. xSemaphoreTake(dev->semaphore, portMAX_DELAY);
  458. }
  459. }
  460. inline void esp_hidh_dev_send(esp_hidh_dev_t *dev)
  461. {
  462. if (dev && dev->semaphore != NULL) {
  463. xSemaphoreGive(dev->semaphore);
  464. }
  465. }
  466. esp_hidh_dev_report_t *esp_hidh_dev_get_report_by_handle(esp_hidh_dev_t *dev, uint16_t handle)
  467. {
  468. esp_hidh_dev_report_t *r = dev->reports;
  469. while (r) {
  470. if (r->handle == handle) {
  471. return r;
  472. }
  473. r = r->next;
  474. }
  475. return NULL;
  476. }
  477. esp_hidh_dev_report_t *esp_hidh_dev_get_report_by_id_type_proto(esp_hidh_dev_t *dev, size_t map_index, size_t report_id, int report_type, uint8_t protocol_mode)
  478. {
  479. esp_hidh_dev_report_t *r = dev->reports;
  480. while (r) {
  481. if (r->map_index == map_index && r->report_type == report_type && r->report_id == report_id &&
  482. r->protocol_mode == protocol_mode) {
  483. return r;
  484. }
  485. r = r->next;
  486. }
  487. return NULL;
  488. }
  489. esp_hidh_dev_report_t *esp_hidh_dev_get_report_by_id_and_type(esp_hidh_dev_t *dev, size_t map_index, size_t report_id, int report_type)
  490. {
  491. esp_hidh_dev_report_t *r = dev->reports;
  492. while (r) {
  493. if (r->map_index == map_index && r->report_id == report_id && r->report_type == report_type && r->protocol_mode == ESP_HID_PROTOCOL_MODE_REPORT) {
  494. return r;
  495. }
  496. r = r->next;
  497. }
  498. return NULL;
  499. }
  500. esp_hidh_dev_report_t *esp_hidh_dev_get_input_report_by_id_and_proto(esp_hidh_dev_t *dev, size_t report_id, int protocol_mode)
  501. {
  502. esp_hidh_dev_report_t *r = dev->reports;
  503. while (r) {
  504. if (r->report_id == report_id && (r->report_type & ESP_HID_REPORT_TYPE_INPUT) && r->protocol_mode == protocol_mode) {
  505. return r;
  506. }
  507. r = r->next;
  508. }
  509. return NULL;
  510. }
  511. esp_hidh_dev_report_t *esp_hidh_dev_get_input_report_by_len_and_proto(esp_hidh_dev_t *dev, size_t len, int protocol_mode)
  512. {
  513. esp_hidh_dev_report_t *r = dev->reports;
  514. while (r) {
  515. if (r->value_len == len && (r->report_type & ESP_HID_REPORT_TYPE_INPUT) && r->protocol_mode == protocol_mode) {
  516. return r;
  517. }
  518. r = r->next;
  519. }
  520. return NULL;
  521. }
  522. /**
  523. * If no Report ID item tags are present in the Report descriptor, it
  524. * can be assumed that only one Input, Output, and Feature report structure exists
  525. * and together they represent all of the device’s data.
  526. */
  527. esp_hidh_dev_report_t *esp_hidh_dev_get_input_report_by_proto_and_data(esp_hidh_dev_t *dev, int protocol_mode,
  528. size_t len, const uint8_t *data, bool *has_report_id)
  529. {
  530. esp_hidh_dev_report_t *r = dev->reports;
  531. *has_report_id = false;
  532. // first, assume data not include report id
  533. while (r) {
  534. if (r->value_len == len && r->report_id == 0 && (r->report_type & ESP_HID_REPORT_TYPE_INPUT) &&
  535. r->protocol_mode == protocol_mode) {
  536. *has_report_id = false;
  537. break;
  538. }
  539. r = r->next;
  540. }
  541. // indicate data include report id
  542. if (r == NULL) {
  543. if (*data == 0) {
  544. ESP_LOGE(TAG, "data not include report id!");
  545. *has_report_id = false;
  546. return NULL;
  547. }
  548. r = dev->reports;
  549. while (r) {
  550. if (r->value_len == len - 1 && r->report_id == *data && (r->report_type & ESP_HID_REPORT_TYPE_INPUT) &&
  551. r->protocol_mode == protocol_mode) {
  552. *has_report_id = true;
  553. break;
  554. }
  555. r = r->next;
  556. }
  557. }
  558. return r;
  559. }
  560. static void esp_hidh_dev_resources_free(esp_hidh_dev_t *dev)
  561. {
  562. esp_hidh_dev_lock(dev);
  563. if (dev->semaphore) {
  564. vSemaphoreDelete(dev->semaphore);
  565. }
  566. if (dev->trans_timer) {
  567. esp_timer_stop(dev->trans_timer);
  568. esp_timer_delete(dev->trans_timer);
  569. dev->trans_timer = NULL;
  570. }
  571. free((void *)dev->config.device_name);
  572. free((void *)dev->config.manufacturer_name);
  573. free((void *)dev->config.serial_number);
  574. for (uint8_t d = 0; d < dev->config.report_maps_len; d++) {
  575. /* data of report map maybe is NULL */
  576. if (dev->config.report_maps[d].data) {
  577. free((void *)dev->config.report_maps[d].data);
  578. }
  579. }
  580. free((void *)dev->config.report_maps);
  581. esp_hidh_dev_report_t *r;
  582. while (dev->reports) {
  583. r = dev->reports;
  584. dev->reports = dev->reports->next;
  585. free(r);
  586. }
  587. esp_hidh_dev_unlock(dev);
  588. if (dev->mutex) {
  589. vSemaphoreDelete(dev->mutex);
  590. }
  591. free(dev);
  592. }
  593. esp_hidh_dev_t *esp_hidh_dev_malloc()
  594. {
  595. esp_hidh_dev_t *dev = (esp_hidh_dev_t *)calloc(1, sizeof(esp_hidh_dev_t));
  596. if (dev == NULL) {
  597. ESP_LOGE(TAG, "malloc esp_hidh_dev_t failed");
  598. return NULL;
  599. }
  600. dev->semaphore = xSemaphoreCreateBinary();
  601. if (dev->semaphore == NULL) {
  602. ESP_LOGE(TAG, "malloc semaphore failed");
  603. esp_hidh_dev_resources_free(dev);
  604. return NULL;
  605. }
  606. dev->mutex = xSemaphoreCreateMutex();
  607. if (dev->mutex == NULL) {
  608. ESP_LOGE(TAG, "malloc mutex failed");
  609. esp_hidh_dev_resources_free(dev);
  610. return NULL;
  611. }
  612. lock_devices();
  613. TAILQ_INSERT_TAIL(&s_esp_hidh_devices, dev, devices);
  614. unlock_devices();
  615. return dev;
  616. }
  617. /**
  618. * The `dev` is allocated by the internal function, and it should also be freed by the internal function. So, when the
  619. * user call this function, it will do nothing.
  620. */
  621. esp_err_t esp_hidh_dev_free(esp_hidh_dev_t *dev)
  622. {
  623. return ESP_OK;
  624. }
  625. esp_err_t esp_hidh_dev_free_inner(esp_hidh_dev_t *dev)
  626. {
  627. esp_err_t ret = ESP_FAIL;
  628. if (dev == NULL) {
  629. return ret;
  630. }
  631. esp_hidh_dev_t *d = NULL;
  632. esp_hidh_dev_t *next = NULL;
  633. lock_devices();
  634. TAILQ_FOREACH_SAFE(d, &s_esp_hidh_devices, devices, next) {
  635. if (d == dev) {
  636. TAILQ_REMOVE(&s_esp_hidh_devices, d, devices);
  637. esp_hidh_dev_resources_free(d);
  638. ret = ESP_OK;
  639. break;
  640. }
  641. }
  642. unlock_devices();
  643. if (ret != ESP_OK) {
  644. ESP_LOGW(TAG, "device not found");
  645. } else {
  646. ESP_LOGD(TAG, "device removed");
  647. }
  648. return ret;
  649. }
  650. #if CONFIG_BLUEDROID_ENABLED
  651. esp_hidh_dev_t *esp_hidh_dev_get_by_bda(esp_bd_addr_t bda)
  652. {
  653. esp_hidh_dev_t * d = NULL;
  654. lock_devices();
  655. TAILQ_FOREACH(d, &s_esp_hidh_devices, devices) {
  656. if (memcmp(bda, d->bda, sizeof(esp_bd_addr_t)) == 0) {
  657. unlock_devices();
  658. return d;
  659. }
  660. }
  661. unlock_devices();
  662. return NULL;
  663. }
  664. esp_hidh_dev_t *esp_hidh_dev_get_by_handle(uint8_t handle)
  665. {
  666. #if CONFIG_BT_HID_HOST_ENABLED
  667. esp_hidh_dev_t * d = NULL;
  668. lock_devices();
  669. TAILQ_FOREACH(d, &s_esp_hidh_devices, devices) {
  670. if (d->transport == ESP_HID_TRANSPORT_BT && d->bt.handle == handle) {
  671. unlock_devices();
  672. return d;
  673. }
  674. }
  675. unlock_devices();
  676. #endif /* CONFIG_BT_HID_HOST_ENABLED */
  677. return NULL;
  678. }
  679. esp_hidh_dev_t *esp_hidh_dev_get_by_conn_id(uint16_t conn_id)
  680. {
  681. #if CONFIG_GATTC_ENABLE
  682. esp_hidh_dev_t * d = NULL;
  683. lock_devices();
  684. TAILQ_FOREACH(d, &s_esp_hidh_devices, devices) {
  685. if (d->transport == ESP_HID_TRANSPORT_BLE && d->ble.conn_id == conn_id) {
  686. unlock_devices();
  687. return d;
  688. }
  689. }
  690. unlock_devices();
  691. #endif /* CONFIG_GATTC_ENABLE */
  692. return NULL;
  693. }
  694. /**
  695. * The deep copy data append the end of the esp_hidh_event_data_t, move the data pointer to the correct address. This is
  696. * a workaround way, it's better to use flexible array in the interface.
  697. */
  698. void esp_hidh_preprocess_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id,
  699. void *event_data)
  700. {
  701. esp_hidh_event_t event = (esp_hidh_event_t)event_id;
  702. esp_hidh_event_data_t *param = (esp_hidh_event_data_t *)event_data;
  703. switch (event) {
  704. case ESP_HIDH_INPUT_EVENT:
  705. if (param->input.length && param->input.data) {
  706. param->input.data = (uint8_t *)param + sizeof(esp_hidh_event_data_t);
  707. }
  708. break;
  709. case ESP_HIDH_FEATURE_EVENT:
  710. if (param->feature.length && param->feature.data) {
  711. param->feature.data = (uint8_t *)param + sizeof(esp_hidh_event_data_t);
  712. }
  713. break;
  714. default:
  715. break;
  716. }
  717. }
  718. void esp_hidh_post_process_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id,
  719. void *event_data)
  720. {
  721. esp_hidh_event_t event = (esp_hidh_event_t)event_id;
  722. esp_hidh_event_data_t *param = (esp_hidh_event_data_t *)event_data;
  723. switch (event) {
  724. case ESP_HIDH_OPEN_EVENT:
  725. if (param->open.status != ESP_OK) {
  726. esp_hidh_dev_t *dev = param->open.dev;
  727. if (dev) {
  728. #if CONFIG_BT_HID_HOST_ENABLED
  729. if (esp_hidh_dev_transport_get(dev) == ESP_HID_TRANSPORT_BT && param->open.status == ESP_HIDH_ERR_SDP) {
  730. break;
  731. }
  732. #endif /* CONFIG_BT_HID_HOST_ENABLED */
  733. esp_hidh_dev_free_inner(dev);
  734. }
  735. }
  736. break;
  737. case ESP_HIDH_CLOSE_EVENT:
  738. esp_hidh_dev_free_inner(param->close.dev);
  739. break;
  740. default:
  741. break;
  742. }
  743. }
  744. #endif /* CONFIG_BLUEDROID_ENABLED */