From a025dfd965e8739fe3da1810abdddb0f2ac9033d Mon Sep 17 00:00:00 2001 From: liqigan Date: Thu, 3 Nov 2022 11:29:09 +0800 Subject: [PATCH] optimize HID Host disconnection procedure --- components/esp_hid/private/esp_hidh_private.h | 4 +- components/esp_hid/src/ble_hidh.c | 21 +++++- components/esp_hid/src/bt_hidh.c | 21 +++++- components/esp_hid/src/esp_hidh.c | 65 +++++-------------- 4 files changed, 56 insertions(+), 55 deletions(-) diff --git a/components/esp_hid/private/esp_hidh_private.h b/components/esp_hid/private/esp_hidh_private.h index aaa52574b9..a6ffda9443 100644 --- a/components/esp_hid/private/esp_hidh_private.h +++ b/components/esp_hid/private/esp_hidh_private.h @@ -123,7 +123,9 @@ esp_hidh_dev_report_t *esp_hidh_dev_get_input_report_by_id_and_proto(esp_hidh_de esp_hidh_dev_report_t *esp_hidh_dev_get_input_report_by_proto_and_data(esp_hidh_dev_t *dev, int protocol_mode, size_t len, const uint8_t *data, bool *has_report_id); esp_hidh_dev_report_t *esp_hidh_dev_get_report_by_handle(esp_hidh_dev_t *dev, uint16_t handle); //BLE Only -void esp_hidh_process_event_data_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, +void esp_hidh_preprocess_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, + void *event_data); +void esp_hidh_post_process_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data); void esp_hidh_dev_lock(esp_hidh_dev_t *dev); void esp_hidh_dev_unlock(esp_hidh_dev_t *dev); diff --git a/components/esp_hid/src/ble_hidh.c b/components/esp_hid/src/ble_hidh.c index f4daf07148..99b7f44b3b 100644 --- a/components/esp_hid/src/ble_hidh.c +++ b/components/esp_hid/src/ble_hidh.c @@ -51,6 +51,7 @@ static esp_event_loop_handle_t event_loop_handle; static uint8_t *s_read_data_val = NULL; static uint16_t s_read_data_len = 0; static esp_gatt_status_t s_read_status = ESP_GATT_OK; +static esp_event_handler_t s_event_callback; static esp_gatt_status_t read_char(esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t handle, esp_gatt_auth_req_t auth_req, uint8_t **out, uint16_t *out_len) { @@ -616,6 +617,18 @@ static void esp_ble_hidh_dev_dump(esp_hidh_dev_t *dev, FILE *fp) } +static void esp_ble_hidh_event_handler_wrapper(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, + void *event_data) +{ + esp_hidh_preprocess_event_handler(event_handler_arg, event_base, event_id, event_data); + + if (s_event_callback) { + s_event_callback(event_handler_arg, event_base, event_id, event_data); + } + + esp_hidh_post_process_event_handler(event_handler_arg, event_base, event_id, event_data); +} + esp_err_t esp_ble_hidh_init(const esp_hidh_config_t *config) { esp_err_t ret; @@ -653,10 +666,10 @@ esp_err_t esp_ble_hidh_init(const esp_hidh_config_t *config) break; } WAIT_CB(); + + s_event_callback = config->callback; ret = esp_event_handler_register_with(event_loop_handle, ESP_HIDH_EVENTS, ESP_EVENT_ANY_ID, - esp_hidh_process_event_data_handler, NULL); - ret |= esp_event_handler_register_with(event_loop_handle, ESP_HIDH_EVENTS, ESP_EVENT_ANY_ID, config->callback, - config->callback_arg); + esp_ble_hidh_event_handler_wrapper, config->callback_arg); } while (0); if (ret != ESP_OK) { @@ -690,6 +703,8 @@ esp_err_t esp_ble_hidh_deinit(void) } vSemaphoreDelete(s_ble_hidh_cb_semaphore); s_ble_hidh_cb_semaphore = NULL; + s_event_callback = NULL; + return err; } diff --git a/components/esp_hid/src/bt_hidh.c b/components/esp_hid/src/bt_hidh.c index 120e8cb2a0..ff583ed300 100644 --- a/components/esp_hid/src/bt_hidh.c +++ b/components/esp_hid/src/bt_hidh.c @@ -27,6 +27,7 @@ typedef struct { typedef struct { fixed_queue_t *connection_queue; /* Queue of connection */ esp_event_loop_handle_t event_loop_handle; + esp_event_handler_t event_callback; } hidh_local_param_t; static hidh_local_param_t hidh_local_param; @@ -172,6 +173,8 @@ static void free_local_param(void) if (hidh_local_param.connection_queue) { fixed_queue_free(hidh_local_param.connection_queue, free); } + + hidh_local_param.event_callback = NULL; } static void open_failed_cb(esp_hidh_dev_t *dev, esp_hidh_status_t status, esp_hidh_event_data_t *p, @@ -992,6 +995,18 @@ static void esp_bt_hidh_dev_dump(esp_hidh_dev_t *dev, FILE *fp) } } +static void esp_bt_hidh_event_handler_wrapper(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, + void *event_data) +{ + esp_hidh_preprocess_event_handler(event_handler_arg, event_base, event_id, event_data); + + if (hidh_local_param.event_callback) { + hidh_local_param.event_callback(event_handler_arg, event_base, event_id, event_data); + } + + esp_hidh_post_process_event_handler(event_handler_arg, event_base, event_id, event_data); +} + esp_err_t esp_bt_hidh_init(const esp_hidh_config_t *config) { esp_err_t ret = ESP_OK; @@ -1019,10 +1034,10 @@ esp_err_t esp_bt_hidh_init(const esp_hidh_config_t *config) ret = ESP_FAIL; break; } + + hidh_local_param.event_callback = config->callback; ret = esp_event_handler_register_with(hidh_local_param.event_loop_handle, ESP_HIDH_EVENTS, ESP_EVENT_ANY_ID, - esp_hidh_process_event_data_handler, NULL); - ret |= esp_event_handler_register_with(hidh_local_param.event_loop_handle, ESP_HIDH_EVENTS, ESP_EVENT_ANY_ID, - config->callback, config->callback_arg); + esp_bt_hidh_event_handler_wrapper, config->callback_arg); if (ret != ESP_OK) { ESP_LOGE(TAG, "event_loop register failed!"); ret = ESP_FAIL; diff --git a/components/esp_hid/src/esp_hidh.c b/components/esp_hid/src/esp_hidh.c index b052cc472f..8931f07fe6 100644 --- a/components/esp_hid/src/esp_hidh.c +++ b/components/esp_hid/src/esp_hidh.c @@ -18,11 +18,8 @@ ESP_EVENT_DEFINE_BASE(ESP_HIDH_EVENTS); static const char *TAG = "ESP_HIDH"; static esp_hidh_dev_head_t s_esp_hidh_devices; -static esp_timer_handle_t s_esp_hidh_timer; static SemaphoreHandle_t s_esp_hidh_devices_semaphore = NULL; -static void esp_hidh_dev_delay_free(void *arg); - static inline void lock_devices(void) { if (s_esp_hidh_devices_semaphore != NULL) { @@ -74,17 +71,6 @@ esp_err_t esp_hidh_init(const esp_hidh_config_t *config) TAILQ_INIT(&s_esp_hidh_devices); - esp_timer_create_args_t timer_config = { - .callback = &esp_hidh_dev_delay_free, - .arg = NULL, - .name = "hidh_timer" - }; - - if ((err = esp_timer_create(&timer_config, &s_esp_hidh_timer)) != ESP_OK) { - ESP_LOGE(TAG, "%s create timer failed!", __func__); - return err; - } - s_esp_hidh_devices_semaphore = xSemaphoreCreateMutex(); if (s_esp_hidh_devices_semaphore == NULL) { ESP_LOGE(TAG, "xSemaphoreCreateMutex failed!"); @@ -108,8 +94,6 @@ esp_err_t esp_hidh_init(const esp_hidh_config_t *config) if (err != ESP_OK) { vSemaphoreDelete(s_esp_hidh_devices_semaphore); s_esp_hidh_devices_semaphore = NULL; - esp_timer_delete(s_esp_hidh_timer); - s_esp_hidh_timer = NULL; } return err; @@ -123,11 +107,6 @@ esp_err_t esp_hidh_deinit(void) return err; } - if (esp_timer_is_active(s_esp_hidh_timer)) { - ESP_LOGE(TAG, "Busy, try again later!"); - return ESP_ERR_NOT_FINISHED; - } - if (!TAILQ_EMPTY(&s_esp_hidh_devices)) { ESP_LOGE(TAG, "Please disconnect all devices first!"); return err; @@ -151,8 +130,6 @@ esp_err_t esp_hidh_deinit(void) TAILQ_INIT(&s_esp_hidh_devices); vSemaphoreDelete(s_esp_hidh_devices_semaphore); s_esp_hidh_devices_semaphore = NULL; - esp_timer_delete(s_esp_hidh_timer); - s_esp_hidh_timer = NULL; } return err; } @@ -742,20 +719,6 @@ esp_err_t esp_hidh_dev_free_inner(esp_hidh_dev_t *dev) return ret; } -static void esp_hidh_dev_delay_free(void *arg) -{ - esp_hidh_dev_t *d = NULL; - esp_hidh_dev_t *next = NULL; - lock_devices(); - TAILQ_FOREACH_SAFE(d, &s_esp_hidh_devices, devices, next) { - if (!d->in_use) { - TAILQ_REMOVE(&s_esp_hidh_devices, d, devices); - esp_hidh_dev_resources_free(d); - } - } - unlock_devices(); -} - #if CONFIG_BLUEDROID_ENABLED esp_hidh_dev_t *esp_hidh_dev_get_by_bda(esp_bd_addr_t bda) { @@ -805,10 +768,10 @@ esp_hidh_dev_t *esp_hidh_dev_get_by_conn_id(uint16_t conn_id) /** * The deep copy data append the end of the esp_hidh_event_data_t, move the data pointer to the correct address. This is - * a workaround way, it's better to use flexiable array in the interface. + * a workaround way, it's better to use flexible array in the interface. */ -void esp_hidh_process_event_data_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, - void *event_data) +void esp_hidh_preprocess_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, + void *event_data) { esp_hidh_event_t event = (esp_hidh_event_t)event_id; esp_hidh_event_data_t *param = (esp_hidh_event_data_t *)event_data; @@ -824,19 +787,25 @@ void esp_hidh_process_event_data_handler(void *event_handler_arg, esp_event_base param->feature.data = (uint8_t *)param + sizeof(esp_hidh_event_data_t); } break; + default: + break; + } +} + +void esp_hidh_post_process_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, + void *event_data) +{ + esp_hidh_event_t event = (esp_hidh_event_t)event_id; + esp_hidh_event_data_t *param = (esp_hidh_event_data_t *)event_data; + + switch (event) { case ESP_HIDH_OPEN_EVENT: if (param->open.status != ESP_OK) { - if (s_esp_hidh_timer && !esp_timer_is_active(s_esp_hidh_timer) && - esp_timer_start_once(s_esp_hidh_timer, ESP_HIDH_DELAY_FREE_TO) != ESP_OK) { - ESP_LOGE(TAG, "%s set hidh timer failed!", __func__); - } + esp_hidh_dev_free_inner(param->open.dev); } break; case ESP_HIDH_CLOSE_EVENT: - if (s_esp_hidh_timer && !esp_timer_is_active(s_esp_hidh_timer) && - esp_timer_start_once(s_esp_hidh_timer, ESP_HIDH_DELAY_FREE_TO) != ESP_OK) { - ESP_LOGE(TAG, "%s set hidh timer failed!", __func__); - } + esp_hidh_dev_free_inner(param->close.dev); break; default: break;