refactor(esp_hid): Create one common event loop

After this change, only one event loop is created.
It is reused by all transport layers (BT, BLE, USB).
This commit is contained in:
Tomas Rezucha 2024-03-06 21:26:29 +01:00
parent c539b7cde5
commit 868d375c1d
6 changed files with 176 additions and 267 deletions

View File

@ -45,9 +45,9 @@ struct esp_hidh_dev_s {
esp_hid_usage_t usage; esp_hid_usage_t usage;
esp_hid_transport_t transport; //BT, BLE or USB esp_hid_transport_t transport; //BT, BLE or USB
esp_hid_trans_type_t trans_type; //indicate what transaction is going on, new transaction only be allowed after the previous done esp_hid_trans_type_t trans_type; //indicate what transaction is going on, new transaction only be allowed after the previous done
esp_timer_handle_t trans_timer; //transactiion timer esp_timer_handle_t trans_timer; //transaction timer
uint8_t report_type; //Get_Report tansaction report_type uint8_t report_type; //Get_Report transaction report_type
uint8_t report_id; //Get_Report tansaction report_id uint8_t report_id; //Get_Report transaction report_id
#if CONFIG_BT_NIMBLE_ENABLED #if CONFIG_BT_NIMBLE_ENABLED
uint8_t *protocol_mode; // protocol mode is unique for each hid service instance uint8_t *protocol_mode; // protocol mode is unique for each hid service instance
#else #else
@ -107,10 +107,36 @@ struct esp_hidh_dev_s {
TAILQ_ENTRY(esp_hidh_dev_s) devices; TAILQ_ENTRY(esp_hidh_dev_s) devices;
}; };
typedef TAILQ_HEAD(esp_hidh_dev_head_s, esp_hidh_dev_s) esp_hidh_dev_head_t; // ------------------------------------------------- Transport layer functions --------------------------------------------------
/**
* @brief Get HIDH event loop
*
* Transport layers will post events into the loop
*
* @return esp_event_loop_handle_t Handle to HIDH event loop
*/
esp_event_loop_handle_t esp_hidh_get_event_loop(void);
/**
* @brief Allocate HIDH device
*
* The resources can be freed by esp_hidh_dev_free_inner()
*
* @return esp_hidh_dev_t* Pointer to newly allocated HIDH device
*/
esp_hidh_dev_t *esp_hidh_dev_malloc(void); esp_hidh_dev_t *esp_hidh_dev_malloc(void);
/**
* @brief Free HIDH device
*
* @param[in] dev Device handle obtained from esp_hidh_dev_malloc()
* @return
* - ESP_OK: Success
* - ESP_FAIL: Parameter is NULL or it is not a valid HIDH device
*/
esp_err_t esp_hidh_dev_free_inner(esp_hidh_dev_t *dev);
#if CONFIG_BLUEDROID_ENABLED #if CONFIG_BLUEDROID_ENABLED
esp_hidh_dev_t *esp_hidh_dev_get_by_bda(esp_bd_addr_t bda); //BT/BLE esp_hidh_dev_t *esp_hidh_dev_get_by_bda(esp_bd_addr_t bda); //BT/BLE
esp_hidh_dev_t *esp_hidh_dev_get_by_handle(uint8_t handle); //Classic Bluetooth Only esp_hidh_dev_t *esp_hidh_dev_get_by_handle(uint8_t handle); //Classic Bluetooth Only
@ -130,13 +156,12 @@ esp_hidh_dev_report_t *esp_hidh_dev_get_input_report_by_proto_and_data(esp_hidh_
esp_hidh_dev_report_t *esp_hidh_dev_get_report_by_handle(esp_hidh_dev_t *dev, uint16_t handle); //BLE Only 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_preprocess_event_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 *event_data);
void esp_hidh_post_process_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void esp_hidh_postprocess_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id,
void *event_data); void *event_data);
void esp_hidh_dev_lock(esp_hidh_dev_t *dev); void esp_hidh_dev_lock(esp_hidh_dev_t *dev);
void esp_hidh_dev_unlock(esp_hidh_dev_t *dev); void esp_hidh_dev_unlock(esp_hidh_dev_t *dev);
void esp_hidh_dev_wait(esp_hidh_dev_t *dev); void esp_hidh_dev_wait(esp_hidh_dev_t *dev);
void esp_hidh_dev_send(esp_hidh_dev_t *dev); void esp_hidh_dev_send(esp_hidh_dev_t *dev);
esp_err_t esp_hidh_dev_free_inner(esp_hidh_dev_t *dev);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -10,6 +10,7 @@
#include "esp_private/esp_hidh_private.h" #include "esp_private/esp_hidh_private.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_check.h"
#include "esp_bt_defs.h" #include "esp_bt_defs.h"
#include "esp_bt_main.h" #include "esp_bt_main.h"
@ -50,7 +51,6 @@ static esp_event_loop_handle_t event_loop_handle;
static uint8_t *s_read_data_val = NULL; static uint8_t *s_read_data_val = NULL;
static uint16_t s_read_data_len = 0; static uint16_t s_read_data_len = 0;
static esp_gatt_status_t s_read_status = ESP_GATT_OK; 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) 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)
{ {
@ -615,95 +615,45 @@ 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 esp_ble_hidh_init(const esp_hidh_config_t *config)
{ {
esp_err_t ret; esp_err_t ret = ESP_OK;
if (config == NULL) { ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "Config is NULL");
ESP_LOGE(TAG, "Config is NULL"); ESP_RETURN_ON_FALSE(!s_ble_hidh_cb_semaphore, ESP_ERR_INVALID_STATE, TAG, "Already initialized");
return ESP_FAIL;
} event_loop_handle = esp_hidh_get_event_loop();
if (s_ble_hidh_cb_semaphore != NULL) {
ESP_LOGE(TAG, "Already initialised");
return ESP_FAIL;
}
s_ble_hidh_cb_semaphore = xSemaphoreCreateBinary(); s_ble_hidh_cb_semaphore = xSemaphoreCreateBinary();
if (s_ble_hidh_cb_semaphore == NULL) { ESP_RETURN_ON_FALSE(s_ble_hidh_cb_semaphore,
ESP_LOGE(TAG, "xSemaphoreCreateMutex failed!"); ESP_ERR_NO_MEM, TAG, "Allocation failed");
return ESP_FAIL;
}
esp_event_loop_args_t event_task_args = {
.queue_size = 5,
.task_name = "esp_ble_hidh_events",
.task_priority = uxTaskPriorityGet(NULL),
.task_stack_size = config->event_stack_size > 0 ? config->event_stack_size : 2048,
.task_core_id = tskNO_AFFINITY
};
do { ESP_GOTO_ON_ERROR(
ret = esp_event_loop_create(&event_task_args, &event_loop_handle); esp_ble_gattc_app_register(0),
if (ret != ESP_OK) { gattc_fail, TAG, "esp_ble_gattc_app_register failed!");
ESP_LOGE(TAG, "%s esp_event_loop_create failed!", __func__);
break;
}
ret = esp_ble_gattc_app_register(0);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "esp_ble_gattc_app_register failed!");
break;
}
WAIT_CB(); WAIT_CB();
return ret;
s_event_callback = config->callback; gattc_fail:
ret = esp_event_handler_register_with(event_loop_handle, ESP_HIDH_EVENTS, ESP_EVENT_ANY_ID,
esp_ble_hidh_event_handler_wrapper, config->callback_arg);
} while (0);
if (ret != ESP_OK) {
if (event_loop_handle) {
esp_event_loop_delete(event_loop_handle);
}
if (s_ble_hidh_cb_semaphore) { if (s_ble_hidh_cb_semaphore) {
vSemaphoreDelete(s_ble_hidh_cb_semaphore); vSemaphoreDelete(s_ble_hidh_cb_semaphore);
s_ble_hidh_cb_semaphore = NULL; s_ble_hidh_cb_semaphore = NULL;
} }
}
return ret; return ret;
} }
esp_err_t esp_ble_hidh_deinit(void) esp_err_t esp_ble_hidh_deinit(void)
{ {
if (s_ble_hidh_cb_semaphore == NULL) { ESP_RETURN_ON_FALSE(s_ble_hidh_cb_semaphore, ESP_ERR_INVALID_STATE, TAG, "Already deinitialized");
ESP_LOGE(TAG, "Already deinitialised"); ESP_RETURN_ON_ERROR(
return ESP_FAIL; esp_ble_gattc_app_unregister(hid_gattc_if),
} TAG, "App Unregister Failed");
esp_err_t err = esp_ble_gattc_app_unregister(hid_gattc_if); if (s_ble_hidh_cb_semaphore) {
if (err != ESP_OK) {
ESP_LOGE(TAG, "App Unregister Failed");
return err;
}
if (event_loop_handle) {
esp_event_loop_delete(event_loop_handle);
}
vSemaphoreDelete(s_ble_hidh_cb_semaphore); vSemaphoreDelete(s_ble_hidh_cb_semaphore);
s_ble_hidh_cb_semaphore = NULL; s_ble_hidh_cb_semaphore = NULL;
s_event_callback = NULL; }
return ESP_OK;
return err;
} }
esp_hidh_dev_t *esp_ble_hidh_dev_open(esp_bd_addr_t bda, esp_ble_addr_type_t address_type) esp_hidh_dev_t *esp_ble_hidh_dev_open(esp_bd_addr_t bda, esp_ble_addr_type_t address_type)

