forked from espressif/esp-idf
Merge branch 'bugfix/a2dp_media_ctrl' into 'master'
Bugfix/a2dp media ctrl Closes BTQABR2023-42 See merge request espressif/esp-idf!25300
This commit is contained in:
@@ -208,6 +208,11 @@ esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl)
|
|||||||
return ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctrl == ESP_A2D_MEDIA_CTRL_STOP) {
|
||||||
|
LOG_WARN("ESP_A2D_MEDIA_CTRL_STOP is deprecated, using ESP_A2D_MEDIA_CTRL_SUSPEND instead.\n");
|
||||||
|
ctrl = ESP_A2D_MEDIA_CTRL_SUSPEND;
|
||||||
|
}
|
||||||
|
|
||||||
bt_status_t stat;
|
bt_status_t stat;
|
||||||
btc_av_args_t arg;
|
btc_av_args_t arg;
|
||||||
btc_msg_t msg;
|
btc_msg_t msg;
|
||||||
|
@@ -69,9 +69,10 @@ typedef enum {
|
|||||||
* @brief Bluetooth A2DP datapath states
|
* @brief Bluetooth A2DP datapath states
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND = 0, /*!< audio stream datapath suspended by remote device */
|
ESP_A2D_AUDIO_STATE_SUSPEND = 0, /*!< audio stream datapath suspended by remote device */
|
||||||
ESP_A2D_AUDIO_STATE_STOPPED, /*!< audio stream datapath stopped */
|
|
||||||
ESP_A2D_AUDIO_STATE_STARTED, /*!< audio stream datapath started */
|
ESP_A2D_AUDIO_STATE_STARTED, /*!< audio stream datapath started */
|
||||||
|
ESP_A2D_AUDIO_STATE_STOPPED = ESP_A2D_AUDIO_STATE_SUSPEND, /*!< @note Deprecated */
|
||||||
|
ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND = ESP_A2D_AUDIO_STATE_SUSPEND, /*!< @note Deprecated */
|
||||||
} esp_a2d_audio_state_t;
|
} esp_a2d_audio_state_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,8 +91,8 @@ typedef enum {
|
|||||||
ESP_A2D_MEDIA_CTRL_NONE = 0, /*!< Not for application use, use inside stack only. */
|
ESP_A2D_MEDIA_CTRL_NONE = 0, /*!< Not for application use, use inside stack only. */
|
||||||
ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY, /*!< check whether AVDTP is connected, only used in A2DP source */
|
ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY, /*!< check whether AVDTP is connected, only used in A2DP source */
|
||||||
ESP_A2D_MEDIA_CTRL_START, /*!< command to set up media transmission channel */
|
ESP_A2D_MEDIA_CTRL_START, /*!< command to set up media transmission channel */
|
||||||
ESP_A2D_MEDIA_CTRL_STOP, /*!< command to stop media transmission */
|
|
||||||
ESP_A2D_MEDIA_CTRL_SUSPEND, /*!< command to suspend media transmission */
|
ESP_A2D_MEDIA_CTRL_SUSPEND, /*!< command to suspend media transmission */
|
||||||
|
ESP_A2D_MEDIA_CTRL_STOP, /*!< @note Deprecated, Please use ESP_A2D_MEDIA_CTRL_SUSPEND */
|
||||||
} esp_a2d_media_ctrl_t;
|
} esp_a2d_media_ctrl_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -2045,7 +2045,7 @@ void bta_av_str_stopped (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
|
|||||||
BT_HDR *p_buf;
|
BT_HDR *p_buf;
|
||||||
UINT8 policy = HCI_ENABLE_SNIFF_MODE;
|
UINT8 policy = HCI_ENABLE_SNIFF_MODE;
|
||||||
|
|
||||||
APPL_TRACE_ERROR("bta_av_str_stopped:audio_open_cnt=%d, p_data %p",
|
APPL_TRACE_DEBUG("bta_av_str_stopped:audio_open_cnt=%d, p_data %p",
|
||||||
bta_av_cb.audio_open_cnt, p_data);
|
bta_av_cb.audio_open_cnt, p_data);
|
||||||
|
|
||||||
bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
|
bta_sys_idle(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr);
|
||||||
@@ -2096,7 +2096,7 @@ void bta_av_str_stopped (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
|
|||||||
} else {
|
} else {
|
||||||
suspend_rsp.status = BTA_AV_SUCCESS;
|
suspend_rsp.status = BTA_AV_SUCCESS;
|
||||||
suspend_rsp.initiator = TRUE;
|
suspend_rsp.initiator = TRUE;
|
||||||
APPL_TRACE_EVENT("bta_av_str_stopped status %d", suspend_rsp.status);
|
APPL_TRACE_WARNING("bta_av_str_stopped status %d", suspend_rsp.status);
|
||||||
|
|
||||||
/* send STOP_EVT event only if not in reconfiguring state */
|
/* send STOP_EVT event only if not in reconfiguring state */
|
||||||
if (p_scb->state != BTA_AV_RCFG_SST) {
|
if (p_scb->state != BTA_AV_RCFG_SST) {
|
||||||
|
@@ -137,26 +137,6 @@ void btc_a2dp_control_media_ctrl(esp_a2d_media_ctrl_t ctrl)
|
|||||||
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
|
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ESP_A2D_MEDIA_CTRL_STOP:
|
|
||||||
if (btc_av_is_connected() == FALSE) {
|
|
||||||
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#if BTC_AV_SRC_INCLUDED
|
|
||||||
if (btc_av_get_peer_sep() == AVDT_TSEP_SNK && !btc_a2dp_source_is_streaming() &&
|
|
||||||
btc_av_get_service_id() == BTA_A2DP_SOURCE_SERVICE_ID) {
|
|
||||||
/* we are already stopped, just ack back*/
|
|
||||||
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif /* BTC_AV_SRC_INCLUDED */
|
|
||||||
btc_dispatch_sm_event(BTC_AV_STOP_STREAM_REQ_EVT, NULL, 0);
|
|
||||||
#if (BTC_AV_SINK_INCLUDED == TRUE)
|
|
||||||
if (btc_av_get_peer_sep() == AVDT_TSEP_SRC && btc_av_get_service_id() == BTA_A2DP_SINK_SERVICE_ID) {
|
|
||||||
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case ESP_A2D_MEDIA_CTRL_SUSPEND:
|
case ESP_A2D_MEDIA_CTRL_SUSPEND:
|
||||||
/* local suspend */
|
/* local suspend */
|
||||||
if (btc_av_stream_started_ready()) {
|
if (btc_av_stream_started_ready()) {
|
||||||
|
@@ -219,7 +219,6 @@ UNUSED_ATTR static const char *dump_av_sm_event_name(btc_av_sm_event_t event)
|
|||||||
CASE_RETURN_STR(BTC_AV_CONNECT_REQ_EVT)
|
CASE_RETURN_STR(BTC_AV_CONNECT_REQ_EVT)
|
||||||
CASE_RETURN_STR(BTC_AV_DISCONNECT_REQ_EVT)
|
CASE_RETURN_STR(BTC_AV_DISCONNECT_REQ_EVT)
|
||||||
CASE_RETURN_STR(BTC_AV_START_STREAM_REQ_EVT)
|
CASE_RETURN_STR(BTC_AV_START_STREAM_REQ_EVT)
|
||||||
CASE_RETURN_STR(BTC_AV_STOP_STREAM_REQ_EVT)
|
|
||||||
CASE_RETURN_STR(BTC_AV_SUSPEND_STREAM_REQ_EVT)
|
CASE_RETURN_STR(BTC_AV_SUSPEND_STREAM_REQ_EVT)
|
||||||
CASE_RETURN_STR(BTC_AV_SINK_CONFIG_REQ_EVT)
|
CASE_RETURN_STR(BTC_AV_SINK_CONFIG_REQ_EVT)
|
||||||
default: return "UNKNOWN_EVENT";
|
default: return "UNKNOWN_EVENT";
|
||||||
@@ -600,7 +599,6 @@ static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BTA_AV_STOP_EVT:
|
case BTA_AV_STOP_EVT:
|
||||||
case BTC_AV_STOP_STREAM_REQ_EVT:
|
|
||||||
#if BTC_AV_SRC_INCLUDED
|
#if BTC_AV_SRC_INCLUDED
|
||||||
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
|
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
|
||||||
/* immediately flush any pending tx frames while suspend is pending */
|
/* immediately flush any pending tx frames while suspend is pending */
|
||||||
@@ -712,7 +710,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
|
|||||||
*/
|
*/
|
||||||
if (!(btc_av_cb.flags & BTC_AV_FLAG_PENDING_START)) {
|
if (!(btc_av_cb.flags & BTC_AV_FLAG_PENDING_START)) {
|
||||||
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
|
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
|
||||||
BTC_TRACE_DEBUG("%s: trigger suspend as remote initiated!!", __FUNCTION__);
|
BTC_TRACE_EVENT("%s: trigger suspend as remote initiated!!", __FUNCTION__);
|
||||||
btc_dispatch_sm_event(BTC_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
|
btc_dispatch_sm_event(BTC_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -882,8 +880,6 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data)
|
|||||||
#endif /* BTC_AV_SRC_INCLUDED */
|
#endif /* BTC_AV_SRC_INCLUDED */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* fixme -- use suspend = true always to work around issue with BTA AV */
|
|
||||||
case BTC_AV_STOP_STREAM_REQ_EVT:
|
|
||||||
case BTC_AV_SUSPEND_STREAM_REQ_EVT:
|
case BTC_AV_SUSPEND_STREAM_REQ_EVT:
|
||||||
|
|
||||||
/* set pending flag to ensure btc task is not trying to restart
|
/* set pending flag to ensure btc task is not trying to restart
|
||||||
@@ -953,10 +949,8 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data)
|
|||||||
btc_av_cb.flags |= BTC_AV_FLAG_REMOTE_SUSPEND;
|
btc_av_cb.flags |= BTC_AV_FLAG_REMOTE_SUSPEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
btc_report_audio_state(ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND, &(btc_av_cb.peer_bda));
|
|
||||||
} else {
|
|
||||||
btc_report_audio_state(ESP_A2D_AUDIO_STATE_STOPPED, &(btc_av_cb.peer_bda));
|
|
||||||
}
|
}
|
||||||
|
btc_report_audio_state(ESP_A2D_AUDIO_STATE_SUSPEND, &(btc_av_cb.peer_bda));
|
||||||
|
|
||||||
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENED);
|
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENED);
|
||||||
|
|
||||||
@@ -969,7 +963,7 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data)
|
|||||||
btc_av_cb.flags |= BTC_AV_FLAG_PENDING_STOP;
|
btc_av_cb.flags |= BTC_AV_FLAG_PENDING_STOP;
|
||||||
btc_a2dp_on_stopped(&p_av->suspend);
|
btc_a2dp_on_stopped(&p_av->suspend);
|
||||||
|
|
||||||
btc_report_audio_state(ESP_A2D_AUDIO_STATE_STOPPED, &(btc_av_cb.peer_bda));
|
btc_report_audio_state(ESP_A2D_AUDIO_STATE_SUSPEND, &(btc_av_cb.peer_bda));
|
||||||
|
|
||||||
/* if stop was successful, change state to open */
|
/* if stop was successful, change state to open */
|
||||||
if (p_av->suspend.status == BTA_AV_SUCCESS) {
|
if (p_av->suspend.status == BTA_AV_SUCCESS) {
|
||||||
@@ -1269,7 +1263,7 @@ BOOLEAN btc_av_stream_ready(void)
|
|||||||
(int)btc_av_cb.sm_handle, state, btc_av_cb.flags);
|
(int)btc_av_cb.sm_handle, state, btc_av_cb.flags);
|
||||||
|
|
||||||
/* check if we are remotely suspended or stop is pending */
|
/* check if we are remotely suspended or stop is pending */
|
||||||
if (btc_av_cb.flags & (BTC_AV_FLAG_REMOTE_SUSPEND | BTC_AV_FLAG_PENDING_STOP)) {
|
if (btc_av_cb.flags & BTC_AV_FLAG_PENDING_STOP) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1294,7 +1288,7 @@ BOOLEAN btc_av_stream_started_ready(void)
|
|||||||
(int)btc_av_cb.sm_handle, state, btc_av_cb.flags);
|
(int)btc_av_cb.sm_handle, state, btc_av_cb.flags);
|
||||||
|
|
||||||
/* disallow media task to start if we have pending actions */
|
/* disallow media task to start if we have pending actions */
|
||||||
if (btc_av_cb.flags & (BTC_AV_FLAG_LOCAL_SUSPEND_PENDING | BTC_AV_FLAG_REMOTE_SUSPEND
|
if (btc_av_cb.flags & (BTC_AV_FLAG_LOCAL_SUSPEND_PENDING
|
||||||
| BTC_AV_FLAG_PENDING_STOP)) {
|
| BTC_AV_FLAG_PENDING_STOP)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1623,7 +1617,6 @@ void btc_a2dp_call_handler(btc_msg_t *msg)
|
|||||||
break;
|
break;
|
||||||
// case BTC_AV_DISCONNECT_REQ_EVT:
|
// case BTC_AV_DISCONNECT_REQ_EVT:
|
||||||
case BTC_AV_START_STREAM_REQ_EVT:
|
case BTC_AV_START_STREAM_REQ_EVT:
|
||||||
case BTC_AV_STOP_STREAM_REQ_EVT:
|
|
||||||
case BTC_AV_SUSPEND_STREAM_REQ_EVT: {
|
case BTC_AV_SUSPEND_STREAM_REQ_EVT: {
|
||||||
btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, NULL);
|
btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, NULL);
|
||||||
break;
|
break;
|
||||||
|
@@ -50,7 +50,6 @@ typedef enum {
|
|||||||
BTC_AV_CONNECT_REQ_EVT = BTA_AV_MAX_EVT,
|
BTC_AV_CONNECT_REQ_EVT = BTA_AV_MAX_EVT,
|
||||||
BTC_AV_DISCONNECT_REQ_EVT,
|
BTC_AV_DISCONNECT_REQ_EVT,
|
||||||
BTC_AV_START_STREAM_REQ_EVT,
|
BTC_AV_START_STREAM_REQ_EVT,
|
||||||
BTC_AV_STOP_STREAM_REQ_EVT,
|
|
||||||
BTC_AV_SUSPEND_STREAM_REQ_EVT,
|
BTC_AV_SUSPEND_STREAM_REQ_EVT,
|
||||||
BTC_AV_SINK_CONFIG_REQ_EVT,
|
BTC_AV_SINK_CONFIG_REQ_EVT,
|
||||||
} btc_av_sm_event_t;
|
} btc_av_sm_event_t;
|
||||||
|
@@ -508,8 +508,8 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
|
|||||||
if (event == BT_APP_HEART_BEAT_EVT) {
|
if (event == BT_APP_HEART_BEAT_EVT) {
|
||||||
/* stop media after 10 heart beat intervals */
|
/* stop media after 10 heart beat intervals */
|
||||||
if (++s_intv_cnt >= 10) {
|
if (++s_intv_cnt >= 10) {
|
||||||
ESP_LOGI(BT_AV_TAG, "a2dp media stopping...");
|
ESP_LOGI(BT_AV_TAG, "a2dp media suspending...");
|
||||||
esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_STOP);
|
esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_SUSPEND);
|
||||||
s_media_state = APP_AV_MEDIA_STATE_STOPPING;
|
s_media_state = APP_AV_MEDIA_STATE_STOPPING;
|
||||||
s_intv_cnt = 0;
|
s_intv_cnt = 0;
|
||||||
}
|
}
|
||||||
@@ -519,15 +519,15 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
|
|||||||
case APP_AV_MEDIA_STATE_STOPPING: {
|
case APP_AV_MEDIA_STATE_STOPPING: {
|
||||||
if (event == ESP_A2D_MEDIA_CTRL_ACK_EVT) {
|
if (event == ESP_A2D_MEDIA_CTRL_ACK_EVT) {
|
||||||
a2d = (esp_a2d_cb_param_t *)(param);
|
a2d = (esp_a2d_cb_param_t *)(param);
|
||||||
if (a2d->media_ctrl_stat.cmd == ESP_A2D_MEDIA_CTRL_STOP &&
|
if (a2d->media_ctrl_stat.cmd == ESP_A2D_MEDIA_CTRL_SUSPEND &&
|
||||||
a2d->media_ctrl_stat.status == ESP_A2D_MEDIA_CTRL_ACK_SUCCESS) {
|
a2d->media_ctrl_stat.status == ESP_A2D_MEDIA_CTRL_ACK_SUCCESS) {
|
||||||
ESP_LOGI(BT_AV_TAG, "a2dp media stopped successfully, disconnecting...");
|
ESP_LOGI(BT_AV_TAG, "a2dp media suspend successfully, disconnecting...");
|
||||||
s_media_state = APP_AV_MEDIA_STATE_IDLE;
|
s_media_state = APP_AV_MEDIA_STATE_IDLE;
|
||||||
esp_a2d_source_disconnect(s_peer_bda);
|
esp_a2d_source_disconnect(s_peer_bda);
|
||||||
s_a2d_state = APP_AV_STATE_DISCONNECTING;
|
s_a2d_state = APP_AV_STATE_DISCONNECTING;
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(BT_AV_TAG, "a2dp media stopping...");
|
ESP_LOGI(BT_AV_TAG, "a2dp media suspending...");
|
||||||
esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_STOP);
|
esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_SUSPEND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user