esp_hid_host_main.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "freertos/FreeRTOS.h"
  10. #include "freertos/task.h"
  11. #include "freertos/event_groups.h"
  12. #include "esp_system.h"
  13. #include "esp_wifi.h"
  14. #include "esp_event.h"
  15. #include "esp_log.h"
  16. #include "nvs_flash.h"
  17. #include "esp_bt.h"
  18. #include "esp_bt_defs.h"
  19. #include "esp_gap_ble_api.h"
  20. #include "esp_gatts_api.h"
  21. #include "esp_gatt_defs.h"
  22. #include "esp_bt_main.h"
  23. #include "esp_bt_device.h"
  24. #include "esp_hidh.h"
  25. #include "esp_hid_gap.h"
  26. static const char *TAG = "ESP_HIDH_DEMO";
  27. void hidh_callback(void *handler_args, esp_event_base_t base, int32_t id, void *event_data)
  28. {
  29. esp_hidh_event_t event = (esp_hidh_event_t)id;
  30. esp_hidh_event_data_t *param = (esp_hidh_event_data_t *)event_data;
  31. switch (event) {
  32. case ESP_HIDH_OPEN_EVENT: {
  33. if (param->open.status == ESP_OK) {
  34. const uint8_t *bda = esp_hidh_dev_bda_get(param->open.dev);
  35. ESP_LOGI(TAG, ESP_BD_ADDR_STR " OPEN: %s", ESP_BD_ADDR_HEX(bda), esp_hidh_dev_name_get(param->open.dev));
  36. esp_hidh_dev_dump(param->open.dev, stdout);
  37. } else {
  38. ESP_LOGE(TAG, " OPEN failed!");
  39. }
  40. break;
  41. }
  42. case ESP_HIDH_BATTERY_EVENT: {
  43. const uint8_t *bda = esp_hidh_dev_bda_get(param->battery.dev);
  44. ESP_LOGI(TAG, ESP_BD_ADDR_STR " BATTERY: %d%%", ESP_BD_ADDR_HEX(bda), param->battery.level);
  45. break;
  46. }
  47. case ESP_HIDH_INPUT_EVENT: {
  48. const uint8_t *bda = esp_hidh_dev_bda_get(param->input.dev);
  49. ESP_LOGI(TAG, ESP_BD_ADDR_STR " INPUT: %8s, MAP: %2u, ID: %3u, Len: %d, Data:", ESP_BD_ADDR_HEX(bda), esp_hid_usage_str(param->input.usage), param->input.map_index, param->input.report_id, param->input.length);
  50. ESP_LOG_BUFFER_HEX(TAG, param->input.data, param->input.length);
  51. break;
  52. }
  53. case ESP_HIDH_FEATURE_EVENT: {
  54. const uint8_t *bda = esp_hidh_dev_bda_get(param->feature.dev);
  55. ESP_LOGI(TAG, ESP_BD_ADDR_STR " FEATURE: %8s, MAP: %2u, ID: %3u, Len: %d", ESP_BD_ADDR_HEX(bda),
  56. esp_hid_usage_str(param->feature.usage), param->feature.map_index, param->feature.report_id,
  57. param->feature.length);
  58. ESP_LOG_BUFFER_HEX(TAG, param->feature.data, param->feature.length);
  59. break;
  60. }
  61. case ESP_HIDH_CLOSE_EVENT: {
  62. const uint8_t *bda = esp_hidh_dev_bda_get(param->close.dev);
  63. ESP_LOGI(TAG, ESP_BD_ADDR_STR " CLOSE: %s", ESP_BD_ADDR_HEX(bda), esp_hidh_dev_name_get(param->close.dev));
  64. break;
  65. }
  66. default:
  67. ESP_LOGI(TAG, "EVENT: %d", event);
  68. break;
  69. }
  70. }
  71. #define SCAN_DURATION_SECONDS 5
  72. void hid_demo_task(void *pvParameters)
  73. {
  74. size_t results_len = 0;
  75. esp_hid_scan_result_t *results = NULL;
  76. ESP_LOGI(TAG, "SCAN...");
  77. //start scan for HID devices
  78. esp_hid_scan(SCAN_DURATION_SECONDS, &results_len, &results);
  79. ESP_LOGI(TAG, "SCAN: %u results", results_len);
  80. if (results_len) {
  81. esp_hid_scan_result_t *r = results;
  82. esp_hid_scan_result_t *cr = NULL;
  83. while (r) {
  84. printf(" %s: " ESP_BD_ADDR_STR ", ", (r->transport == ESP_HID_TRANSPORT_BLE) ? "BLE" : "BT ", ESP_BD_ADDR_HEX(r->bda));
  85. printf("RSSI: %d, ", r->rssi);
  86. printf("USAGE: %s, ", esp_hid_usage_str(r->usage));
  87. #if CONFIG_BT_BLE_ENABLED
  88. if (r->transport == ESP_HID_TRANSPORT_BLE) {
  89. cr = r;
  90. printf("APPEARANCE: 0x%04x, ", r->ble.appearance);
  91. printf("ADDR_TYPE: '%s', ", ble_addr_type_str(r->ble.addr_type));
  92. }
  93. #endif /* CONFIG_BT_BLE_ENABLED */
  94. #if CONFIG_BT_HID_HOST_ENABLED
  95. if (r->transport == ESP_HID_TRANSPORT_BT) {
  96. cr = r;
  97. printf("COD: %s[", esp_hid_cod_major_str(r->bt.cod.major));
  98. esp_hid_cod_minor_print(r->bt.cod.minor, stdout);
  99. printf("] srv 0x%03x, ", r->bt.cod.service);
  100. print_uuid(&r->bt.uuid);
  101. printf(", ");
  102. }
  103. #endif /* CONFIG_BT_HID_HOST_ENABLED */
  104. printf("NAME: %s ", r->name ? r->name : "");
  105. printf("\n");
  106. r = r->next;
  107. }
  108. if (cr) {
  109. //open the last result
  110. esp_hidh_dev_open(cr->bda, cr->transport, cr->ble.addr_type);
  111. }
  112. //free the results
  113. esp_hid_scan_results_free(results);
  114. }
  115. vTaskDelete(NULL);
  116. }
  117. void app_main(void)
  118. {
  119. esp_err_t ret;
  120. #if HID_HOST_MODE == HIDH_IDLE_MODE
  121. ESP_LOGE(TAG, "Please turn on BT HID host or BLE!");
  122. return;
  123. #endif
  124. ret = nvs_flash_init();
  125. if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  126. ESP_ERROR_CHECK(nvs_flash_erase());
  127. ret = nvs_flash_init();
  128. }
  129. ESP_ERROR_CHECK( ret );
  130. ESP_LOGI(TAG, "setting hid gap, mode:%d", HID_HOST_MODE);
  131. ESP_ERROR_CHECK( esp_hid_gap_init(HID_HOST_MODE) );
  132. #if CONFIG_BT_BLE_ENABLED
  133. ESP_ERROR_CHECK( esp_ble_gattc_register_callback(esp_hidh_gattc_event_handler) );
  134. #endif /* CONFIG_BT_BLE_ENABLED */
  135. esp_hidh_config_t config = {
  136. .callback = hidh_callback,
  137. .event_stack_size = 4096,
  138. .callback_arg = NULL,
  139. };
  140. ESP_ERROR_CHECK( esp_hidh_init(&config) );
  141. xTaskCreate(&hid_demo_task, "hid_task", 6 * 1024, NULL, 2, NULL);
  142. }