View File

@ -9,6 +9,7 @@
#include "esp_private/esp_hidh_private.h" #include "esp_private/esp_hidh_private.h"
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include "esp_check.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
@ -27,7 +28,6 @@ typedef struct {
typedef struct { typedef struct {
fixed_queue_t *connection_queue; /* Queue of connection */ fixed_queue_t *connection_queue; /* Queue of connection */
esp_event_loop_handle_t event_loop_handle; esp_event_loop_handle_t event_loop_handle;
esp_event_handler_t event_callback;
} hidh_local_param_t; } hidh_local_param_t;
static hidh_local_param_t hidh_local_param; static hidh_local_param_t hidh_local_param;
@ -167,15 +167,9 @@ static inline bool is_trans_done(esp_hidh_dev_t *dev)
static void free_local_param(void) static void free_local_param(void)
{ {
if (hidh_local_param.event_loop_handle) {
esp_event_loop_delete(hidh_local_param.event_loop_handle);
}
if (hidh_local_param.connection_queue) { if (hidh_local_param.connection_queue) {
fixed_queue_free(hidh_local_param.connection_queue, free); 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, static void open_failed_cb(esp_hidh_dev_t *dev, esp_hidh_status_t status, esp_hidh_event_data_t *p,
@ -994,68 +988,31 @@ 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 esp_bt_hidh_init(const esp_hidh_config_t *config)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
if (config == NULL) { ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "Config is NULL");
ESP_LOGE(TAG, "Config is NULL");
return ESP_ERR_INVALID_ARG;
}
esp_event_loop_args_t event_task_args = {
.queue_size = 5,
.task_name = "esp_bt_hidh_events",
.task_priority = uxTaskPriorityGet(NULL),
.task_stack_size = config->event_stack_size > 0 ? config->event_stack_size : 4096,
.task_core_id = tskNO_AFFINITY
};
do { hidh_local_param.connection_queue = fixed_queue_new(QUEUE_SIZE_MAX);
if ((hidh_local_param.connection_queue = fixed_queue_new(QUEUE_SIZE_MAX)) == NULL) { ESP_RETURN_ON_FALSE(hidh_local_param.connection_queue, ESP_ERR_NO_MEM, TAG, "Alloc failed");
ESP_LOGE(TAG, "connection_queue create failed!"); hidh_local_param.event_loop_handle = esp_hidh_get_event_loop();
ret = ESP_FAIL;
break;
}
ret = esp_event_loop_create(&event_task_args, &hidh_local_param.event_loop_handle);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "esp_event_loop_create failed!");
ret = ESP_FAIL;
break;
}
hidh_local_param.event_callback = config->callback; ESP_GOTO_ON_ERROR(
ret = esp_event_handler_register_with(hidh_local_param.event_loop_handle, ESP_HIDH_EVENTS, ESP_EVENT_ANY_ID, esp_bt_hid_host_register_callback(esp_hh_cb),
esp_bt_hidh_event_handler_wrapper, config->callback_arg); bt_hid_fail, TAG, "BT HID register failed");
if (ret != ESP_OK) { ESP_GOTO_ON_ERROR(
ESP_LOGE(TAG, "event_loop register failed!"); esp_bt_hid_host_init(),
ret = ESP_FAIL; bt_hid_fail, TAG, "BT HID register failed");
break; return ret;
}
ret = esp_bt_hid_host_register_callback(esp_hh_cb);
ret |= esp_bt_hid_host_init();
} while (0);
if (ret != ESP_OK) { bt_hid_fail:
free_local_param(); free_local_param();
}
return ret; return ret;
} }
esp_err_t esp_bt_hidh_deinit(void) esp_err_t esp_bt_hidh_deinit(void)
{ {
esp_err_t ret = esp_bt_hid_host_deinit(); return esp_bt_hid_host_deinit();
return ret;
} }
static esp_hidh_dev_t *hidh_dev_ctor(esp_bd_addr_t bda) static esp_hidh_dev_t *hidh_dev_ctor(esp_bd_addr_t bda)

View File

@ -10,7 +10,8 @@
#include "ble_hidh.h" #include "ble_hidh.h"
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include "esp_event_base.h" #include "esp_event.h"
#include "esp_check.h"
#if CONFIG_BT_HID_HOST_ENABLED #if CONFIG_BT_HID_HOST_ENABLED
#include "esp_hidh_api.h" #include "esp_hidh_api.h"
#endif /* CONFIG_BT_HID_HOST_ENABLED */ #endif /* CONFIG_BT_HID_HOST_ENABLED */
@ -20,8 +21,10 @@ ESP_EVENT_DEFINE_BASE(ESP_HIDH_EVENTS);
static const char *TAG = "ESP_HIDH"; static const char *TAG = "ESP_HIDH";
static esp_hidh_dev_head_t s_esp_hidh_devices; static TAILQ_HEAD(esp_hidh_dev_head_s, esp_hidh_dev_s) s_esp_hidh_devices;
static SemaphoreHandle_t s_esp_hidh_devices_semaphore = NULL; static SemaphoreHandle_t s_esp_hidh_devices_semaphore = NULL;
static esp_event_loop_handle_t s_esp_hidh_event_loop_h;
static esp_event_handler_t s_event_callback;
static inline void lock_devices(void) static inline void lock_devices(void)
{ {
@ -58,82 +61,107 @@ bool esp_hidh_dev_exists(esp_hidh_dev_t *dev)
return false; return false;
} }
static void esp_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_postprocess_event_handler(event_handler_arg, event_base, event_id, event_data);
}
esp_err_t esp_hidh_init(const esp_hidh_config_t *config) esp_err_t esp_hidh_init(const esp_hidh_config_t *config)
{ {
esp_err_t err = ESP_FAIL; esp_err_t ret = ESP_OK;
if (config == NULL) { ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "Config is NULL");
ESP_LOGE(TAG, "Config is NULL"); ESP_RETURN_ON_FALSE(!s_esp_hidh_devices_semaphore, ESP_ERR_INVALID_STATE, TAG, "Already initialized");
return err;
}
if (s_esp_hidh_devices_semaphore != NULL) {
ESP_LOGE(TAG, "Already initialized");
return err;
}
TAILQ_INIT(&s_esp_hidh_devices); TAILQ_INIT(&s_esp_hidh_devices);
s_event_callback = config->callback;
const esp_event_loop_args_t event_task_args = {
.queue_size = 5,
.task_name = "esp_hidh_events",
.task_priority = uxTaskPriorityGet(NULL),
.task_stack_size = config->event_stack_size > 0 ? config->event_stack_size : 4096,
.task_core_id = tskNO_AFFINITY
};
esp_event_loop_create(&event_task_args, &s_esp_hidh_event_loop_h);
s_esp_hidh_devices_semaphore = xSemaphoreCreateMutex(); s_esp_hidh_devices_semaphore = xSemaphoreCreateMutex();
if (s_esp_hidh_devices_semaphore == NULL) {
ESP_LOGE(TAG, "xSemaphoreCreateMutex failed!");
return err;
}
// unlock_devices();
err = ESP_OK;
ESP_GOTO_ON_FALSE(s_esp_hidh_devices_semaphore && s_esp_hidh_event_loop_h,
ESP_ERR_NO_MEM, alloc_fail, TAG, "Allocation failed");
ESP_GOTO_ON_ERROR(
esp_event_handler_register_with(s_esp_hidh_event_loop_h, ESP_HIDH_EVENTS, ESP_EVENT_ANY_ID,
esp_hidh_event_handler_wrapper, config->callback_arg),
alloc_fail, TAG, "event_loop register failed!");
// BT and BLE are natively supported by esp_hid.
// For USB support you must initialize it manually after esp_hidh_init()
#if CONFIG_BT_HID_HOST_ENABLED #if CONFIG_BT_HID_HOST_ENABLED
if (err == ESP_OK) { ESP_GOTO_ON_ERROR(
err = esp_bt_hidh_init(config); esp_bt_hidh_init(config),
} alloc_fail, TAG, "BT HIDH init failed");
#endif /* CONFIG_BT_HID_HOST_ENABLED */ #endif /* CONFIG_BT_HID_HOST_ENABLED */
#if CONFIG_GATTC_ENABLE || CONFIG_BT_NIMBLE_ENABLED #if CONFIG_GATTC_ENABLE || CONFIG_BT_NIMBLE_ENABLED
if (err == ESP_OK) { ESP_GOTO_ON_ERROR(
err = esp_ble_hidh_init(config); esp_ble_hidh_init(config),
} bt_fail, TAG, "BLE HIDH init failed");
#endif /* CONFIG_GATTC_ENABLE */ #endif /* CONFIG_GATTC_ENABLE */
return ret;
if (err != ESP_OK) { #if CONFIG_GATTC_ENABLE || CONFIG_BT_NIMBLE_ENABLED
bt_fail:
#if CONFIG_BT_HID_HOST_ENABLED
esp_bt_hidh_deinit();
#endif /* CONFIG_BT_HID_HOST_ENABLED */
#endif
alloc_fail:
if (s_esp_hidh_devices_semaphore) {
vSemaphoreDelete(s_esp_hidh_devices_semaphore); vSemaphoreDelete(s_esp_hidh_devices_semaphore);
s_esp_hidh_devices_semaphore = NULL; s_esp_hidh_devices_semaphore = NULL;
} }
if (s_esp_hidh_event_loop_h) {
esp_event_loop_delete(s_esp_hidh_event_loop_h);
s_esp_hidh_event_loop_h = NULL;
}
return ret;
}
return err; esp_event_loop_handle_t esp_hidh_get_event_loop(void)
{
return s_esp_hidh_event_loop_h;
} }
esp_err_t esp_hidh_deinit(void) esp_err_t esp_hidh_deinit(void)
{ {
esp_err_t err = ESP_FAIL; esp_err_t ret = ESP_OK;
if (s_esp_hidh_devices_semaphore == NULL) { ESP_RETURN_ON_FALSE(s_esp_hidh_devices_semaphore, ESP_ERR_INVALID_STATE, TAG, "Already deinitialized");
ESP_LOGE(TAG, "Already uninitialized"); ESP_RETURN_ON_FALSE(TAILQ_EMPTY(&s_esp_hidh_devices), ESP_ERR_INVALID_STATE, TAG, "Please disconnect all devices first!");
return err;
}
if (!TAILQ_EMPTY(&s_esp_hidh_devices)) {
ESP_LOGE(TAG, "Please disconnect all devices first!");
return err;
}
err = ESP_OK;
#if CONFIG_BT_HID_HOST_ENABLED #if CONFIG_BT_HID_HOST_ENABLED
if (err == ESP_OK) { ESP_RETURN_ON_ERROR(
err = esp_bt_hidh_deinit(); esp_bt_hidh_deinit(),
} TAG, "BT HIDH deinit failed");
#endif /* CONFIG_BT_HID_HOST_ENABLED */ #endif /* CONFIG_BT_HID_HOST_ENABLED */
#if CONFIG_GATTC_ENABLE || CONFIG_BT_NIMBLE_ENABLED #if CONFIG_GATTC_ENABLE || CONFIG_BT_NIMBLE_ENABLED
if (err == ESP_OK) { ESP_RETURN_ON_ERROR(
err = esp_ble_hidh_deinit(); esp_ble_hidh_deinit(),
} TAG, "BLE HIDH deinit failed");
#endif /* CONFIG_GATTC_ENABLE */ #endif /* CONFIG_GATTC_ENABLE */
if (err == ESP_OK) {
TAILQ_INIT(&s_esp_hidh_devices); TAILQ_INIT(&s_esp_hidh_devices);
vSemaphoreDelete(s_esp_hidh_devices_semaphore); vSemaphoreDelete(s_esp_hidh_devices_semaphore);
s_esp_hidh_devices_semaphore = NULL; s_esp_hidh_devices_semaphore = NULL;
} esp_event_loop_delete(s_esp_hidh_event_loop_h);
return err; s_esp_hidh_event_loop_h = NULL;
return ret;
} }
#if CONFIG_BLUEDROID_ENABLED #if CONFIG_BLUEDROID_ENABLED
@ -811,7 +839,7 @@ void esp_hidh_preprocess_event_handler(void *event_handler_arg, esp_event_base_t
} }
} }
void esp_hidh_post_process_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void esp_hidh_postprocess_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id,
void *event_data) void *event_data)
{ {
esp_hidh_event_t event = (esp_hidh_event_t)event_id; esp_hidh_event_t event = (esp_hidh_event_t)event_id;
@ -895,7 +923,7 @@ void esp_hidh_preprocess_event_handler(void *event_handler_arg, esp_event_base_t
} }
} }
void esp_hidh_post_process_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void esp_hidh_postprocess_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id,
void *event_data) void *event_data)
{ {
esp_hidh_event_t event = (esp_hidh_event_t)event_id; esp_hidh_event_t event = (esp_hidh_event_t)event_id;

View File

@ -9,6 +9,7 @@
#include "esp_private/esp_hidh_private.h" #include "esp_private/esp_hidh_private.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_check.h"
#include "esp_hid_common.h" #include "esp_hid_common.h"
@ -59,7 +60,6 @@ static esp_event_loop_handle_t event_loop_handle;
static uint8_t *s_read_data_val = NULL; static uint8_t *s_read_data_val = NULL;
static uint16_t s_read_data_len = 0; static uint16_t s_read_data_len = 0;
static int s_read_status = 0; static int s_read_status = 0;
static esp_event_handler_t s_event_callback;
/** /**
* Utility function to log an array of bytes. * Utility function to log an array of bytes.
@ -870,18 +870,6 @@ 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);
}
static void nimble_host_synced(void) static void nimble_host_synced(void)
{ {
/* /*
@ -896,50 +884,14 @@ static void nimble_host_reset(int reason)
esp_err_t esp_ble_hidh_init(const esp_hidh_config_t *config) esp_err_t esp_ble_hidh_init(const esp_hidh_config_t *config)
{ {
esp_err_t ret; esp_err_t ret = ESP_OK;
if (config == NULL) { ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "Config is NULL");
ESP_LOGE(TAG, "Config is NULL"); ESP_RETURN_ON_FALSE(!s_ble_hidh_cb_semaphore, ESP_ERR_INVALID_STATE, TAG, "Already initialized");
return ESP_FAIL;
} event_loop_handle = esp_hidh_get_event_loop();
if (s_ble_hidh_cb_semaphore != NULL) {
ESP_LOGE(TAG, "Already initialised");
return ESP_FAIL;
}
s_ble_hidh_cb_semaphore = xSemaphoreCreateBinary(); s_ble_hidh_cb_semaphore = xSemaphoreCreateBinary();
if (s_ble_hidh_cb_semaphore == NULL) { ESP_RETURN_ON_FALSE(s_ble_hidh_cb_semaphore,
ESP_LOGE(TAG, "xSemaphoreCreateMutex failed!"); ESP_ERR_NO_MEM, TAG, "Allocation failed");
return ESP_FAIL;
}
esp_event_loop_args_t event_task_args = {
.queue_size = 5,
.task_name = "esp_ble_hidh_events",
.task_priority = uxTaskPriorityGet(NULL),
.task_stack_size = config->event_stack_size > 0 ? config->event_stack_size : 2048,
.task_core_id = tskNO_AFFINITY
};
do {
ret = esp_event_loop_create(&event_task_args, &event_loop_handle);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "%s esp_event_loop_create failed!", __func__);
break;
}
s_event_callback = config->callback;
ret = esp_event_handler_register_with(event_loop_handle, ESP_HIDH_EVENTS, ESP_EVENT_ANY_ID,
esp_ble_hidh_event_handler_wrapper, config->callback_arg);
} while (0);
if (ret != ESP_OK) {
if (event_loop_handle) {
esp_event_loop_delete(event_loop_handle);
}
if (s_ble_hidh_cb_semaphore) {
vSemaphoreDelete(s_ble_hidh_cb_semaphore);
s_ble_hidh_cb_semaphore = NULL;
}
}
ble_hs_cfg.reset_cb = nimble_host_reset; ble_hs_cfg.reset_cb = nimble_host_reset;
ble_hs_cfg.sync_cb = nimble_host_synced; ble_hs_cfg.sync_cb = nimble_host_synced;
@ -948,19 +900,13 @@ esp_err_t esp_ble_hidh_init(const esp_hidh_config_t *config)
esp_err_t esp_ble_hidh_deinit(void) esp_err_t esp_ble_hidh_deinit(void)
{ {
if (s_ble_hidh_cb_semaphore == NULL) { ESP_RETURN_ON_FALSE(s_ble_hidh_cb_semaphore, ESP_ERR_INVALID_STATE, TAG, "Already deinitialized");
ESP_LOGE(TAG, "Already deinitialised"); if (s_ble_hidh_cb_semaphore) {
return ESP_FAIL;
}
if (event_loop_handle) {
esp_event_loop_delete(event_loop_handle);
}
vSemaphoreDelete(s_ble_hidh_cb_semaphore); vSemaphoreDelete(s_ble_hidh_cb_semaphore);
s_ble_hidh_cb_semaphore = NULL; s_ble_hidh_cb_semaphore = NULL;
s_event_callback = NULL; }
return 0; return ESP_OK;
} }
esp_hidh_dev_t *esp_ble_hidh_dev_open(uint8_t *bda, uint8_t address_type) esp_hidh_dev_t *esp_ble_hidh_dev_open(uint8_t *bda, uint8_t address_type)

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Unlicense OR CC0-1.0 * SPDX-License-Identifier: Unlicense OR CC0-1.0
*/ */
@ -8,13 +8,16 @@
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <inttypes.h> #include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "esp_bt_device.h"
#include "esp_hid_gap.h" #include "esp_hid_gap.h"
#if CONFIG_BT_BLUEDROID_ENABLED
#include "esp_bt_device.h"
#endif
#if CONFIG_BT_NIMBLE_ENABLED #if CONFIG_BT_NIMBLE_ENABLED
#include "host/ble_hs.h" #include "host/ble_hs.h"
#include "nimble/nimble_port.h" #include "nimble/nimble_port.h"