]> granicus.if.org Git - esp-idf/commitdiff
component/bt: modification to a2dp API to support reconnection
authorwangmengyang <wangmengyang@espressif.com>
Thu, 23 Feb 2017 06:30:08 +0000 (14:30 +0800)
committerwangmengyang <wangmengyang@espressif.com>
Thu, 23 Feb 2017 06:30:08 +0000 (14:30 +0800)
1. add API esp_a2d_sink_connect() to initiate connection to other devices;
2. modify lower layers to transfer the disconnection reason upwards

12 files changed:
components/bt/bluedroid/api/include/esp_a2dp_api.h [changed mode: 0644->0755]
components/bt/bluedroid/bta/av/bta_av_aact.c
components/bt/bluedroid/bta/av/bta_av_act.c
components/bt/bluedroid/bta/av/bta_av_int.h
components/bt/bluedroid/bta/include/bta_av_api.h
components/bt/bluedroid/btif/btif_avk.c [changed mode: 0644->0755]
components/bt/bluedroid/stack/avdt/avdt_ad.c
components/bt/bluedroid/stack/avdt/avdt_ccb_act.c
components/bt/bluedroid/stack/avdt/avdt_l2c.c
components/bt/bluedroid/stack/avdt/avdt_scb_act.c
components/bt/bluedroid/stack/avdt/include/avdt_int.h
components/bt/bluedroid/stack/include/avdt_api.h

old mode 100644 (file)
new mode 100755 (executable)
index c8cc53e..2d8cadb
@@ -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
index a47d7d3320daa7ed7992d074557b2cc16e8d88be..9192f52320e37a5bd413c36d1819a742e20c9403 100755 (executable)
@@ -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);
index 002c92dfa77c4283253d2aa0de9a9be454e53961..b1b0e5805b10e8df7cce9084681d70a0bdd25d1e 100755 (executable)
@@ -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);
                 }
             }
index 15f13afca68ea65fc472846b822e1ab436b99207..c4b5907590b6035cacbb948df3835f1ee9da56b4 100755 (executable)
@@ -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;
 
index 90ca461e07df855ccd8745e292d19d41242fce95..7f70d2990b94a1a9c781aabc44675e6f06325f99 100755 (executable)
@@ -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 */
old mode 100644 (file)
new mode 100755 (executable)
index 06315f7..d8cbb2a
@@ -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(&param, 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, &param);
 }
 
@@ -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__,
index c8928d0a9b68841e8d8356bbf2c148c7a3a49c6c..67fb490d696efec2fcfdbba35adba5095b6998a7 100755 (executable)
@@ -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);
         }
     }
index 4dd9b239b8760b792660f855ba78bc10545e599c..8b3dbfa6a6fa45d42f3aba148599e31b68be8184 100755 (executable)
@@ -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);
     }
 }
index 44721c93f23d76f97bfde50fc6de4e81a3851e5d..a01ed9dbdcf9dbfab1344541bab6c7b6b9aa7403 100755 (executable)
@@ -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);
     }
 }
 
index eb2227c6bed53b7ff5e8fb8c7e109bab3be3e321..f0a4d9dc5fcd8b2e4081fda7ea36a298fc7bb906 100755 (executable)
@@ -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);
index fb1b31360c1a6eb3116cf6eef89a87641b61455e..5c2939c495b8dc31024ca5009d2f14c7b9ad9d4f 100755 (executable)
@@ -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 */
index 41f8a12ded90ea61412b8e11c65e643e56e3d084..2299d1e85bf2933bb6c9834702e5ef8c1b7ce422 100755 (executable)
@@ -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
 *****************************************************************************/