mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
component/bt: modification to a2dp API to support reconnection
1. add API esp_a2d_sink_connect() to initiate connection to other devices; 2. modify lower layers to transfer the disconnection reason upwards
This commit is contained in:
parent
80cdfc9e0a
commit
118131109e
19
components/bt/bluedroid/api/include/esp_a2dp_api.h
Normal file → Executable file
19
components/bt/bluedroid/api/include/esp_a2dp_api.h
Normal file → Executable file
@ -83,6 +83,12 @@ typedef enum {
|
||||
ESP_A2D_CONNECTION_STATE_DISCONNECTING
|
||||
} esp_a2d_connection_state_t;
|
||||
|
||||
/// Bluetooth A2DP disconnection reason
|
||||
typedef enum {
|
||||
ESP_A2D_DISC_RSN_NORMAL = 0,
|
||||
ESP_A2D_DISC_RSN_ABNORMAL
|
||||
} esp_a2d_disc_rsn_t;
|
||||
|
||||
/// Bluetooth A2DP datapath states
|
||||
typedef enum {
|
||||
ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND = 0,
|
||||
@ -103,6 +109,7 @@ typedef union {
|
||||
struct a2d_conn_stat_param {
|
||||
esp_a2d_connection_state_t state; /*!< one of values from esp_a2d_connection_state_t */
|
||||
esp_bd_addr_t remote_bda;
|
||||
esp_a2d_disc_rsn_t disc_rsn; /* disconnection reason */
|
||||
} conn_stat;
|
||||
|
||||
/*< ESP_A2D_AUDIO_STATE_EVT */
|
||||
@ -183,6 +190,18 @@ esp_err_t esp_a2d_sink_init(void);
|
||||
void esp_a2d_sink_deinit(void);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to connect with the remote bluetooth device
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: connect request is sent to lower layer
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to disconnect with the remote bluetooth device
|
||||
|
@ -530,9 +530,14 @@ static void bta_av_proc_stream_evt(UINT8 handle, BD_ADDR bd_addr, UINT8 event, t
|
||||
}
|
||||
break;
|
||||
case AVDT_SUSPEND_IND_EVT:
|
||||
p_msg->msg.hdr.err_code = 0;
|
||||
p_msg->msg.hdr.err_code = 0;
|
||||
break;
|
||||
|
||||
/*
|
||||
case AVDT_CLOSE_CFM_EVT:
|
||||
case AVDT_CLOSE_IND_EVT:
|
||||
p_msg->disc_rsn = p_data->hdr.err_param;
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1080,6 +1085,7 @@ void bta_av_cleanup(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
|
||||
p_scb->cur_psc_mask = 0;
|
||||
p_scb->wait = 0;
|
||||
p_scb->num_disc_snks = 0;
|
||||
p_scb->disc_rsn = 0;
|
||||
bta_sys_stop_timer(&p_scb->timer);
|
||||
if (p_scb->deregistring)
|
||||
{
|
||||
@ -2571,6 +2577,7 @@ void bta_av_str_closed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
|
||||
p_scb->p_cos->close(p_scb->hndl, p_scb->codec_type, mtu);
|
||||
data.close.chnl = p_scb->chnl;
|
||||
data.close.hndl = p_scb->hndl;
|
||||
data.close.disc_rsn = p_scb->disc_rsn;
|
||||
event = BTA_AV_CLOSE_EVT;
|
||||
|
||||
bta_sys_conn_close(BTA_ID_AV, p_scb->app_id, p_scb->peer_addr);
|
||||
|
@ -1508,6 +1508,7 @@ void bta_av_sig_chg(tBTA_AV_DATA *p_data)
|
||||
if ((mask & p_lcb->conn_msk) && (p_cb->p_scb[xx]) &&
|
||||
(bdcmp(p_cb->p_scb[xx]->peer_addr, p_data->str_msg.bd_addr) == 0))
|
||||
{
|
||||
p_cb->p_scb[xx]->disc_rsn = p_data->str_msg.hdr.offset;
|
||||
bta_av_ssm_execute(p_cb->p_scb[xx], BTA_AV_AVDT_DISCONNECT_EVT, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ typedef struct {
|
||||
BD_ADDR bd_addr; /* bd address */
|
||||
UINT8 handle;
|
||||
UINT8 avdt_event;
|
||||
BOOLEAN initiator; /* TRUE, if local device initiates the SUSPEND */
|
||||
BOOLEAN initiator; /* TRUE, if local device initiates the SUSPEND */
|
||||
} tBTA_AV_STR_MSG;
|
||||
|
||||
/* data type for BTA_AV_AVRC_MSG_EVT */
|
||||
@ -516,6 +516,7 @@ typedef struct
|
||||
UINT8 wait; /* set 0x1, when getting Caps as ACP, set 0x2, when started */
|
||||
UINT8 q_tag; /* identify the associated q_info union member */
|
||||
BOOLEAN no_rtp_hdr; /* TRUE if add no RTP header*/
|
||||
UINT8 disc_rsn; /* disconenction reason */
|
||||
UINT16 uuid_int; /*intended UUID of Initiator to connect to */
|
||||
} tBTA_AV_SCB;
|
||||
|
||||
|
@ -331,6 +331,7 @@ typedef struct
|
||||
{
|
||||
tBTA_AV_CHNL chnl;
|
||||
tBTA_AV_HNDL hndl;
|
||||
UINT8 disc_rsn; /* disconnection reason */
|
||||
} tBTA_AV_CLOSE;
|
||||
|
||||
/* data associated with BTA_AV_START_EVT */
|
||||
|
48
components/bt/bluedroid/btif/btif_avk.c
Normal file → Executable file
48
components/bt/bluedroid/btif/btif_avk.c
Normal file → Executable file
@ -238,7 +238,7 @@ static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
|
||||
/*****************************************************************************
|
||||
** Static functions
|
||||
******************************************************************************/
|
||||
static void btif_report_connection_state(esp_a2d_connection_state_t state, bt_bdaddr_t *bd_addr)
|
||||
static void btif_report_connection_state(esp_a2d_connection_state_t state, bt_bdaddr_t *bd_addr, int disc_rsn)
|
||||
{
|
||||
esp_a2d_cb_param_t param;
|
||||
memset(¶m, 0, sizeof(esp_a2d_cb_param_t));
|
||||
@ -247,6 +247,10 @@ static void btif_report_connection_state(esp_a2d_connection_state_t state, bt_bd
|
||||
if (bd_addr) {
|
||||
memcpy(param.conn_stat.remote_bda, bd_addr, sizeof(esp_bd_addr_t));
|
||||
}
|
||||
if (state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
|
||||
param.conn_stat.disc_rsn = (disc_rsn == 0) ? ESP_A2D_DISC_RSN_NORMAL :
|
||||
ESP_A2D_DISC_RSN_ABNORMAL;
|
||||
}
|
||||
BTIF_A2D_CB_TO_APP(ESP_A2D_CONNECTION_STATE_EVT, ¶m);
|
||||
}
|
||||
|
||||
@ -374,7 +378,7 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
|
||||
switch (event) {
|
||||
case BTIF_SM_ENTER_EVT:
|
||||
/* inform the application that we are entering connecting state */
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda), 0);
|
||||
break;
|
||||
|
||||
case BTIF_SM_EXIT_EVT:
|
||||
@ -382,7 +386,7 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
|
||||
|
||||
case BTA_AV_REJECT_EVT:
|
||||
BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT \n");
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda), 0);
|
||||
btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
|
||||
break;
|
||||
|
||||
@ -408,7 +412,7 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
|
||||
}
|
||||
|
||||
/* inform the application of the event */
|
||||
btif_report_connection_state(state, &(btif_av_cb.peer_bda));
|
||||
btif_report_connection_state(state, &(btif_av_cb.peer_bda), 0);
|
||||
/* change state to open/idle based on the status */
|
||||
btif_sm_change_state(btif_av_cb.sm_handle, av_state);
|
||||
if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) {
|
||||
@ -442,7 +446,7 @@ static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data
|
||||
break;
|
||||
} else {
|
||||
BTIF_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request\n", __func__);
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, (bt_bdaddr_t *)p_data);
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, (bt_bdaddr_t *)p_data, 0);
|
||||
btif_queue_advance();
|
||||
break;
|
||||
}
|
||||
@ -506,13 +510,15 @@ static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data
|
||||
case BTIF_SM_EXIT_EVT:
|
||||
break;
|
||||
|
||||
case BTA_AV_CLOSE_EVT:
|
||||
|
||||
case BTA_AV_CLOSE_EVT: {
|
||||
tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data;
|
||||
/* inform the application that we are disconnecting */
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda),
|
||||
close->disc_rsn);
|
||||
|
||||
btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Handle the RC_CLOSE event for the cleanup */
|
||||
case BTA_AV_RC_CLOSE_EVT:
|
||||
@ -599,15 +605,17 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
|
||||
}
|
||||
|
||||
/* inform the application that we are disconnecting */
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda), 0);
|
||||
break;
|
||||
|
||||
case BTA_AV_CLOSE_EVT:
|
||||
case BTA_AV_CLOSE_EVT: {
|
||||
/* avdtp link is closed */
|
||||
btif_a2dp_on_stopped(NULL);
|
||||
|
||||
tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data;
|
||||
/* inform the application that we are disconnected */
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda),
|
||||
close->disc_rsn);
|
||||
|
||||
/* change state to idle, send acknowledgement if start is pending */
|
||||
if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
|
||||
@ -615,6 +623,7 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
|
||||
}
|
||||
btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
case BTA_AV_RECONFIG_EVT:
|
||||
if ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
|
||||
@ -633,7 +642,7 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
|
||||
} else {
|
||||
BTIF_TRACE_DEBUG("%s: Moved to opened by Other Incoming Conn req\n", __func__);
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED,
|
||||
(bt_bdaddr_t *)p_data);
|
||||
(bt_bdaddr_t *)p_data, ESP_A2D_DISC_RSN_NORMAL);
|
||||
}
|
||||
btif_queue_advance();
|
||||
break;
|
||||
@ -718,7 +727,7 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data
|
||||
}
|
||||
|
||||
/* inform the application that we are disconnecting */
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda), 0);
|
||||
|
||||
/* wait in closing state until fully closed */
|
||||
btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
|
||||
@ -774,20 +783,23 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data
|
||||
|
||||
break;
|
||||
|
||||
case BTA_AV_CLOSE_EVT:
|
||||
case BTA_AV_CLOSE_EVT: {
|
||||
|
||||
btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
|
||||
|
||||
/* avdtp link is closed */
|
||||
btif_a2dp_on_stopped(NULL);
|
||||
|
||||
|
||||
tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data;
|
||||
/* inform the application that we are disconnected */
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
|
||||
btif_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda),
|
||||
close->disc_rsn);
|
||||
|
||||
btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
|
||||
break;
|
||||
|
||||
CHECK_RC_EVENT(event, p_data);
|
||||
}
|
||||
|
||||
CHECK_RC_EVENT(event, p_data);
|
||||
|
||||
default:
|
||||
BTIF_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
|
||||
|
@ -326,9 +326,10 @@ void avdt_ad_tc_close_ind(tAVDT_TC_TBL *p_tbl, UINT16 reason)
|
||||
tAVDT_CCB *p_ccb;
|
||||
tAVDT_SCB *p_scb;
|
||||
tAVDT_SCB_TC_CLOSE close;
|
||||
UNUSED(reason);
|
||||
// UNUSED(reason);
|
||||
|
||||
close.old_tc_state = p_tbl->state;
|
||||
|
||||
/* clear avdt_ad_tc_tbl entry */
|
||||
p_tbl->state = AVDT_AD_ST_UNUSED;
|
||||
p_tbl->cfg_flags = 0;
|
||||
@ -336,10 +337,12 @@ void avdt_ad_tc_close_ind(tAVDT_TC_TBL *p_tbl, UINT16 reason)
|
||||
|
||||
AVDT_TRACE_DEBUG("avdt_ad_tc_close_ind tcid: %d, old: %d\n",
|
||||
p_tbl->tcid, close.old_tc_state);
|
||||
|
||||
/* if signaling channel, notify ccb that channel open */
|
||||
if (p_tbl->tcid == 0)
|
||||
{
|
||||
p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
|
||||
p_ccb->disc_rsn = (reason == AVDT_DISC_RSN_ABNORMAL) ? AVDT_DISC_RSN_ABNORMAL : AVDT_DISC_RSN_NORMAL;
|
||||
avdt_ccb_event(p_ccb, AVDT_CCB_LL_CLOSE_EVT, NULL);
|
||||
}
|
||||
/* if media or other channel, notify scb that channel close */
|
||||
@ -351,6 +354,7 @@ void avdt_ad_tc_close_ind(tAVDT_TC_TBL *p_tbl, UINT16 reason)
|
||||
{
|
||||
close.tcid = p_tbl->tcid;
|
||||
close.type = avdt_ad_tcid_to_type(p_tbl->tcid);
|
||||
close.disc_rsn = (reason == AVDT_DISC_RSN_ABNORMAL) ? AVDT_DISC_RSN_ABNORMAL : AVDT_DISC_RSN_NORMAL;
|
||||
avdt_scb_event(p_scb, AVDT_SCB_TC_CLOSE_EVT, (tAVDT_SCB_EVT *)&close);
|
||||
}
|
||||
}
|
||||
|
@ -1077,6 +1077,7 @@ void avdt_ccb_ll_closed(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
|
||||
tAVDT_CTRL_CBACK *p_cback;
|
||||
BD_ADDR bd_addr;
|
||||
tAVDT_CTRL avdt_ctrl;
|
||||
UINT8 disc_rsn;
|
||||
UNUSED(p_data);
|
||||
|
||||
/* clear any pending commands */
|
||||
@ -1088,6 +1089,8 @@ void avdt_ccb_ll_closed(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
|
||||
p_cback = avdt_cb.p_conn_cback;
|
||||
memcpy(bd_addr, p_ccb->peer_addr, BD_ADDR_LEN);
|
||||
|
||||
disc_rsn = p_ccb->disc_rsn;
|
||||
|
||||
/* dealloc ccb */
|
||||
avdt_ccb_dealloc(p_ccb, NULL);
|
||||
|
||||
@ -1095,6 +1098,8 @@ void avdt_ccb_ll_closed(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
|
||||
if (p_cback)
|
||||
{
|
||||
avdt_ctrl.hdr.err_code = 0;
|
||||
avdt_ctrl.hdr.err_param = disc_rsn;
|
||||
|
||||
(*p_cback)(0, bd_addr, AVDT_DISCONNECT_IND_EVT, &avdt_ctrl);
|
||||
}
|
||||
}
|
||||
|
@ -444,7 +444,7 @@ void avdt_l2c_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
|
||||
void avdt_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed)
|
||||
{
|
||||
tAVDT_TC_TBL *p_tbl;
|
||||
|
||||
UINT16 disc_rsn = AVDT_DISC_RSN_NORMAL;
|
||||
AVDT_TRACE_DEBUG("avdt_l2c_disconnect_ind_cback lcid: %d, ack_needed: %d\n",
|
||||
lcid, ack_needed);
|
||||
/* look up info for this channel */
|
||||
@ -454,9 +454,11 @@ void avdt_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed)
|
||||
{
|
||||
/* send L2CAP disconnect response */
|
||||
L2CA_DisconnectRsp(lcid);
|
||||
} else {
|
||||
disc_rsn = AVDT_DISC_RSN_ABNORMAL;
|
||||
}
|
||||
|
||||
avdt_ad_tc_close_ind(p_tbl, 0);
|
||||
avdt_ad_tc_close_ind(p_tbl, disc_rsn);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1007,6 +1007,7 @@ void avdt_scb_hdl_tc_close(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
|
||||
|
||||
/* set up hdr */
|
||||
avdt_ctrl.hdr.err_code = p_scb->close_code;
|
||||
avdt_ctrl.hdr.err_param = p_data->close.disc_rsn;
|
||||
|
||||
/* clear sep variables */
|
||||
avdt_scb_clr_vars(p_scb, p_data);
|
||||
|
@ -440,6 +440,7 @@ typedef struct {
|
||||
UINT8 label; /* Message header "label" (sequence number) */
|
||||
BOOLEAN reconn; /* If TRUE, reinitiate connection after transitioning from CLOSING to IDLE state */
|
||||
UINT8 ret_count; /* Command retransmission count */
|
||||
UINT8 disc_rsn; /* disconnection reason */
|
||||
} tAVDT_CCB;
|
||||
|
||||
/* type for action functions */
|
||||
@ -463,6 +464,7 @@ typedef struct {
|
||||
UINT8 old_tc_state; /* channel state before closed */
|
||||
UINT8 tcid; /* TCID */
|
||||
UINT8 type; /* channel type */
|
||||
UINT8 disc_rsn; /* disconnection reason */
|
||||
} tAVDT_SCB_TC_CLOSE;
|
||||
|
||||
/* type for scb event data */
|
||||
|
@ -203,6 +203,9 @@ typedef UINT8 AVDT_REPORT_TYPE;
|
||||
#define AVDT_NSC_RECONFIG 0x02 /* Reconfigure command not supported */
|
||||
#define AVDT_NSC_SECURITY 0x04 /* Security command not supported */
|
||||
|
||||
/* AVDT disconnection reason */
|
||||
#define AVDT_DISC_RSN_NORMAL 0
|
||||
#define AVDT_DISC_RSN_ABNORMAL (0xce) /* unintentional disconnection */
|
||||
/*****************************************************************************
|
||||
** Type Definitions
|
||||
*****************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user