From: wangmengyang Date: Thu, 23 Feb 2017 06:30:08 +0000 (+0800) Subject: component/bt: modification to a2dp API to support reconnection X-Git-Tag: v2.1-rc1~196^2~42 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=118131109ebe47813f5f8d2faf4a09116e0fc2ad;p=esp-idf 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 --- diff --git a/components/bt/bluedroid/api/include/esp_a2dp_api.h b/components/bt/bluedroid/api/include/esp_a2dp_api.h old mode 100644 new mode 100755 index c8cc53e86a..2d8cadb3c5 --- a/components/bt/bluedroid/api/include/esp_a2dp_api.h +++ b/components/bt/bluedroid/api/include/esp_a2dp_api.h @@ -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 diff --git a/components/bt/bluedroid/bta/av/bta_av_aact.c b/components/bt/bluedroid/bta/av/bta_av_aact.c index a47d7d3320..9192f52320 100755 --- a/components/bt/bluedroid/bta/av/bta_av_aact.c +++ b/components/bt/bluedroid/bta/av/bta_av_aact.c @@ -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); diff --git a/components/bt/bluedroid/bta/av/bta_av_act.c b/components/bt/bluedroid/bta/av/bta_av_act.c index 002c92dfa7..b1b0e5805b 100755 --- a/components/bt/bluedroid/bta/av/bta_av_act.c +++ b/components/bt/bluedroid/bta/av/bta_av_act.c @@ -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); } } diff --git a/components/bt/bluedroid/bta/av/bta_av_int.h b/components/bt/bluedroid/bta/av/bta_av_int.h index 15f13afca6..c4b5907590 100755 --- a/components/bt/bluedroid/bta/av/bta_av_int.h +++ b/components/bt/bluedroid/bta/av/bta_av_int.h @@ -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; diff --git a/components/bt/bluedroid/bta/include/bta_av_api.h b/components/bt/bluedroid/bta/include/bta_av_api.h index 90ca461e07..7f70d2990b 100755 --- a/components/bt/bluedroid/bta/include/bta_av_api.h +++ b/components/bt/bluedroid/bta/include/bta_av_api.h @@ -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 */ diff --git a/components/bt/bluedroid/btif/btif_avk.c b/components/bt/bluedroid/btif/btif_avk.c old mode 100644 new mode 100755 index 06315f7e32..d8cbb2a585 --- a/components/bt/bluedroid/btif/btif_avk.c +++ b/components/bt/bluedroid/btif/btif_avk.c @@ -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__, diff --git a/components/bt/bluedroid/stack/avdt/avdt_ad.c b/components/bt/bluedroid/stack/avdt/avdt_ad.c index c8928d0a9b..67fb490d69 100755 --- a/components/bt/bluedroid/stack/avdt/avdt_ad.c +++ b/components/bt/bluedroid/stack/avdt/avdt_ad.c @@ -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); } } diff --git a/components/bt/bluedroid/stack/avdt/avdt_ccb_act.c b/components/bt/bluedroid/stack/avdt/avdt_ccb_act.c index 4dd9b239b8..8b3dbfa6a6 100755 --- a/components/bt/bluedroid/stack/avdt/avdt_ccb_act.c +++ b/components/bt/bluedroid/stack/avdt/avdt_ccb_act.c @@ -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); } } diff --git a/components/bt/bluedroid/stack/avdt/avdt_l2c.c b/components/bt/bluedroid/stack/avdt/avdt_l2c.c index 44721c93f2..a01ed9dbdc 100755 --- a/components/bt/bluedroid/stack/avdt/avdt_l2c.c +++ b/components/bt/bluedroid/stack/avdt/avdt_l2c.c @@ -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); } } diff --git a/components/bt/bluedroid/stack/avdt/avdt_scb_act.c b/components/bt/bluedroid/stack/avdt/avdt_scb_act.c index eb2227c6be..f0a4d9dc5f 100755 --- a/components/bt/bluedroid/stack/avdt/avdt_scb_act.c +++ b/components/bt/bluedroid/stack/avdt/avdt_scb_act.c @@ -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); diff --git a/components/bt/bluedroid/stack/avdt/include/avdt_int.h b/components/bt/bluedroid/stack/avdt/include/avdt_int.h index fb1b31360c..5c2939c495 100755 --- a/components/bt/bluedroid/stack/avdt/include/avdt_int.h +++ b/components/bt/bluedroid/stack/avdt/include/avdt_int.h @@ -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 */ diff --git a/components/bt/bluedroid/stack/include/avdt_api.h b/components/bt/bluedroid/stack/include/avdt_api.h index 41f8a12ded..2299d1e85b 100755 --- a/components/bt/bluedroid/stack/include/avdt_api.h +++ b/components/bt/bluedroid/stack/include/avdt_api.h @@ -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 *****************************************************************************/