mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-18 06:35:35 +03:00
fix(bt/example): fix critical issues of classic_bt examples reported by AI review
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -75,7 +75,7 @@ static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
case ESP_A2D_SNK_PSC_CFG_EVT:
|
||||
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
|
||||
case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: {
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_CONNECTION_STATE_EVT:
|
||||
@@ -83,9 +83,9 @@ static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
case ESP_A2D_AUDIO_CFG_EVT:
|
||||
case ESP_A2D_SEP_REG_STATE_EVT: {
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE
|
||||
bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
#else
|
||||
bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -173,5 +173,5 @@ void app_main(void)
|
||||
|
||||
bt_app_task_start_up();
|
||||
/* bluetooth device name, connection mode and profile set up */
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -37,7 +37,7 @@ static TaskHandle_t s_bt_app_task_handle = NULL;
|
||||
|
||||
static bool bt_app_send_msg(bt_app_msg_t *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
if (msg == NULL || s_bt_app_task_queue == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,9 @@ static void bt_app_task_handler(void *arg)
|
||||
}
|
||||
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
@@ -85,7 +88,8 @@ static void bt_app_task_handler(void *arg)
|
||||
* EXTERN FUNCTION DEFINITIONS
|
||||
********************************/
|
||||
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback)
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback)
|
||||
{
|
||||
ESP_LOGD(BT_APP_CORE_TAG, "%s event: 0x%x, param len: %d", __func__, event, param_len);
|
||||
|
||||
@@ -95,6 +99,7 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
msg.sig = BT_APP_SIG_WORK_DISPATCH;
|
||||
msg.event = event;
|
||||
msg.cb = p_cback;
|
||||
msg.free_cb = p_free_cback;
|
||||
|
||||
if (param_len == 0) {
|
||||
return bt_app_send_msg(&msg);
|
||||
@@ -105,7 +110,14 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
if (p_copy_cback) {
|
||||
p_copy_cback(msg.param, p_params, param_len);
|
||||
}
|
||||
return bt_app_send_msg(&msg);
|
||||
if (!bt_app_send_msg(&msg)) {
|
||||
if (p_free_cback) {
|
||||
p_free_cback(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +137,15 @@ void bt_app_task_shut_down(void)
|
||||
s_bt_app_task_handle = NULL;
|
||||
}
|
||||
if (s_bt_app_task_queue) {
|
||||
bt_app_msg_t msg;
|
||||
while (xQueueReceive(s_bt_app_task_queue, &msg, 0) == pdTRUE) {
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
vQueueDelete(s_bt_app_task_queue);
|
||||
s_bt_app_task_queue = NULL;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -25,11 +25,19 @@
|
||||
*/
|
||||
typedef void (* bt_app_cb_t) (uint16_t event, void *param);
|
||||
|
||||
/**
|
||||
* @brief parameter deep-free function
|
||||
*
|
||||
* @param [in] p_param pointer to the parameter
|
||||
*/
|
||||
typedef void (* bt_app_free_cb_t) (void *p_param);
|
||||
|
||||
/* message to be sent */
|
||||
typedef struct {
|
||||
uint16_t sig; /*!< signal to bt_app_task */
|
||||
uint16_t event; /*!< message event id */
|
||||
bt_app_cb_t cb; /*!< context switch callback */
|
||||
bt_app_free_cb_t free_cb; /*!< parameter deep-free function */
|
||||
void *param; /*!< parameter area needs to be last */
|
||||
} bt_app_msg_t;
|
||||
|
||||
@@ -50,10 +58,12 @@ typedef void (* bt_app_copy_cb_t) (void *p_dest, void *p_src, int len);
|
||||
* @param [in] p_params pointer to the parameter
|
||||
* @param [in] param_len length of the parameter
|
||||
* @param [in] p_copy_cback parameter deep-copy function
|
||||
* @param [in] p_free_cback parameter deep-free function
|
||||
*
|
||||
* @return true if work dispatch successfully, false otherwise
|
||||
*/
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback);
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback);
|
||||
|
||||
/**
|
||||
* @brief start up the application task
|
||||
|
||||
@@ -360,7 +360,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
||||
|
||||
static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
{
|
||||
bt_app_work_dispatch(bt_app_av_sm_hdlr, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_app_av_sm_hdlr, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
}
|
||||
|
||||
/* generate some random noise to simulate source audio */
|
||||
@@ -380,7 +380,7 @@ static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len)
|
||||
|
||||
static void bt_app_a2d_heart_beat(TimerHandle_t arg)
|
||||
{
|
||||
bt_app_work_dispatch(bt_app_av_sm_hdlr, BT_APP_HEART_BEAT_EVT, NULL, 0, NULL);
|
||||
bt_app_work_dispatch(bt_app_av_sm_hdlr, BT_APP_HEART_BEAT_EVT, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
static void bt_app_av_sm_hdlr(uint16_t event, void *param)
|
||||
@@ -726,13 +726,12 @@ static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t
|
||||
switch (event) {
|
||||
case ESP_AVRC_CT_CONNECTION_STATE_EVT:
|
||||
case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT:
|
||||
case ESP_AVRC_CT_METADATA_RSP_EVT:
|
||||
case ESP_AVRC_CT_CHANGE_NOTIFY_EVT:
|
||||
case ESP_AVRC_CT_REMOTE_FEATURES_EVT:
|
||||
case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT:
|
||||
case ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT:
|
||||
case ESP_AVRC_CT_PROF_STATE_EVT: {
|
||||
bt_app_work_dispatch(bt_av_hdl_avrc_ct_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_av_hdl_avrc_ct_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -793,12 +792,6 @@ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param)
|
||||
rc->psth_rsp.key_state, rc->psth_rsp.rsp_code);
|
||||
break;
|
||||
}
|
||||
/* when metadata responded, this event comes */
|
||||
case ESP_AVRC_CT_METADATA_RSP_EVT: {
|
||||
ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata response: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text);
|
||||
free(rc->meta_rsp.attr_text);
|
||||
break;
|
||||
}
|
||||
/* when notification changed, this event comes */
|
||||
case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: {
|
||||
ESP_LOGI(BT_RC_CT_TAG, "AVRC event notification: %d", rc->change_ntf.event_id);
|
||||
@@ -906,5 +899,5 @@ void app_main(void)
|
||||
ESP_LOGI(BT_AV_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str)));
|
||||
bt_app_task_start_up();
|
||||
/* Bluetooth device name, connection mode and profile set up */
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_STACK_UP_EVT, NULL, 0, NULL);
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_STACK_UP_EVT, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -89,7 +89,7 @@ static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
case ESP_A2D_SNK_PSC_CFG_EVT:
|
||||
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
|
||||
case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: {
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_CONNECTION_STATE_EVT:
|
||||
@@ -98,12 +98,12 @@ static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
case ESP_A2D_SEP_REG_STATE_EVT: {
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE
|
||||
bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
#else
|
||||
bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
#endif
|
||||
#else
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -130,16 +130,13 @@ static void bt_app_a2d_audio_data_cb(esp_a2d_conn_hdl_t conn_hdl, esp_a2d_audio_
|
||||
static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_AVRC_CT_METADATA_RSP_EVT:
|
||||
case ESP_AVRC_CT_CONNECTION_STATE_EVT:
|
||||
case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT:
|
||||
case ESP_AVRC_CT_CHANGE_NOTIFY_EVT:
|
||||
case ESP_AVRC_CT_REMOTE_FEATURES_EVT:
|
||||
case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT:
|
||||
case ESP_AVRC_CT_COVER_ART_STATE_EVT:
|
||||
case ESP_AVRC_CT_COVER_ART_DATA_EVT:
|
||||
case ESP_AVRC_CT_PROF_STATE_EVT: {
|
||||
bt_app_work_dispatch(bt_avrc_common_ct_evt_def_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_avrc_common_ct_evt_def_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -155,13 +152,13 @@ static void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t
|
||||
case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT:
|
||||
case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT:
|
||||
case ESP_AVRC_TG_PROF_STATE_EVT: {
|
||||
bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_AVRC_TG_CONNECTION_STATE_EVT:
|
||||
case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT:
|
||||
case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: {
|
||||
bt_app_work_dispatch(bt_avrc_avc_tg_evt_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_avrc_avc_tg_evt_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -247,5 +244,5 @@ void app_main(void)
|
||||
|
||||
bt_app_task_start_up();
|
||||
/* bluetooth device name, connection mode and profile set up */
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -115,7 +115,7 @@ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
case ESP_A2D_SNK_PSC_CFG_EVT:
|
||||
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
|
||||
case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: {
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_CONNECTION_STATE_EVT:
|
||||
@@ -124,12 +124,12 @@ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
case ESP_A2D_SEP_REG_STATE_EVT: {
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE
|
||||
bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
#else
|
||||
bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
#endif
|
||||
#else
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -157,7 +157,8 @@ void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_AVRC_CT_METADATA_RSP_EVT: {
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), bt_avrc_common_copy_metadata);
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t),
|
||||
bt_avrc_common_copy_metadata, bt_avrc_common_free_metadata);
|
||||
break;
|
||||
}
|
||||
case ESP_AVRC_CT_COVER_ART_DATA_EVT: {
|
||||
@@ -169,7 +170,7 @@ void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param
|
||||
ESP_LOGE(BT_RC_CT_TAG, "Cover Art Client get operation failed");
|
||||
break;
|
||||
}
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_AVRC_CT_CONNECTION_STATE_EVT:
|
||||
@@ -179,7 +180,7 @@ void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param
|
||||
case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT:
|
||||
case ESP_AVRC_CT_COVER_ART_STATE_EVT:
|
||||
case ESP_AVRC_CT_PROF_STATE_EVT:
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event);
|
||||
@@ -197,7 +198,7 @@ void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param
|
||||
case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT:
|
||||
case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT:
|
||||
case ESP_AVRC_TG_PROF_STATE_EVT:
|
||||
bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(BT_RC_TG_TAG, "Invalid AVRC event: %d", event);
|
||||
|
||||
@@ -129,5 +129,5 @@ void app_main(void)
|
||||
|
||||
bt_app_task_start_up();
|
||||
/* bluetooth device name, connection mode and profile set up */
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -92,7 +92,7 @@ static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
case ESP_A2D_SNK_PSC_CFG_EVT:
|
||||
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
|
||||
case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: {
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_CONNECTION_STATE_EVT:
|
||||
@@ -101,12 +101,12 @@ static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
case ESP_A2D_SEP_REG_STATE_EVT: {
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_STREAM_ENABLE
|
||||
#if CONFIG_EXAMPLE_A2DP_SINK_USE_EXTERNAL_CODEC == FALSE
|
||||
bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
#else
|
||||
bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_ext_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
#endif
|
||||
#else
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -183,7 +183,8 @@ static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_AVRC_CT_METADATA_RSP_EVT: {
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), bt_avrc_common_copy_metadata);
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t),
|
||||
bt_avrc_common_copy_metadata, bt_avrc_common_free_metadata);
|
||||
break;
|
||||
}
|
||||
case ESP_AVRC_CT_CONNECTION_STATE_EVT:
|
||||
@@ -192,7 +193,7 @@ static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t
|
||||
case ESP_AVRC_CT_REMOTE_FEATURES_EVT:
|
||||
case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT:
|
||||
case ESP_AVRC_CT_PROF_STATE_EVT:
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event);
|
||||
@@ -210,7 +211,7 @@ static void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t
|
||||
case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT:
|
||||
case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT:
|
||||
case ESP_AVRC_TG_PROF_STATE_EVT:
|
||||
bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(BT_RC_TG_TAG, "Invalid AVRC event: %d", event);
|
||||
@@ -291,5 +292,5 @@ void app_main(void)
|
||||
|
||||
bt_app_task_start_up();
|
||||
/* bluetooth device name, connection mode and profile set up */
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -124,7 +124,7 @@ static void update_device_info(esp_bt_gap_cb_param_t *param)
|
||||
uint8_t *bdname = NULL;
|
||||
uint8_t bdname_len = 0;
|
||||
uint8_t *eir = NULL;
|
||||
uint8_t eir_len = 0;
|
||||
int eir_len = 0;
|
||||
esp_bt_gap_dev_prop_t *p;
|
||||
|
||||
ESP_LOGI(GAP_TAG, "Device found: %s", bda2str(param->disc_res.bda, bda_str, sizeof(bda_str)));
|
||||
@@ -177,8 +177,9 @@ static void update_device_info(esp_bt_gap_cb_param_t *param)
|
||||
p_dev->bdname_len = bdname_len;
|
||||
}
|
||||
if (eir_len > 0) {
|
||||
memcpy(p_dev->eir, eir, eir_len);
|
||||
p_dev->eir_len = eir_len;
|
||||
uint8_t copy_len = (eir_len > ESP_BT_GAP_EIR_DATA_LEN) ? ESP_BT_GAP_EIR_DATA_LEN : eir_len;
|
||||
memcpy(p_dev->eir, eir, copy_len);
|
||||
p_dev->eir_len = copy_len;
|
||||
}
|
||||
|
||||
if (p_dev->bdname_len == 0) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -39,7 +39,7 @@ static TaskHandle_t s_bt_app_task_handle = NULL; /* handle of application task
|
||||
|
||||
static bool bt_app_send_msg(bt_app_msg_t *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
if (msg == NULL || s_bt_app_task_queue == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,9 @@ static void bt_app_task_handler(void *arg)
|
||||
} /* switch (msg.sig) */
|
||||
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
@@ -87,7 +90,8 @@ static void bt_app_task_handler(void *arg)
|
||||
* EXTERNAL FUNCTION DEFINITIONS
|
||||
*******************************/
|
||||
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback)
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback)
|
||||
{
|
||||
ESP_LOGD(BT_APP_CORE_TAG, "%s event: 0x%x, param len: %d", __func__, event, param_len);
|
||||
|
||||
@@ -97,6 +101,7 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
msg.sig = BT_APP_SIG_WORK_DISPATCH;
|
||||
msg.event = event;
|
||||
msg.cb = p_cback;
|
||||
msg.free_cb = p_free_cback;
|
||||
|
||||
if (param_len == 0) {
|
||||
return bt_app_send_msg(&msg);
|
||||
@@ -107,7 +112,14 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
if (p_copy_cback) {
|
||||
p_copy_cback(msg.param, p_params, param_len);
|
||||
}
|
||||
return bt_app_send_msg(&msg);
|
||||
if (!bt_app_send_msg(&msg)) {
|
||||
if (p_free_cback) {
|
||||
p_free_cback(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +139,15 @@ void bt_app_task_shut_down(void)
|
||||
s_bt_app_task_handle = NULL;
|
||||
}
|
||||
if (s_bt_app_task_queue) {
|
||||
bt_app_msg_t msg;
|
||||
while (xQueueReceive(s_bt_app_task_queue, &msg, 0) == pdTRUE) {
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
vQueueDelete(s_bt_app_task_queue);
|
||||
s_bt_app_task_queue = NULL;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -25,6 +25,13 @@
|
||||
*/
|
||||
typedef void (* bt_app_cb_t) (uint16_t event, void *param);
|
||||
|
||||
/**
|
||||
* @brief parameter deep-free function
|
||||
*
|
||||
* @param [in] p_param pointer to parameter data
|
||||
*/
|
||||
typedef void (* bt_app_free_cb_t) (void *p_param);
|
||||
|
||||
/**
|
||||
* @brief handler for write and read
|
||||
*/
|
||||
@@ -35,6 +42,7 @@ typedef struct {
|
||||
uint16_t sig; /*!< signal to bt_app_task */
|
||||
uint16_t event; /*!< message event id */
|
||||
bt_app_cb_t cb; /*!< context switch callback */
|
||||
bt_app_free_cb_t free_cb;/*!< parameter deep-free function */
|
||||
void *param; /*!< parameter area needs to be last */
|
||||
} bt_app_msg_t;
|
||||
|
||||
@@ -52,13 +60,15 @@ typedef void (* bt_app_copy_cb_t) (void *p_dest, void *p_src, int len);
|
||||
*
|
||||
* @param [in] p_cback callback function
|
||||
* @param [in] event event id
|
||||
* @param [in] p_params callback paramters
|
||||
* @param [in] p_params callback parameters
|
||||
* @param [in] param_len parameter length in byte
|
||||
* @param [in] p_copy_cback parameter deep-copy function
|
||||
* @param [in] p_free_cback parameter deep-free function
|
||||
*
|
||||
* @return true if work dispatch successfully, false otherwise
|
||||
*/
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback);
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback);
|
||||
|
||||
/**
|
||||
* @brief start up the application task
|
||||
|
||||
@@ -257,7 +257,7 @@ static void esp_bt_l2cap_cb(esp_bt_l2cap_cb_event_t event, esp_bt_l2cap_cb_param
|
||||
case ESP_BT_L2CAP_START_EVT:
|
||||
case ESP_BT_L2CAP_SRV_STOP_EVT:
|
||||
case ESP_BT_L2CAP_VFS_REGISTER_EVT: {
|
||||
bt_app_work_dispatch(esp_hdl_bt_l2cap_cb_evt, event, param, sizeof(esp_bt_l2cap_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(esp_hdl_bt_l2cap_cb_evt, event, param, sizeof(esp_bt_l2cap_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -324,7 +324,7 @@ static void esp_sdp_cb(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param)
|
||||
case ESP_SDP_SEARCH_COMP_EVT:
|
||||
case ESP_SDP_CREATE_RECORD_COMP_EVT:
|
||||
case ESP_SDP_REMOVE_RECORD_COMP_EVT: {
|
||||
bt_app_work_dispatch(esp_hdl_sdp_cb_evt, event, param, sizeof(esp_sdp_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(esp_hdl_sdp_cb_evt, event, param, sizeof(esp_sdp_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -359,7 +359,7 @@ static void esp_hdl_sdp_cb_evt(uint16_t event, void *p_param)
|
||||
break;
|
||||
case ESP_SDP_SEARCH_COMP_EVT:
|
||||
ESP_LOGI(SDP_TAG, "ESP_SDP_SEARCH_COMP_EVT: status:%d", sdp_param->search.status);
|
||||
if (sdp_param->search.status == ESP_SDP_SUCCESS) {
|
||||
if (sdp_param->search.status == ESP_SDP_SUCCESS && sdp_param->search.record_count > 0 && sdp_param->search.records) {
|
||||
ESP_LOGI(SDP_TAG, "Remote device address: %s", bda2str(sdp_param->search.remote_addr, bda_str, sizeof(bda_str)));
|
||||
ESP_LOGI(SDP_TAG, "Remote device record count: %d", sdp_param->search.record_count);
|
||||
ESP_LOGI(SDP_TAG, "Remote device rfcomm channel number: %"PRId32, sdp_param->search.records->hdr.rfcomm_channel_number);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -39,7 +39,7 @@ static TaskHandle_t s_bt_app_task_handle = NULL; /* handle of application task
|
||||
|
||||
static bool bt_app_send_msg(bt_app_msg_t *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
if (msg == NULL || s_bt_app_task_queue == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,9 @@ static void bt_app_task_handler(void *arg)
|
||||
} /* switch (msg.sig) */
|
||||
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
@@ -87,7 +90,8 @@ static void bt_app_task_handler(void *arg)
|
||||
* EXTERNAL FUNCTION DEFINITIONS
|
||||
*******************************/
|
||||
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback)
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback)
|
||||
{
|
||||
ESP_LOGD(BT_APP_CORE_TAG, "%s event: 0x%x, param len: %d", __func__, event, param_len);
|
||||
|
||||
@@ -97,6 +101,7 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
msg.sig = BT_APP_SIG_WORK_DISPATCH;
|
||||
msg.event = event;
|
||||
msg.cb = p_cback;
|
||||
msg.free_cb = p_free_cback;
|
||||
|
||||
if (param_len == 0) {
|
||||
return bt_app_send_msg(&msg);
|
||||
@@ -107,7 +112,14 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
if (p_copy_cback) {
|
||||
p_copy_cback(msg.param, p_params, param_len);
|
||||
}
|
||||
return bt_app_send_msg(&msg);
|
||||
if (!bt_app_send_msg(&msg)) {
|
||||
if (p_free_cback) {
|
||||
p_free_cback(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +139,15 @@ void bt_app_task_shut_down(void)
|
||||
s_bt_app_task_handle = NULL;
|
||||
}
|
||||
if (s_bt_app_task_queue) {
|
||||
bt_app_msg_t msg;
|
||||
while (xQueueReceive(s_bt_app_task_queue, &msg, 0) == pdTRUE) {
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
vQueueDelete(s_bt_app_task_queue);
|
||||
s_bt_app_task_queue = NULL;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -25,6 +25,13 @@
|
||||
*/
|
||||
typedef void (* bt_app_cb_t) (uint16_t event, void *param);
|
||||
|
||||
/**
|
||||
* @brief parameter deep-free function
|
||||
*
|
||||
* @param [in] p_param pointer to parameter data
|
||||
*/
|
||||
typedef void (* bt_app_free_cb_t) (void *p_param);
|
||||
|
||||
/**
|
||||
* @brief handler for write and read
|
||||
*/
|
||||
@@ -35,6 +42,7 @@ typedef struct {
|
||||
uint16_t sig; /*!< signal to bt_app_task */
|
||||
uint16_t event; /*!< message event id */
|
||||
bt_app_cb_t cb; /*!< context switch callback */
|
||||
bt_app_free_cb_t free_cb;/*!< parameter deep-free function */
|
||||
void *param; /*!< parameter area needs to be last */
|
||||
} bt_app_msg_t;
|
||||
|
||||
@@ -52,13 +60,15 @@ typedef void (* bt_app_copy_cb_t) (void *p_dest, void *p_src, int len);
|
||||
*
|
||||
* @param [in] p_cback callback function
|
||||
* @param [in] event event id
|
||||
* @param [in] p_params callback paramters
|
||||
* @param [in] p_params callback parameters
|
||||
* @param [in] param_len parameter length in byte
|
||||
* @param [in] p_copy_cback parameter deep-copy function
|
||||
* @param [in] p_free_cback parameter deep-free function
|
||||
*
|
||||
* @return true if work dispatch successfully, false otherwise
|
||||
*/
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback);
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback);
|
||||
|
||||
/**
|
||||
* @brief start up the application task
|
||||
|
||||
@@ -164,7 +164,7 @@ static void esp_bt_l2cap_cb(esp_bt_l2cap_cb_event_t event, esp_bt_l2cap_cb_param
|
||||
case ESP_BT_L2CAP_START_EVT:
|
||||
case ESP_BT_L2CAP_SRV_STOP_EVT:
|
||||
case ESP_BT_L2CAP_VFS_REGISTER_EVT: {
|
||||
bt_app_work_dispatch(esp_hdl_bt_l2cap_cb_evt, event, param, sizeof(esp_bt_l2cap_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(esp_hdl_bt_l2cap_cb_evt, event, param, sizeof(esp_bt_l2cap_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -239,7 +239,7 @@ static void esp_sdp_cb(esp_sdp_cb_event_t event, esp_sdp_cb_param_t *param)
|
||||
case ESP_SDP_SEARCH_COMP_EVT:
|
||||
case ESP_SDP_CREATE_RECORD_COMP_EVT:
|
||||
case ESP_SDP_REMOVE_RECORD_COMP_EVT: {
|
||||
bt_app_work_dispatch(esp_hdl_sdp_cb_evt, event, param, sizeof(esp_sdp_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(esp_hdl_sdp_cb_evt, event, param, sizeof(esp_sdp_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -49,7 +49,7 @@ static void console_uart_task(void *pvParameters)
|
||||
|
||||
if ((tmp_buf = (uint8_t *)calloc(TMP_BUF_LEN, sizeof(uint8_t))) == NULL) {
|
||||
ESP_LOGE(TAG_CNSL,"temp buf malloc fail");
|
||||
return;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
@@ -118,8 +118,16 @@ esp_err_t console_uart_init(void)
|
||||
}
|
||||
|
||||
uart_set_pin(CONSOLE_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||
uart_driver_install(CONSOLE_UART_NUM, 1024, 1024, 8, &uart_queue, 0);
|
||||
xTaskCreate(console_uart_task, "uTask", 4 * 1024, NULL, 8, NULL);
|
||||
ret = uart_driver_install(CONSOLE_UART_NUM, 1024, 1024, 8, &uart_queue, 0);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG_CNSL, "Uart %d driver install err %04x", CONSOLE_UART_NUM, ret);
|
||||
return ret;
|
||||
}
|
||||
if (xTaskCreate(console_uart_task, "uTask", 4 * 1024, NULL, 8, NULL) != pdPASS) {
|
||||
ESP_LOGE(TAG_CNSL, "Create console task failed");
|
||||
uart_driver_delete(CONSOLE_UART_NUM);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ static void esp_spp_cb(uint16_t e, void *p)
|
||||
static void esp_spp_stack_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
|
||||
{
|
||||
/* To avoid stucking Bluetooth stack, we dispatch the SPP callback event to the other lower priority task */
|
||||
spp_task_work_dispatch(esp_spp_cb, event, param, sizeof(esp_spp_cb_param_t), NULL);
|
||||
spp_task_work_dispatch(esp_spp_cb, event, param, sizeof(esp_spp_cb_param_t), NULL, NULL);
|
||||
}
|
||||
|
||||
void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -21,7 +21,8 @@ static void spp_task_work_dispatched(spp_task_msg_t *msg);
|
||||
static QueueHandle_t spp_task_task_queue = NULL;
|
||||
static TaskHandle_t spp_task_task_handle = NULL;
|
||||
|
||||
bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_params, int param_len, spp_task_copy_cb_t p_copy_cback)
|
||||
bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
spp_task_copy_cb_t p_copy_cback, spp_task_free_cb_t p_free_cback)
|
||||
{
|
||||
ESP_LOGD(SPP_TASK_TAG, "%s event 0x%x, param len %d", __func__, event, param_len);
|
||||
|
||||
@@ -31,6 +32,7 @@ bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_param
|
||||
msg.sig = SPP_TASK_SIG_WORK_DISPATCH;
|
||||
msg.event = event;
|
||||
msg.cb = p_cback;
|
||||
msg.free_cb = p_free_cback;
|
||||
|
||||
if (param_len == 0) {
|
||||
return spp_task_send_msg(&msg);
|
||||
@@ -41,7 +43,14 @@ bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_param
|
||||
if (p_copy_cback) {
|
||||
p_copy_cback(&msg, msg.param, p_params);
|
||||
}
|
||||
return spp_task_send_msg(&msg);
|
||||
if (!spp_task_send_msg(&msg)) {
|
||||
if (p_free_cback) {
|
||||
p_free_cback(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +93,9 @@ static void spp_task_task_handler(void *arg)
|
||||
}
|
||||
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
@@ -104,6 +116,15 @@ void spp_task_task_shut_down(void)
|
||||
spp_task_task_handle = NULL;
|
||||
}
|
||||
if (spp_task_task_queue) {
|
||||
spp_task_msg_t msg;
|
||||
while (xQueueReceive(spp_task_task_queue, &msg, 0) == pdTRUE) {
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
vQueueDelete(spp_task_task_queue);
|
||||
spp_task_task_queue = NULL;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -20,11 +20,17 @@
|
||||
*/
|
||||
typedef void (* spp_task_cb_t) (uint16_t event, void *param);
|
||||
|
||||
/**
|
||||
* @brief parameter deep-free function
|
||||
*/
|
||||
typedef void (* spp_task_free_cb_t) (void *p_param);
|
||||
|
||||
/* message to be sent */
|
||||
typedef struct {
|
||||
uint16_t sig; /*!< signal to spp_task_task */
|
||||
uint16_t event; /*!< message event id */
|
||||
spp_task_cb_t cb; /*!< context switch callback */
|
||||
spp_task_free_cb_t free_cb; /*!< parameter deep-free function */
|
||||
void *param; /*!< parameter area needs to be last */
|
||||
} spp_task_msg_t;
|
||||
|
||||
@@ -36,7 +42,8 @@ typedef void (* spp_task_copy_cb_t) (spp_task_msg_t *msg, void *p_dest, void *p_
|
||||
/**
|
||||
* @brief work dispatcher for the application task
|
||||
*/
|
||||
bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_params, int param_len, spp_task_copy_cb_t p_copy_cback);
|
||||
bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
spp_task_copy_cb_t p_copy_cback, spp_task_free_cb_t p_free_cback);
|
||||
|
||||
void spp_task_task_start_up(void);
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
|
||||
static void esp_spp_stack_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
|
||||
{
|
||||
/* To avoid stucking Bluetooth stack, we dispatch the SPP callback event to the other lower priority task */
|
||||
spp_task_work_dispatch(esp_spp_cb, event, param, sizeof(esp_spp_cb_param_t), NULL);
|
||||
spp_task_work_dispatch(esp_spp_cb, event, param, sizeof(esp_spp_cb_param_t), NULL, NULL);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -21,7 +21,8 @@ static void spp_task_work_dispatched(spp_task_msg_t *msg);
|
||||
static QueueHandle_t spp_task_task_queue = NULL;
|
||||
static TaskHandle_t spp_task_task_handle = NULL;
|
||||
|
||||
bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_params, int param_len, spp_task_copy_cb_t p_copy_cback)
|
||||
bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
spp_task_copy_cb_t p_copy_cback, spp_task_free_cb_t p_free_cback)
|
||||
{
|
||||
ESP_LOGD(SPP_TASK_TAG, "%s event 0x%x, param len %d", __func__, event, param_len);
|
||||
|
||||
@@ -31,6 +32,7 @@ bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_param
|
||||
msg.sig = SPP_TASK_SIG_WORK_DISPATCH;
|
||||
msg.event = event;
|
||||
msg.cb = p_cback;
|
||||
msg.free_cb = p_free_cback;
|
||||
|
||||
if (param_len == 0) {
|
||||
return spp_task_send_msg(&msg);
|
||||
@@ -41,7 +43,14 @@ bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_param
|
||||
if (p_copy_cback) {
|
||||
p_copy_cback(&msg, msg.param, p_params);
|
||||
}
|
||||
return spp_task_send_msg(&msg);
|
||||
if (!spp_task_send_msg(&msg)) {
|
||||
if (p_free_cback) {
|
||||
p_free_cback(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +93,9 @@ static void spp_task_task_handler(void *arg)
|
||||
}
|
||||
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
@@ -104,6 +116,15 @@ void spp_task_task_shut_down(void)
|
||||
spp_task_task_handle = NULL;
|
||||
}
|
||||
if (spp_task_task_queue) {
|
||||
spp_task_msg_t msg;
|
||||
while (xQueueReceive(spp_task_task_queue, &msg, 0) == pdTRUE) {
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
vQueueDelete(spp_task_task_queue);
|
||||
spp_task_task_queue = NULL;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -20,11 +20,17 @@
|
||||
*/
|
||||
typedef void (* spp_task_cb_t) (uint16_t event, void *param);
|
||||
|
||||
/**
|
||||
* @brief parameter deep-free function
|
||||
*/
|
||||
typedef void (* spp_task_free_cb_t) (void *p_param);
|
||||
|
||||
/* message to be sent */
|
||||
typedef struct {
|
||||
uint16_t sig; /*!< signal to spp_task_task */
|
||||
uint16_t event; /*!< message event id */
|
||||
spp_task_cb_t cb; /*!< context switch callback */
|
||||
spp_task_free_cb_t free_cb; /*!< parameter deep-free function */
|
||||
void *param; /*!< parameter area needs to be last */
|
||||
} spp_task_msg_t;
|
||||
|
||||
@@ -36,7 +42,8 @@ typedef void (* spp_task_copy_cb_t) (spp_task_msg_t *msg, void *p_dest, void *p_
|
||||
/**
|
||||
* @brief work dispatcher for the application task
|
||||
*/
|
||||
bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_params, int param_len, spp_task_copy_cb_t p_copy_cback);
|
||||
bool spp_task_work_dispatch(spp_task_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
spp_task_copy_cb_t p_copy_cback, spp_task_free_cb_t p_free_cback);
|
||||
|
||||
void spp_task_task_start_up(void);
|
||||
|
||||
|
||||
@@ -67,7 +67,9 @@ static void audio_sink_srv_dac_task_handler(void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
dac_continuous_write(s_dac_cb.tx_chan, data, item_size, &bytes_written, -1);
|
||||
if (s_dac_cb.chan_st == CHANNEL_STATUS_ENABLED) {
|
||||
dac_continuous_write(s_dac_cb.tx_chan, data, item_size, &bytes_written, -1);
|
||||
}
|
||||
vRingbufferReturnItem(s_dac_cb.ringbuf, (void *)data);
|
||||
}
|
||||
}
|
||||
@@ -80,7 +82,10 @@ static void audio_sink_srv_dac_task_handler(void *arg)
|
||||
|
||||
void audio_sink_srv_open(void)
|
||||
{
|
||||
memset(&s_dac_cb, 0, sizeof(audio_sink_srv_dac_cb_t));
|
||||
if (s_dac_cb.chan_st != CHANNEL_STATUS_IDLE) {
|
||||
ESP_LOGW(AUDIO_SNK_SRV_DAC_TAG, "Service already opened");
|
||||
return;
|
||||
}
|
||||
dac_continuous_config_t cont_cfg = {
|
||||
.chan_mask = DAC_CHANNEL_MASK_ALL,
|
||||
.desc_num = 8,
|
||||
@@ -91,7 +96,11 @@ void audio_sink_srv_open(void)
|
||||
.chan_mode = DAC_CHANNEL_MODE_ALTER,
|
||||
};
|
||||
/* Allocate continuous channels */
|
||||
ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg, &s_dac_cb.tx_chan));
|
||||
esp_err_t ret = dac_continuous_new_channels(&cont_cfg, &s_dac_cb.tx_chan);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(AUDIO_SNK_SRV_DAC_TAG, "Failed to create DAC channels: %s", esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
s_dac_cb.chan_st = CHANNEL_STATUS_OPENED;
|
||||
}
|
||||
|
||||
@@ -99,10 +108,6 @@ void audio_sink_srv_close(void)
|
||||
{
|
||||
audio_sink_srv_stop();
|
||||
|
||||
if (s_dac_cb.chan_st == CHANNEL_STATUS_OPENED) {
|
||||
ESP_ERROR_CHECK(dac_continuous_del_channels(s_dac_cb.tx_chan));
|
||||
s_dac_cb.chan_st = CHANNEL_STATUS_IDLE;
|
||||
}
|
||||
if (s_dac_cb.write_task_handle) {
|
||||
vTaskDelete(s_dac_cb.write_task_handle);
|
||||
s_dac_cb.write_task_handle = NULL;
|
||||
@@ -115,6 +120,10 @@ void audio_sink_srv_close(void)
|
||||
vSemaphoreDelete(s_dac_cb.write_semaphore);
|
||||
s_dac_cb.write_semaphore = NULL;
|
||||
}
|
||||
if (s_dac_cb.chan_st == CHANNEL_STATUS_OPENED) {
|
||||
ESP_ERROR_CHECK(dac_continuous_del_channels(s_dac_cb.tx_chan));
|
||||
s_dac_cb.chan_st = CHANNEL_STATUS_IDLE;
|
||||
}
|
||||
memset(&s_dac_cb, 0, sizeof(audio_sink_srv_dac_cb_t));
|
||||
}
|
||||
|
||||
@@ -125,19 +134,37 @@ void audio_sink_srv_start(void)
|
||||
return;
|
||||
}
|
||||
ESP_ERROR_CHECK(dac_continuous_enable(s_dac_cb.tx_chan));
|
||||
s_dac_cb.chan_st = CHANNEL_STATUS_ENABLED;
|
||||
|
||||
ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "ringbuffer data empty! mode changed: RINGBUFFER_MODE_PREFETCHING");
|
||||
s_dac_cb.ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING;
|
||||
if ((s_dac_cb.write_semaphore = xSemaphoreCreateBinary()) == NULL) {
|
||||
if ((s_dac_cb.write_semaphore == NULL) && ((s_dac_cb.write_semaphore = xSemaphoreCreateBinary()) == NULL)) {
|
||||
ESP_LOGE(AUDIO_SNK_SRV_DAC_TAG, "%s, Semaphore create failed", __func__);
|
||||
return;
|
||||
goto err_sem;
|
||||
}
|
||||
if ((s_dac_cb.ringbuf = xRingbufferCreate(RINGBUF_HIGHEST_WATER_LEVEL, RINGBUF_TYPE_BYTEBUF)) == NULL) {
|
||||
if ((s_dac_cb.ringbuf == NULL) &&
|
||||
((s_dac_cb.ringbuf = xRingbufferCreate(RINGBUF_HIGHEST_WATER_LEVEL, RINGBUF_TYPE_BYTEBUF)) == NULL)) {
|
||||
ESP_LOGE(AUDIO_SNK_SRV_DAC_TAG, "%s, ringbuffer create failed", __func__);
|
||||
return;
|
||||
goto err_rb;
|
||||
}
|
||||
xTaskCreate(audio_sink_srv_dac_task_handler, "BtDACTask", 4 * 1024, NULL, configMAX_PRIORITIES - 3, &s_dac_cb.write_task_handle);
|
||||
|
||||
if (s_dac_cb.write_task_handle == NULL) {
|
||||
if (xTaskCreate(audio_sink_srv_dac_task_handler, "BtDACTask", 4 * 1024, NULL,
|
||||
configMAX_PRIORITIES - 3, &s_dac_cb.write_task_handle) != pdPASS) {
|
||||
ESP_LOGE(AUDIO_SNK_SRV_DAC_TAG, "%s, Task create failed", __func__);
|
||||
goto err_task;
|
||||
}
|
||||
}
|
||||
s_dac_cb.chan_st = CHANNEL_STATUS_ENABLED;
|
||||
return;
|
||||
|
||||
err_task:
|
||||
vRingbufferDelete(s_dac_cb.ringbuf);
|
||||
s_dac_cb.ringbuf = NULL;
|
||||
err_rb:
|
||||
vSemaphoreDelete(s_dac_cb.write_semaphore);
|
||||
s_dac_cb.write_semaphore = NULL;
|
||||
err_sem:
|
||||
dac_continuous_disable(s_dac_cb.tx_chan);
|
||||
}
|
||||
|
||||
void audio_sink_srv_stop(void)
|
||||
@@ -151,6 +178,7 @@ void audio_sink_srv_stop(void)
|
||||
void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc)
|
||||
{
|
||||
ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "A2DP audio stream configuration, codec type: %d", mcc->type);
|
||||
audio_sink_srv_stop();
|
||||
/* for now only SBC stream is supported */
|
||||
if (mcc->type == ESP_A2D_MCT_SBC) {
|
||||
int sample_rate = 16000;
|
||||
@@ -166,7 +194,10 @@ void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc)
|
||||
if (mcc->cie.sbc_info.ch_mode & ESP_A2D_SBC_CIE_CH_MODE_MONO) {
|
||||
ch_count = 1;
|
||||
}
|
||||
dac_continuous_del_channels(s_dac_cb.tx_chan);
|
||||
if (s_dac_cb.tx_chan) {
|
||||
dac_continuous_del_channels(s_dac_cb.tx_chan);
|
||||
s_dac_cb.tx_chan = NULL;
|
||||
}
|
||||
dac_continuous_config_t cont_cfg = {
|
||||
.chan_mask = DAC_CHANNEL_MASK_ALL,
|
||||
.desc_num = 8,
|
||||
@@ -177,7 +208,7 @@ void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc)
|
||||
.chan_mode = (ch_count == 1) ? DAC_CHANNEL_MODE_SIMUL : DAC_CHANNEL_MODE_ALTER,
|
||||
};
|
||||
/* Allocate continuous channels */
|
||||
dac_continuous_new_channels(&cont_cfg, &s_dac_cb.tx_chan);
|
||||
ESP_ERROR_CHECK(dac_continuous_new_channels(&cont_cfg, &s_dac_cb.tx_chan));
|
||||
ESP_LOGI(AUDIO_SNK_SRV_DAC_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-%d-%d",
|
||||
mcc->cie.sbc_info.samp_freq,
|
||||
mcc->cie.sbc_info.ch_mode,
|
||||
@@ -195,6 +226,10 @@ size_t audio_sink_srv_data_output(const uint8_t *data, size_t size)
|
||||
size_t item_size = 0;
|
||||
BaseType_t done = pdFALSE;
|
||||
|
||||
if (s_dac_cb.ringbuf == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s_dac_cb.ringbuffer_mode == RINGBUFFER_MODE_DROPPING) {
|
||||
ESP_LOGW(AUDIO_SNK_SRV_DAC_TAG, "ringbuffer is full, drop this packet!");
|
||||
vRingbufferGetInfo(s_dac_cb.ringbuf, NULL, NULL, NULL, NULL, &item_size);
|
||||
|
||||
@@ -72,7 +72,9 @@ static void audio_sink_srv_i2s_task_handler(void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
i2s_channel_write(s_i2s_cb.tx_chan, data, item_size, &bytes_written, portMAX_DELAY);
|
||||
if (s_i2s_cb.chan_st == CHANNEL_STATUS_ENABLED) {
|
||||
i2s_channel_write(s_i2s_cb.tx_chan, data, item_size, &bytes_written, portMAX_DELAY);
|
||||
}
|
||||
vRingbufferReturnItem(s_i2s_cb.ringbuf, (void *)data);
|
||||
}
|
||||
}
|
||||
@@ -85,7 +87,10 @@ static void audio_sink_srv_i2s_task_handler(void *arg)
|
||||
|
||||
void audio_sink_srv_open(void)
|
||||
{
|
||||
memset(&s_i2s_cb, 0, sizeof(audio_sink_srv_i2s_cb_t));
|
||||
if (s_i2s_cb.chan_st != CHANNEL_STATUS_IDLE) {
|
||||
ESP_LOGW(AUDIO_SNK_SRV_I2S_TAG, "Service already open, skipping initialization");
|
||||
return;
|
||||
}
|
||||
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
|
||||
chan_cfg.auto_clear = true;
|
||||
i2s_std_config_t std_cfg = {
|
||||
@@ -114,10 +119,6 @@ void audio_sink_srv_close(void)
|
||||
{
|
||||
audio_sink_srv_stop();
|
||||
|
||||
if (s_i2s_cb.chan_st == CHANNEL_STATUS_OPENED) {
|
||||
ESP_ERROR_CHECK(i2s_del_channel(s_i2s_cb.tx_chan));
|
||||
s_i2s_cb.chan_st = CHANNEL_STATUS_IDLE;
|
||||
}
|
||||
if (s_i2s_cb.write_task_handle) {
|
||||
vTaskDelete(s_i2s_cb.write_task_handle);
|
||||
s_i2s_cb.write_task_handle = NULL;
|
||||
@@ -130,6 +131,10 @@ void audio_sink_srv_close(void)
|
||||
vSemaphoreDelete(s_i2s_cb.write_semaphore);
|
||||
s_i2s_cb.write_semaphore = NULL;
|
||||
}
|
||||
if (s_i2s_cb.chan_st == CHANNEL_STATUS_OPENED) {
|
||||
ESP_ERROR_CHECK(i2s_del_channel(s_i2s_cb.tx_chan));
|
||||
s_i2s_cb.chan_st = CHANNEL_STATUS_IDLE;
|
||||
}
|
||||
memset(&s_i2s_cb, 0, sizeof(audio_sink_srv_i2s_cb_t));
|
||||
}
|
||||
|
||||
@@ -140,19 +145,36 @@ void audio_sink_srv_start(void)
|
||||
return;
|
||||
}
|
||||
ESP_ERROR_CHECK(i2s_channel_enable(s_i2s_cb.tx_chan));
|
||||
s_i2s_cb.chan_st = CHANNEL_STATUS_ENABLED;
|
||||
|
||||
ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "ringbuffer data empty! mode changed: RINGBUFFER_MODE_PREFETCHING");
|
||||
s_i2s_cb.ringbuffer_mode = RINGBUFFER_MODE_PREFETCHING;
|
||||
if ((s_i2s_cb.write_semaphore = xSemaphoreCreateBinary()) == NULL) {
|
||||
if ((s_i2s_cb.write_semaphore == NULL) && (s_i2s_cb.write_semaphore = xSemaphoreCreateBinary()) == NULL) {
|
||||
ESP_LOGE(AUDIO_SNK_SRV_I2S_TAG, "%s, Semaphore create failed", __func__);
|
||||
return;
|
||||
goto err_sem;
|
||||
}
|
||||
if ((s_i2s_cb.ringbuf = xRingbufferCreate(RINGBUF_HIGHEST_WATER_LEVEL, RINGBUF_TYPE_BYTEBUF)) == NULL) {
|
||||
if ((s_i2s_cb.ringbuf == NULL) &&
|
||||
(s_i2s_cb.ringbuf = xRingbufferCreate(RINGBUF_HIGHEST_WATER_LEVEL, RINGBUF_TYPE_BYTEBUF)) == NULL) {
|
||||
ESP_LOGE(AUDIO_SNK_SRV_I2S_TAG, "%s, ringbuffer create failed", __func__);
|
||||
return;
|
||||
goto err_rb;
|
||||
}
|
||||
xTaskCreate(audio_sink_srv_i2s_task_handler, "BtI2STask", 4 * 1024, NULL, configMAX_PRIORITIES - 3, &s_i2s_cb.write_task_handle);
|
||||
if (s_i2s_cb.write_task_handle == NULL) {
|
||||
if (xTaskCreate(audio_sink_srv_i2s_task_handler, "BtI2STask", 4 * 1024, NULL,
|
||||
configMAX_PRIORITIES - 3, &s_i2s_cb.write_task_handle) != pdPASS) {
|
||||
ESP_LOGE(AUDIO_SNK_SRV_I2S_TAG, "%s, Task create failed", __func__);
|
||||
goto err_task;
|
||||
}
|
||||
}
|
||||
s_i2s_cb.chan_st = CHANNEL_STATUS_ENABLED;
|
||||
return;
|
||||
|
||||
err_task:
|
||||
vRingbufferDelete(s_i2s_cb.ringbuf);
|
||||
s_i2s_cb.ringbuf = NULL;
|
||||
err_rb:
|
||||
vSemaphoreDelete(s_i2s_cb.write_semaphore);
|
||||
s_i2s_cb.write_semaphore = NULL;
|
||||
err_sem:
|
||||
i2s_channel_disable(s_i2s_cb.tx_chan);
|
||||
}
|
||||
|
||||
void audio_sink_srv_stop(void)
|
||||
@@ -166,6 +188,7 @@ void audio_sink_srv_stop(void)
|
||||
void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc)
|
||||
{
|
||||
ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "A2DP audio stream configuration, codec type: %d", mcc->type);
|
||||
audio_sink_srv_stop();
|
||||
/* for now only SBC stream is supported */
|
||||
if (mcc->type == ESP_A2D_MCT_SBC) {
|
||||
int sample_rate = 16000;
|
||||
@@ -183,8 +206,8 @@ void audio_sink_srv_codec_info_update(esp_a2d_mcc_t *mcc)
|
||||
}
|
||||
i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate);
|
||||
i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, ch_count);
|
||||
i2s_channel_reconfig_std_clock(s_i2s_cb.tx_chan, &clk_cfg);
|
||||
i2s_channel_reconfig_std_slot(s_i2s_cb.tx_chan, &slot_cfg);
|
||||
ESP_ERROR_CHECK(i2s_channel_reconfig_std_clock(s_i2s_cb.tx_chan, &clk_cfg));
|
||||
ESP_ERROR_CHECK(i2s_channel_reconfig_std_slot(s_i2s_cb.tx_chan, &slot_cfg));
|
||||
ESP_LOGI(AUDIO_SNK_SRV_I2S_TAG, "Configure audio player: 0x%x-0x%x-0x%x-0x%x-0x%x-%d-%d",
|
||||
mcc->cie.sbc_info.samp_freq,
|
||||
mcc->cie.sbc_info.ch_mode,
|
||||
@@ -202,6 +225,10 @@ size_t audio_sink_srv_data_output(const uint8_t *data, size_t size)
|
||||
size_t item_size = 0;
|
||||
BaseType_t done = pdFALSE;
|
||||
|
||||
if (s_i2s_cb.ringbuf == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s_i2s_cb.ringbuffer_mode == RINGBUFFER_MODE_DROPPING) {
|
||||
ESP_LOGW(AUDIO_SNK_SRV_I2S_TAG, "ringbuffer is full, drop this packet!");
|
||||
vRingbufferGetInfo(s_i2s_cb.ringbuf, NULL, NULL, NULL, NULL, &item_size);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -33,11 +33,17 @@ static avrc_abs_vol_srv_cb_t s_avrc_abs_vol_srv_cb;
|
||||
|
||||
void avrc_abs_vol_srv_open(void)
|
||||
{
|
||||
memset(&s_avrc_abs_vol_srv_cb, 0, sizeof(avrc_abs_vol_srv_cb_t));
|
||||
if (s_avrc_abs_vol_srv_cb.volume_lock) {
|
||||
_lock_close(&s_avrc_abs_vol_srv_cb.volume_lock);
|
||||
}
|
||||
_lock_init(&s_avrc_abs_vol_srv_cb.volume_lock);
|
||||
s_avrc_abs_vol_srv_cb.volume = 0;
|
||||
s_avrc_abs_vol_srv_cb.volume_notify = false;
|
||||
}
|
||||
|
||||
void avrc_abs_vol_srv_close(void)
|
||||
{
|
||||
_lock_close(&s_avrc_abs_vol_srv_cb.volume_lock);
|
||||
memset(&s_avrc_abs_vol_srv_cb, 0, sizeof(avrc_abs_vol_srv_cb_t));
|
||||
}
|
||||
|
||||
|
||||
@@ -72,11 +72,11 @@ void bt_avrc_avc_tg_evt_hdl(uint16_t event, void *param)
|
||||
avrc_abs_vol_srv_open();
|
||||
xTaskCreate(volume_change_simulation, "vcsTask", 4 * 1024, NULL, 5, &s_vcs_task_hdl);
|
||||
} else {
|
||||
avrc_abs_vol_srv_close();
|
||||
if (s_vcs_task_hdl) {
|
||||
vTaskDelete(s_vcs_task_hdl);
|
||||
s_vcs_task_hdl = NULL;
|
||||
}
|
||||
avrc_abs_vol_srv_close();
|
||||
ESP_LOGI(BT_RC_TG_TAG, "Stop volume change simulation");
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -54,7 +54,11 @@ void bt_avrc_common_ct_evt_def_hdl(uint16_t event, void *param)
|
||||
}
|
||||
/* when metadata response, this event comes */
|
||||
case ESP_AVRC_CT_METADATA_RSP_EVT: {
|
||||
ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text);
|
||||
if (rc->meta_rsp.attr_text) {
|
||||
ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text);
|
||||
} else {
|
||||
ESP_LOGE(BT_RC_CT_TAG, "AVRC metadata rsp: attr_text NULL");
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* when notified, this event comes */
|
||||
@@ -161,8 +165,20 @@ void bt_avrc_common_copy_metadata(void *p_dest, void *p_src, int len)
|
||||
p_dest_rc->meta_rsp.attr_length = p_src_rc->meta_rsp.attr_length;
|
||||
|
||||
p_dest_rc->meta_rsp.attr_text = (uint8_t *) malloc(p_dest_rc->meta_rsp.attr_length + 1);
|
||||
memcpy(p_dest_rc->meta_rsp.attr_text, p_src_rc->meta_rsp.attr_text, p_dest_rc->meta_rsp.attr_length);
|
||||
p_dest_rc->meta_rsp.attr_text[p_dest_rc->meta_rsp.attr_length] = 0;
|
||||
if (p_dest_rc->meta_rsp.attr_text) {
|
||||
memcpy(p_dest_rc->meta_rsp.attr_text, p_src_rc->meta_rsp.attr_text, p_dest_rc->meta_rsp.attr_length);
|
||||
p_dest_rc->meta_rsp.attr_text[p_dest_rc->meta_rsp.attr_length] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void bt_avrc_common_free_metadata(void *p_param)
|
||||
{
|
||||
esp_avrc_ct_cb_param_t *rc = (esp_avrc_ct_cb_param_t *)p_param;
|
||||
|
||||
if (rc && rc->meta_rsp.attr_text) {
|
||||
free(rc->meta_rsp.attr_text);
|
||||
rc->meta_rsp.attr_text = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void bt_avrc_common_ct_get_peer_rn_cap(void)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -44,6 +44,13 @@ uint8_t bt_avrc_common_alloc_tl(void);
|
||||
*/
|
||||
void bt_avrc_common_copy_metadata(void *p_dest, void *p_src, int len);
|
||||
|
||||
/**
|
||||
* @brief AVRCP deep free function for copied metadata
|
||||
*
|
||||
* @param [in] p_param pointer to copied callback parameter
|
||||
*/
|
||||
void bt_avrc_common_free_metadata(void *p_param);
|
||||
|
||||
/**
|
||||
* @brief AVRCP controller get notification capabilities command
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -181,6 +181,11 @@ static void avrc_cover_art_srv_init_display(void)
|
||||
|
||||
static void avrc_cover_art_srv_deinit_display(void)
|
||||
{
|
||||
/* Check if initialized by looking at handles */
|
||||
if (s_avrc_cover_art_srv_cb.panel_handle == NULL && s_avrc_cover_art_srv_cb.io_handle == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Turn off backlight first */
|
||||
ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL));
|
||||
|
||||
@@ -320,6 +325,11 @@ void avrc_cover_art_srv_ca_req(void)
|
||||
|
||||
void avrc_cover_art_srv_save_image_data(uint8_t *p_data, uint16_t data_len)
|
||||
{
|
||||
if (s_avrc_cover_art_srv_cb.image_size > UINT32_MAX - data_len) {
|
||||
ESP_LOGE(RC_CA_SRV_TAG, "Image size overflow");
|
||||
avrc_cover_art_srv_free_image_data();
|
||||
return;
|
||||
}
|
||||
s_avrc_cover_art_srv_cb.image_size += data_len;
|
||||
|
||||
uint8_t *p_buf = (uint8_t *)realloc(s_avrc_cover_art_srv_cb.image_data, s_avrc_cover_art_srv_cb.image_size * sizeof(uint8_t));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -34,9 +34,13 @@ void bt_avrc_ca_ct_evt_hdl(uint16_t event, void *param)
|
||||
}
|
||||
/* when metadata response, this event comes */
|
||||
case ESP_AVRC_CT_METADATA_RSP_EVT: {
|
||||
ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text);
|
||||
if (rc->meta_rsp.attr_id == ESP_AVRC_MD_ATTR_COVER_ART) {
|
||||
avrc_cover_art_srv_ct_metadata_update(rc->meta_rsp.attr_text, rc->meta_rsp.attr_length);
|
||||
if (rc->meta_rsp.attr_text) {
|
||||
ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text);
|
||||
if (rc->meta_rsp.attr_id == ESP_AVRC_MD_ATTR_COVER_ART) {
|
||||
avrc_cover_art_srv_ct_metadata_update(rc->meta_rsp.attr_text, rc->meta_rsp.attr_length);
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(BT_RC_CT_TAG, "AVRC metadata rsp: attr_text NULL");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ static avrc_metadata_srv_cb_t s_avrc_metadata_srv_cb;
|
||||
|
||||
static void avrc_metadata_srv_copy_metadata(avrc_metadata_srv_param_t *p_dest, avrc_metadata_srv_param_t *p_src)
|
||||
{
|
||||
if (p_src->attr_length < 0) {
|
||||
ESP_LOGE(RC_MD_SRV_TAG, "Invalid attribute length: %d", p_src->attr_length);
|
||||
return;
|
||||
}
|
||||
p_dest->attr_id = p_src->attr_id;
|
||||
p_dest->attr_length = p_src->attr_length;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -46,10 +46,14 @@ void bt_avrc_md_ct_evt_hdl(uint16_t event, void *param)
|
||||
}
|
||||
/* when metadata response, this event comes */
|
||||
case ESP_AVRC_CT_METADATA_RSP_EVT: {
|
||||
ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text);
|
||||
/* save metadata to avrcp metadata service and then if there is a need to handle metadata,
|
||||
functions can be added in the avrcp metadata service for processing */
|
||||
avrc_metadata_srv_md_save((avrc_metadata_srv_param_t *)rc);
|
||||
if (rc->meta_rsp.attr_text) {
|
||||
ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text);
|
||||
/* save metadata to avrcp metadata service and then if there is a need to handle metadata,
|
||||
functions can be added in the avrcp metadata service for processing */
|
||||
avrc_metadata_srv_md_save((avrc_metadata_srv_param_t *)rc);
|
||||
} else {
|
||||
ESP_LOGE(BT_RC_CT_TAG, "AVRC metadata rsp: attr_text NULL");
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* when notified, this event comes */
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
idf_component_register(SRCS "bt_app_core_utils.c"
|
||||
PRIV_REQUIRES bt
|
||||
INCLUDE_DIRS ".")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -44,7 +44,7 @@ static TaskHandle_t s_bt_app_task_handle = NULL; /* handle of application task
|
||||
|
||||
static bool bt_app_send_msg(bt_app_msg_t *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
if (msg == NULL || s_bt_app_task_queue == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -82,6 +82,9 @@ static void bt_app_task_handler(void *arg)
|
||||
} /* switch (msg.sig) */
|
||||
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
@@ -92,7 +95,8 @@ static void bt_app_task_handler(void *arg)
|
||||
* EXTERNAL FUNCTION DEFINITIONS
|
||||
*******************************/
|
||||
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback)
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback)
|
||||
{
|
||||
ESP_LOGD(BT_APP_CORE_TAG, "%s event: 0x%x, param len: %d", __func__, event, param_len);
|
||||
|
||||
@@ -102,6 +106,7 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
msg.sig = BT_APP_SIG_WORK_DISPATCH;
|
||||
msg.event = event;
|
||||
msg.cb = p_cback;
|
||||
msg.free_cb = p_free_cback;
|
||||
|
||||
if (param_len == 0) {
|
||||
return bt_app_send_msg(&msg);
|
||||
@@ -112,7 +117,14 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
if (p_copy_cback) {
|
||||
p_copy_cback(msg.param, p_params, param_len);
|
||||
}
|
||||
return bt_app_send_msg(&msg);
|
||||
if (!bt_app_send_msg(&msg)) {
|
||||
if (p_free_cback) {
|
||||
p_free_cback(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +144,15 @@ void bt_app_task_shut_down(void)
|
||||
s_bt_app_task_handle = NULL;
|
||||
}
|
||||
if (s_bt_app_task_queue) {
|
||||
bt_app_msg_t msg;
|
||||
while (xQueueReceive(s_bt_app_task_queue, &msg, 0) == pdTRUE) {
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
vQueueDelete(s_bt_app_task_queue);
|
||||
s_bt_app_task_queue = NULL;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -22,11 +22,19 @@
|
||||
*/
|
||||
typedef void (* bt_app_cb_t)(uint16_t event, void *param);
|
||||
|
||||
/**
|
||||
* @brief parameter deep-free function
|
||||
*
|
||||
* @param [in] p_param pointer to parameter data
|
||||
*/
|
||||
typedef void (* bt_app_free_cb_t)(void *p_param);
|
||||
|
||||
/* message to be sent */
|
||||
typedef struct {
|
||||
uint16_t sig; /*!< signal to bt_app_task */
|
||||
uint16_t event; /*!< message event id */
|
||||
bt_app_cb_t cb; /*!< context switch callback */
|
||||
bt_app_free_cb_t free_cb;/*!< parameter deep-free function */
|
||||
void *param; /*!< parameter area needs to be last */
|
||||
} bt_app_msg_t;
|
||||
|
||||
@@ -47,10 +55,12 @@ typedef void (* bt_app_copy_cb_t)(void *p_dest, void *p_src, int len);
|
||||
* @param [in] p_params callback parameters
|
||||
* @param [in] param_len parameter length in byte
|
||||
* @param [in] p_copy_cback parameter deep-copy function
|
||||
* @param [in] p_free_cback parameter deep-free function
|
||||
*
|
||||
* @return true if work dispatch successfully, false otherwise
|
||||
*/
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback);
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback);
|
||||
|
||||
/**
|
||||
* @brief start up the application task
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -21,7 +21,8 @@ static void bt_app_work_dispatched(bt_app_msg_t *msg);
|
||||
static QueueHandle_t bt_app_task_queue = NULL;
|
||||
static TaskHandle_t bt_app_task_handle = NULL;
|
||||
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback)
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback)
|
||||
{
|
||||
ESP_LOGD(BT_APP_CORE_TAG, "%s event 0x%x, param len %d", __func__, event, param_len);
|
||||
|
||||
@@ -31,6 +32,7 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
msg.sig = BT_APP_SIG_WORK_DISPATCH;
|
||||
msg.event = event;
|
||||
msg.cb = p_cback;
|
||||
msg.free_cb = p_free_cback;
|
||||
|
||||
if (param_len == 0) {
|
||||
return bt_app_send_msg(&msg);
|
||||
@@ -41,7 +43,14 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
if (p_copy_cback) {
|
||||
p_copy_cback(&msg, msg.param, p_params);
|
||||
}
|
||||
return bt_app_send_msg(&msg);
|
||||
if (!bt_app_send_msg(&msg)) {
|
||||
if (p_free_cback) {
|
||||
p_free_cback(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -49,7 +58,7 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
|
||||
static bool bt_app_send_msg(bt_app_msg_t *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
if (msg == NULL || bt_app_task_queue == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -83,6 +92,9 @@ static void bt_app_task_handler(void *arg)
|
||||
} // switch (msg.sig)
|
||||
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
@@ -103,6 +115,15 @@ void bt_app_task_shut_down(void)
|
||||
bt_app_task_handle = NULL;
|
||||
}
|
||||
if (bt_app_task_queue) {
|
||||
bt_app_msg_t msg;
|
||||
while (xQueueReceive(bt_app_task_queue, &msg, 0) == pdTRUE) {
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
vQueueDelete(bt_app_task_queue);
|
||||
bt_app_task_queue = NULL;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -20,11 +20,17 @@
|
||||
*/
|
||||
typedef void (* bt_app_cb_t) (uint16_t event, void *param);
|
||||
|
||||
/**
|
||||
* @brief parameter deep-free function
|
||||
*/
|
||||
typedef void (* bt_app_free_cb_t) (void *p_param);
|
||||
|
||||
/* message to be sent */
|
||||
typedef struct {
|
||||
uint16_t sig; /*!< signal to bt_app_task */
|
||||
uint16_t event; /*!< message event id */
|
||||
bt_app_cb_t cb; /*!< context switch callback */
|
||||
bt_app_free_cb_t free_cb; /*!< parameter deep-free function */
|
||||
void *param; /*!< parameter area needs to be last */
|
||||
} bt_app_msg_t;
|
||||
|
||||
@@ -36,7 +42,8 @@ typedef void (* bt_app_copy_cb_t) (bt_app_msg_t *msg, void *p_dest, void *p_src)
|
||||
/**
|
||||
* @brief work dispatcher for the application task
|
||||
*/
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback);
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback);
|
||||
|
||||
void bt_app_task_start_up(void);
|
||||
|
||||
|
||||
@@ -279,6 +279,7 @@ void bt_app_send_data_shut_down(void)
|
||||
if(s_periodic_timer) {
|
||||
ESP_ERROR_CHECK(esp_timer_stop(s_periodic_timer));
|
||||
ESP_ERROR_CHECK(esp_timer_delete(s_periodic_timer));
|
||||
s_periodic_timer = NULL;
|
||||
}
|
||||
if (s_send_data_Semaphore) {
|
||||
vSemaphoreDelete(s_send_data_Semaphore);
|
||||
@@ -286,6 +287,7 @@ void bt_app_send_data_shut_down(void)
|
||||
}
|
||||
if (s_m_rb) {
|
||||
vRingbufferDelete(s_m_rb);
|
||||
s_m_rb = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ void app_main(void)
|
||||
bt_app_task_start_up();
|
||||
|
||||
/* Bluetooth device name, connection mode and profile set up */
|
||||
bt_app_work_dispatch(bt_hf_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
|
||||
bt_app_work_dispatch(bt_hf_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL, NULL);
|
||||
|
||||
#if CONFIG_BT_HFP_AUDIO_DATA_PATH_PCM
|
||||
/* configure the PCM interface and PINs used */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -21,7 +21,8 @@ static void bt_app_work_dispatched(bt_app_msg_t *msg);
|
||||
static QueueHandle_t bt_app_task_queue = NULL;
|
||||
static TaskHandle_t bt_app_task_handle = NULL;
|
||||
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback)
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback)
|
||||
{
|
||||
ESP_LOGD(BT_APP_CORE_TAG, "%s event 0x%x, param len %d", __func__, event, param_len);
|
||||
|
||||
@@ -31,6 +32,7 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
msg.sig = BT_APP_SIG_WORK_DISPATCH;
|
||||
msg.event = event;
|
||||
msg.cb = p_cback;
|
||||
msg.free_cb = p_free_cback;
|
||||
|
||||
if (param_len == 0) {
|
||||
return bt_app_send_msg(&msg);
|
||||
@@ -41,7 +43,14 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
if (p_copy_cback) {
|
||||
p_copy_cback(&msg, msg.param, p_params);
|
||||
}
|
||||
return bt_app_send_msg(&msg);
|
||||
if (!bt_app_send_msg(&msg)) {
|
||||
if (p_free_cback) {
|
||||
p_free_cback(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +59,7 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
||||
|
||||
static bool bt_app_send_msg(bt_app_msg_t *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
if (msg == NULL || bt_app_task_queue == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -87,6 +96,9 @@ static void bt_app_task_handler(void *arg)
|
||||
} // switch (msg.sig)
|
||||
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
@@ -107,6 +119,15 @@ void bt_app_task_shut_down(void)
|
||||
bt_app_task_handle = NULL;
|
||||
}
|
||||
if (bt_app_task_queue) {
|
||||
bt_app_msg_t msg;
|
||||
while (xQueueReceive(bt_app_task_queue, &msg, 0) == pdTRUE) {
|
||||
if (msg.param) {
|
||||
if (msg.free_cb) {
|
||||
msg.free_cb(msg.param);
|
||||
}
|
||||
free(msg.param);
|
||||
}
|
||||
}
|
||||
vQueueDelete(bt_app_task_queue);
|
||||
bt_app_task_queue = NULL;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -20,11 +20,17 @@
|
||||
*/
|
||||
typedef void (* bt_app_cb_t) (uint16_t event, void *param);
|
||||
|
||||
/**
|
||||
* @brief parameter deep-free function
|
||||
*/
|
||||
typedef void (* bt_app_free_cb_t) (void *p_param);
|
||||
|
||||
/* message to be sent */
|
||||
typedef struct {
|
||||
uint16_t sig; /*!< signal to bt_app_task */
|
||||
uint16_t event; /*!< message event id */
|
||||
bt_app_cb_t cb; /*!< context switch callback */
|
||||
bt_app_free_cb_t free_cb; /*!< parameter deep-free function */
|
||||
void *param; /*!< parameter area needs to be the last */
|
||||
} bt_app_msg_t;
|
||||
|
||||
@@ -36,7 +42,8 @@ typedef void (* bt_app_copy_cb_t) (bt_app_msg_t *msg, void *p_dest, void *p_src)
|
||||
/**
|
||||
* @brief work dispatcher for the application task
|
||||
*/
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback);
|
||||
bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len,
|
||||
bt_app_copy_cb_t p_copy_cback, bt_app_free_cb_t p_free_cback);
|
||||
|
||||
void bt_app_task_start_up(void);
|
||||
|
||||
|
||||
@@ -160,9 +160,9 @@ const char *c_at_response_code_str[] = {
|
||||
|
||||
// esp_hf_subscriber_service_type_t
|
||||
const char *c_subscriber_service_type_str[] = {
|
||||
"unknown",
|
||||
"voice",
|
||||
"fax",
|
||||
[ESP_HF_SUBSCRIBER_SERVICE_TYPE_UNKNOWN] = "unknown",
|
||||
[ESP_HF_SUBSCRIBER_SERVICE_TYPE_VOICE] = "voice",
|
||||
[ESP_HF_SUBSCRIBER_SERVICE_TYPE_FAX] = "fax",
|
||||
};
|
||||
|
||||
// esp_hf_client_in_band_ring_state_t
|
||||
@@ -242,6 +242,7 @@ static void bt_app_hf_client_audio_close(void)
|
||||
}
|
||||
|
||||
vRingbufferDelete(m_rb);
|
||||
m_rb = NULL;
|
||||
}
|
||||
|
||||
static uint32_t bt_app_hf_client_outgoing_cb(uint8_t *p_buf, uint32_t sz)
|
||||
@@ -329,11 +330,14 @@ void bt_app_hf_client_cb(esp_hf_client_cb_event_t event, esp_hf_client_cb_param_
|
||||
} else if (param->audio_stat.state == ESP_HF_CLIENT_AUDIO_STATE_DISCONNECTED) {
|
||||
s_sync_conn_hdl = 0;
|
||||
s_msbc_air_mode = false;
|
||||
esp_hf_audio_buff_t *buff_to_free = NULL;
|
||||
while (xQueueReceive(s_audio_buff_queue, &buff_to_free, 0)) {
|
||||
esp_hf_client_audio_buff_free(buff_to_free);
|
||||
if (s_audio_buff_queue) {
|
||||
esp_hf_audio_buff_t *buff_to_free = NULL;
|
||||
while (xQueueReceive(s_audio_buff_queue, &buff_to_free, 0)) {
|
||||
esp_hf_client_audio_buff_free(buff_to_free);
|
||||
}
|
||||
vQueueDelete(s_audio_buff_queue);
|
||||
s_audio_buff_queue = NULL;
|
||||
}
|
||||
vQueueDelete(s_audio_buff_queue);
|
||||
s_audio_buff_cnt = 0;
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -207,7 +207,7 @@ void app_main(void)
|
||||
bt_app_task_start_up();
|
||||
|
||||
/* Bluetooth device name, connection mode and profile set up */
|
||||
bt_app_work_dispatch(bt_hf_client_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
|
||||
bt_app_work_dispatch(bt_hf_client_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL, NULL);
|
||||
|
||||
#if CONFIG_BT_HFP_AUDIO_DATA_PATH_PCM
|
||||
/* configure the PCM interface and PINs used */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -92,14 +92,14 @@ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
|
||||
case ESP_A2D_CONNECTION_STATE_EVT:
|
||||
case ESP_A2D_AUDIO_STATE_EVT:
|
||||
case ESP_A2D_AUDIO_CFG_EVT: {
|
||||
bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_int_codec_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_A2D_PROF_STATE_EVT:
|
||||
case ESP_A2D_SNK_PSC_CFG_EVT:
|
||||
case ESP_A2D_SNK_SET_DELAY_VALUE_EVT:
|
||||
case ESP_A2D_SNK_GET_DELAY_VALUE_EVT: {
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_a2d_evt_def_hdl, event, param, sizeof(esp_a2d_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -117,7 +117,8 @@ void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_AVRC_CT_METADATA_RSP_EVT: {
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), bt_avrc_common_copy_metadata);
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t),
|
||||
bt_avrc_common_copy_metadata, bt_avrc_common_free_metadata);
|
||||
break;
|
||||
}
|
||||
case ESP_AVRC_CT_CONNECTION_STATE_EVT:
|
||||
@@ -126,7 +127,7 @@ void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param
|
||||
case ESP_AVRC_CT_REMOTE_FEATURES_EVT:
|
||||
case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT:
|
||||
case ESP_AVRC_CT_PROF_STATE_EVT:
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_app_avrc_ct_evt_hdl, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(BT_RC_CT_TAG, "Invalid AVRC event: %d", event);
|
||||
@@ -141,13 +142,13 @@ void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param
|
||||
case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT:
|
||||
case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT:
|
||||
case ESP_AVRC_TG_PROF_STATE_EVT: {
|
||||
bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_avrc_common_tg_evt_def_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case ESP_AVRC_TG_CONNECTION_STATE_EVT:
|
||||
case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT:
|
||||
case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: {
|
||||
bt_app_work_dispatch(bt_avrc_avc_tg_evt_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL);
|
||||
bt_app_work_dispatch(bt_avrc_avc_tg_evt_hdl, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -732,7 +732,7 @@ void app_main(void)
|
||||
|
||||
bt_app_task_start_up();
|
||||
/* bluetooth device name, connection mode and profile set up */
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
|
||||
bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL, NULL);
|
||||
|
||||
/* gatt server init */
|
||||
ble_gatts_init();
|
||||
|
||||
Reference in New Issue
Block a user