Skip to content

Commit

Permalink
Merge branch 'feat/esp_hid_clean_interface' into 'master'
Browse files Browse the repository at this point in the history
refactor(esp_hid): Create one common event loop

See merge request espressif/esp-idf!29449
  • Loading branch information
tore-espressif committed Mar 14, 2024
2 parents ee8fa6a + 868d375 commit 4f900ed
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 267 deletions.
43 changes: 34 additions & 9 deletions components/esp_hid/include/esp_private/esp_hidh_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ struct esp_hidh_dev_s {
esp_hid_usage_t usage;
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_timer_handle_t trans_timer; //transactiion timer
uint8_t report_type; //Get_Report tansaction report_type
uint8_t report_id; //Get_Report tansaction report_id
esp_timer_handle_t trans_timer; //transaction timer
uint8_t report_type; //Get_Report transaction report_type
uint8_t report_id; //Get_Report transaction report_id
#if CONFIG_BT_NIMBLE_ENABLED
uint8_t *protocol_mode; // protocol mode is unique for each hid service instance
#else
Expand All @@ -66,8 +66,8 @@ struct esp_hidh_dev_s {
void *tmp;
size_t tmp_len;

SemaphoreHandle_t semaphore;
SemaphoreHandle_t mutex;
SemaphoreHandle_t semaphore;
SemaphoreHandle_t mutex;

esp_err_t (*close)(esp_hidh_dev_t *dev);
esp_err_t (*report_write)(esp_hidh_dev_t *dev, size_t map_index, size_t report_id, int report_type, uint8_t *data, size_t len);
Expand Down Expand Up @@ -107,10 +107,36 @@ struct esp_hidh_dev_s {
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);

/**
* @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
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
Expand All @@ -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
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_postprocess_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);
void esp_hidh_dev_wait(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
}
#endif
100 changes: 25 additions & 75 deletions components/esp_hid/src/ble_hidh.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "esp_private/esp_hidh_private.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"

#include "esp_bt_defs.h"
#include "esp_bt_main.h"
Expand Down Expand Up @@ -50,7 +51,6 @@ 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)
{
Expand Down Expand Up @@ -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 ret;
if (config == NULL) {
ESP_LOGE(TAG, "Config is NULL");
return ESP_FAIL;
}
if (s_ble_hidh_cb_semaphore != NULL) {
ESP_LOGE(TAG, "Already initialised");
return ESP_FAIL;
}
s_ble_hidh_cb_semaphore = xSemaphoreCreateBinary();
if (s_ble_hidh_cb_semaphore == NULL) {
ESP_LOGE(TAG, "xSemaphoreCreateMutex 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;
}

ret = esp_ble_gattc_app_register(0);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "esp_ble_gattc_app_register failed!");
break;
}
WAIT_CB();
esp_err_t ret = ESP_OK;
ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "Config is NULL");
ESP_RETURN_ON_FALSE(!s_ble_hidh_cb_semaphore, ESP_ERR_INVALID_STATE, TAG, "Already initialized");

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);
event_loop_handle = esp_hidh_get_event_loop();
s_ble_hidh_cb_semaphore = xSemaphoreCreateBinary();
ESP_RETURN_ON_FALSE(s_ble_hidh_cb_semaphore,
ESP_ERR_NO_MEM, TAG, "Allocation failed");

if (ret != ESP_OK) {
if (event_loop_handle) {
esp_event_loop_delete(event_loop_handle);
}
ESP_GOTO_ON_ERROR(
esp_ble_gattc_app_register(0),
gattc_fail, TAG, "esp_ble_gattc_app_register failed!");
WAIT_CB();
return ret;

if (s_ble_hidh_cb_semaphore) {
vSemaphoreDelete(s_ble_hidh_cb_semaphore);
s_ble_hidh_cb_semaphore = NULL;
}
gattc_fail:
if (s_ble_hidh_cb_semaphore) {
vSemaphoreDelete(s_ble_hidh_cb_semaphore);
s_ble_hidh_cb_semaphore = NULL;
}
return ret;
}

esp_err_t esp_ble_hidh_deinit(void)
{
if (s_ble_hidh_cb_semaphore == NULL) {
ESP_LOGE(TAG, "Already deinitialised");
return ESP_FAIL;
}
ESP_RETURN_ON_FALSE(s_ble_hidh_cb_semaphore, ESP_ERR_INVALID_STATE, TAG, "Already deinitialized");
ESP_RETURN_ON_ERROR(
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 (err != ESP_OK) {
ESP_LOGE(TAG, "App Unregister Failed");
return err;
if (s_ble_hidh_cb_semaphore) {
vSemaphoreDelete(s_ble_hidh_cb_semaphore);
s_ble_hidh_cb_semaphore = NULL;
}

if (event_loop_handle) {
esp_event_loop_delete(event_loop_handle);
}
vSemaphoreDelete(s_ble_hidh_cb_semaphore);
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)
Expand Down
77 changes: 17 additions & 60 deletions components/esp_hid/src/bt_hidh.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "esp_private/esp_hidh_private.h"
#include <string.h>
#include <stdbool.h>
#include "esp_check.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
Expand All @@ -27,7 +28,6 @@ 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;
Expand Down Expand Up @@ -167,15 +167,9 @@ static inline bool is_trans_done(esp_hidh_dev_t *dev)

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) {
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,
Expand Down Expand Up @@ -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 ret = ESP_OK;
if (config == 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 {
if ((hidh_local_param.connection_queue = fixed_queue_new(QUEUE_SIZE_MAX)) == NULL) {
ESP_LOGE(TAG, "connection_queue create failed!");
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;
ret = esp_event_handler_register_with(hidh_local_param.event_loop_handle, ESP_HIDH_EVENTS, ESP_EVENT_ANY_ID,
esp_bt_hidh_event_handler_wrapper, config->callback_arg);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "event_loop register failed!");
ret = ESP_FAIL;
break;
}
ret = esp_bt_hid_host_register_callback(esp_hh_cb);
ret |= esp_bt_hid_host_init();
} while (0);
ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "Config is NULL");

hidh_local_param.connection_queue = fixed_queue_new(QUEUE_SIZE_MAX);
ESP_RETURN_ON_FALSE(hidh_local_param.connection_queue, ESP_ERR_NO_MEM, TAG, "Alloc failed");
hidh_local_param.event_loop_handle = esp_hidh_get_event_loop();

ESP_GOTO_ON_ERROR(
esp_bt_hid_host_register_callback(esp_hh_cb),
bt_hid_fail, TAG, "BT HID register failed");
ESP_GOTO_ON_ERROR(
esp_bt_hid_host_init(),
bt_hid_fail, TAG, "BT HID register failed");
return ret;

if (ret != ESP_OK) {
free_local_param();
}
bt_hid_fail:
free_local_param();
return ret;
}

esp_err_t esp_bt_hidh_deinit(void)
{
esp_err_t ret = esp_bt_hid_host_deinit();
return ret;
return esp_bt_hid_host_deinit();
}

static esp_hidh_dev_t *hidh_dev_ctor(esp_bd_addr_t bda)
Expand Down
Loading

0 comments on commit 4f900ed

Please sign in to comment.