mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
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:
parent
c539b7cde5
commit
868d375c1d
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user