mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
optimize HID Host disconnection procedure
This commit is contained in:
parent
39189e7522
commit
54c5e28c80
@ -131,7 +131,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);
|
||||
|
@ -59,6 +59,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)
|
||||
{
|
||||
@ -624,6 +625,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;
|
||||
@ -661,10 +674,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) {
|
||||
@ -698,6 +711,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;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,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;
|
||||
@ -180,6 +181,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,
|
||||
@ -1000,6 +1003,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;
|
||||
@ -1027,10 +1042,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;
|
||||
|
@ -18,10 +18,7 @@ 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 xSemaphoreHandle s_esp_hidh_devices_semaphore = NULL;
|
||||
|
||||
static void esp_hidh_dev_delay_free(void *arg);
|
||||
static SemaphoreHandle_t s_esp_hidh_devices_semaphore = NULL;
|
||||
|
||||
static inline void lock_devices(void)
|
||||
{
|
||||
@ -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,9 +768,9 @@ 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 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;
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user