A2DP SRC offload support

bluedroid changes to support A2DP SRC offload to BT FW.
add functionality to relay a2dp offload requests and responses
between AudioHAL & the BT vendor library.

Change-Id: Ie4e5992c48e95b0efb372a405e8537e4fd3ea071
Signed-off-by: Sridhar Vashist <svashist@motorola.com>
diff --git a/system/audio_a2dp_hw/audio_a2dp_hw.h b/system/audio_a2dp_hw/audio_a2dp_hw.h
index 1e9464c..901fafb 100644
--- a/system/audio_a2dp_hw/audio_a2dp_hw.h
+++ b/system/audio_a2dp_hw/audio_a2dp_hw.h
@@ -48,12 +48,14 @@
     A2DP_CTRL_CMD_STOP,
     A2DP_CTRL_CMD_SUSPEND,
     A2DP_CTRL_GET_AUDIO_CONFIG,
+    A2DP_CTRL_CMD_OFFLOAD_START,
 } tA2DP_CTRL_CMD;
 
 typedef enum {
     A2DP_CTRL_ACK_SUCCESS,
     A2DP_CTRL_ACK_FAILURE,
-    A2DP_CTRL_ACK_INCALL_FAILURE /* Failure when in Call*/
+    A2DP_CTRL_ACK_INCALL_FAILURE, /* Failure when in Call*/
+    A2DP_CTRL_ACK_UNSUPPORTED
 } tA2DP_CTRL_ACK;
 
 
diff --git a/system/bta/av/bta_av_aact.c b/system/bta/av/bta_av_aact.c
index 333db2f..d4e2e57 100644
--- a/system/bta/av/bta_av_aact.c
+++ b/system/bta/av/bta_av_aact.c
@@ -37,6 +37,9 @@
 #include "utl.h"
 #include "l2c_api.h"
 #include "l2cdefs.h"
+#include "bt_utils.h"
+#include "vendor.h"
+
 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
 #include "bta_ar_api.h"
 #endif
@@ -60,6 +63,9 @@
 #define BTA_AV_RECONFIG_RETRY       6
 #endif
 
+/* ACL quota we are letting FW use for A2DP Offload Tx. */
+#define BTA_AV_A2DP_OFFLOAD_XMIT_QUOTA      4
+
 static void bta_av_st_rc_timer(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
 
 /* state machine states */
@@ -140,6 +146,8 @@
     bta_av_role_res,        /* BTA_AV_ROLE_RES */
     bta_av_delay_co,        /* BTA_AV_DELAY_CO */
     bta_av_open_at_inc,     /* BTA_AV_OPEN_AT_INC */
+    bta_av_offload_req,     /* BTA_AV_OFFLOAD_REQ */
+    bta_av_offload_rsp,     /* BTA_AV_OFFLOAD_RSP */
     NULL
 };
 
@@ -1076,6 +1084,14 @@
     p_scb->wait = 0;
     p_scb->num_disc_snks = 0;
     bta_sys_stop_timer(&p_scb->timer);
+
+    vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
+    if (p_scb->offload_start_pending) {
+        tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
+        (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
+    }
+    p_scb->offload_start_pending = FALSE;
+
     if (p_scb->deregistring)
     {
         /* remove stream */
@@ -1381,6 +1397,7 @@
     bta_av_conn_chg((tBTA_AV_DATA *) &msg);
     /* set the congestion flag, so AV would not send media packets by accident */
     p_scb->cong = TRUE;
+    p_scb->offload_start_pending = FALSE;
 
 
     p_scb->stream_mtu = p_data->str_msg.msg.open_ind.peer_mtu - AVDT_MEDIA_HDR_SIZE;
@@ -2061,6 +2078,13 @@
 
     if (p_scb->co_started)
     {
+        vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
+        if (p_scb->offload_start_pending) {
+            tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
+            (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
+        }
+        p_scb->offload_start_pending = FALSE;
+
         bta_av_stream_chg(p_scb, FALSE);
         p_scb->co_started = FALSE;
 
@@ -2653,6 +2677,13 @@
     /* in case that we received suspend_ind, we may need to call co_stop here */
     if(p_scb->co_started)
     {
+        vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
+        if (p_scb->offload_start_pending) {
+            tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
+            (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
+        }
+        p_scb->offload_start_pending = FALSE;
+
         bta_av_stream_chg(p_scb, FALSE);
 
         {
@@ -3101,4 +3132,88 @@
     }
 }
 
+/*******************************************************************************
+**
+** Function         bta_av_offload_req
+**
+** Description      This function is called if application requests offload of
+**                  a2dp audio.
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_av_offload_req(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
+{
+    tBTA_AV_STATUS status = BTA_AV_FAIL_RESOURCES;
+    UINT16 mtu = bta_av_chk_mtu(p_scb, p_scb->stream_mtu);
+
+    APPL_TRACE_DEBUG("%s stream %s, audio channels open %d", __func__,
+                     p_scb->started ? "STARTED" : "STOPPED", bta_av_cb.audio_open_cnt);
+
+    /* Check if stream has already been started. */
+    /* Support offload if only one audio source stream is open. */
+    if (p_scb->started != TRUE) {
+        status = BTA_AV_FAIL_STREAM;
+
+    } else if (bta_av_cb.audio_open_cnt == 1 &&
+               p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC &&
+               p_scb->chnl == BTA_AV_CHNL_AUDIO) {
+
+        bt_vendor_op_a2dp_offload_t a2dp_offload_start;
+
+        if (L2CA_GetConnectionConfig(p_scb->l2c_cid, &a2dp_offload_start.acl_data_size,
+                                     &a2dp_offload_start.remote_cid, &a2dp_offload_start.lm_handle)) {
+
+            APPL_TRACE_DEBUG("%s l2cmtu %d lcid 0x%02X rcid 0x%02X lm_handle 0x%02X", __func__,
+                             a2dp_offload_start.acl_data_size, p_scb->l2c_cid,
+                             a2dp_offload_start.remote_cid, a2dp_offload_start.lm_handle);
+
+            a2dp_offload_start.bta_av_handle = p_scb->hndl;
+            a2dp_offload_start.xmit_quota = BTA_AV_A2DP_OFFLOAD_XMIT_QUOTA;
+            a2dp_offload_start.stream_mtu = (mtu < p_scb->stream_mtu) ? mtu : p_scb->stream_mtu;
+            a2dp_offload_start.local_cid = p_scb->l2c_cid;
+            a2dp_offload_start.is_flushable = TRUE;
+            a2dp_offload_start.stream_source = ((UINT32)(p_scb->cfg.codec_info[1] | p_scb->cfg.codec_info[2]));
+
+            memcpy(a2dp_offload_start.codec_info, p_scb->cfg.codec_info,
+                   sizeof(a2dp_offload_start.codec_info));
+
+            if (!vendor_get_interface()->send_command(BT_VND_OP_A2DP_OFFLOAD_START, &a2dp_offload_start)) {
+                status = BTA_AV_SUCCESS;
+                p_scb->offload_start_pending = TRUE;
+            }
+        }
+    }
+
+    if (status != BTA_AV_SUCCESS)
+        (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
+}
+
+/*******************************************************************************
+**
+** Function         bta_av_offload_rsp
+**
+** Description      This function is called when the vendor lib responds to
+**                  BT_VND_OP_A2DP_OFFLOAD_START.
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_av_offload_rsp(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
+{
+    tBTA_AV_STATUS status = p_data->api_status_rsp.status;
+
+    APPL_TRACE_DEBUG("%s stream %s status %s", __func__,
+                     p_scb->started ? "STARTED" : "STOPPED",
+                     status ? "FAIL" : "SUCCESS");
+
+    /* Check if stream has already been started. */
+    if (status == BTA_AV_SUCCESS && p_scb->started != TRUE) {
+        status = BTA_AV_FAIL_STREAM;
+    }
+
+    p_scb->offload_start_pending = FALSE;
+    (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV *)&status);
+}
+
 #endif /* BTA_AV_INCLUDED */
diff --git a/system/bta/av/bta_av_api.c b/system/bta/av/bta_av_api.c
index eadd4b8..6dcdcfb 100644
--- a/system/bta/av/bta_av_api.c
+++ b/system/bta/av/bta_av_api.c
@@ -246,6 +246,47 @@
 
 /*******************************************************************************
 **
+** Function         BTA_AvOffloadStart
+**
+** Description      Start a2dp audio offloading.
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AvOffloadStart(tBTA_AV_HNDL hndl)
+{
+    BT_HDR  *p_buf;
+    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
+    {
+        p_buf->event = BTA_AV_API_OFFLOAD_START_EVT;
+        p_buf->layer_specific = hndl;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_AvOffloadStartRsp
+**
+** Description      Response from vendor lib for A2DP Offload Start request.
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AvOffloadStartRsp(tBTA_AV_HNDL hndl, tBTA_AV_STATUS status)
+{
+    tBTA_AV_API_STATUS_RSP *p_buf;
+    if ((p_buf = (tBTA_AV_API_STATUS_RSP *) GKI_getbuf(sizeof(tBTA_AV_API_STATUS_RSP))) != NULL)
+    {
+        p_buf->hdr.event = BTA_AV_API_OFFLOAD_START_RSP_EVT;
+        p_buf->hdr.layer_specific = hndl;
+        p_buf->status = status;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
 ** Function         BTA_AvEnable_Sink
 **
 ** Description      Enable/Disable A2DP Sink..
diff --git a/system/bta/av/bta_av_int.h b/system/bta/av/bta_av_int.h
index 78725a2..2151209 100644
--- a/system/bta/av/bta_av_int.h
+++ b/system/bta/av/bta_av_int.h
@@ -84,6 +84,8 @@
     BTA_AV_ROLE_CHANGE_EVT,
     BTA_AV_AVDT_DELAY_RPT_EVT,
     BTA_AV_ACP_CONNECT_EVT,
+    BTA_AV_API_OFFLOAD_START_EVT,
+    BTA_AV_API_OFFLOAD_START_RSP_EVT,
 
     /* these events are handled outside of the state machine */
     BTA_AV_API_ENABLE_EVT,
@@ -379,6 +381,14 @@
     UINT16              avdt_version;   /* AVDTP protocol version */
 } tBTA_AV_SDP_RES;
 
+/* data type for BTA_AV_API_OFFLOAD_RSP_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tBTA_AV_STATUS      status;
+} tBTA_AV_API_STATUS_RSP;
+
+
 /* type for SEP control block */
 typedef struct
 {
@@ -422,6 +432,7 @@
     tBTA_AV_ROLE_RES        role_res;
     tBTA_AV_SDP_RES         sdp_res;
     tBTA_AV_API_META_RSP    api_meta_rsp;
+    tBTA_AV_API_STATUS_RSP  api_status_rsp;
 } tBTA_AV_DATA;
 
 typedef void (tBTA_AV_VDP_DATA_ACT)(void *p_scb);
@@ -515,6 +526,7 @@
     UINT8               q_tag;          /* identify the associated q_info union member */
     BOOLEAN             no_rtp_hdr;     /* TRUE if add no RTP header*/
     UINT16              uuid_int;       /*intended UUID of Initiator to connect to */
+    BOOLEAN             offload_start_pending;
 } tBTA_AV_SCB;
 
 #define BTA_AV_RC_ROLE_MASK     0x10
@@ -723,6 +735,9 @@
 extern void bta_av_role_res (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
 extern void bta_av_delay_co (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
 extern void bta_av_open_at_inc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
+extern void bta_av_offload_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
+extern void bta_av_offload_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
+
 
 /* ssm action functions - vdp specific */
 extern void bta_av_do_disc_vdp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
diff --git a/system/bta/av/bta_av_ssm.c b/system/bta/av/bta_av_ssm.c
index 64ee42a..4956603 100644
--- a/system/bta/av/bta_av_ssm.c
+++ b/system/bta/av/bta_av_ssm.c
@@ -96,6 +96,8 @@
     BTA_AV_ROLE_RES,
     BTA_AV_DELAY_CO,
     BTA_AV_OPEN_AT_INC,
+    BTA_AV_OFFLOAD_REQ,
+    BTA_AV_OFFLOAD_RSP,
     BTA_AV_NUM_SACTIONS
 };
 
@@ -145,7 +147,9 @@
 /* AVDT_DISCONNECT_EVT */   {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
 /* ROLE_CHANGE_EVT*/        {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
 /* AVDT_DELAY_RPT_EVT */    {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
-/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST }
+/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
+/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
+/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_INIT_SST }
 };
 
 /* state table for incoming state */
@@ -185,7 +189,9 @@
 /* AVDT_DISCONNECT_EVT */   {BTA_AV_CCO_CLOSE,      BTA_AV_CLEANUP,        BTA_AV_INIT_SST },
 /* ROLE_CHANGE_EVT*/        {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
 /* AVDT_DELAY_RPT_EVT */    {BTA_AV_DELAY_CO,       BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
-/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST }
+/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
+/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
+/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST }
 };
 
 /* state table for opening state */
@@ -225,7 +231,9 @@
 /* AVDT_DISCONNECT_EVT */   {BTA_AV_CONN_FAILED,    BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
 /* ROLE_CHANGE_EVT*/        {BTA_AV_ROLE_RES,       BTA_AV_SIGNORE,        BTA_AV_OPENING_SST },
 /* AVDT_DELAY_RPT_EVT */    {BTA_AV_DELAY_CO,       BTA_AV_SIGNORE,        BTA_AV_OPENING_SST },
-/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_OPENING_SST }
+/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_OPENING_SST },
+/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_OPENING_SST },
+/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_OPENING_SST }
 };
 
 /* state table for open state */
@@ -265,7 +273,9 @@
 /* AVDT_DISCONNECT_EVT */   {BTA_AV_STR_CLOSED,     BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
 /* ROLE_CHANGE_EVT*/        {BTA_AV_ROLE_RES,       BTA_AV_SIGNORE,        BTA_AV_OPEN_SST },
 /* AVDT_DELAY_RPT_EVT */    {BTA_AV_DELAY_CO,       BTA_AV_SIGNORE,        BTA_AV_OPEN_SST },
-/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_OPEN_SST }
+/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_OPEN_SST },
+/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_OPEN_SST },
+/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_OPEN_SST }
 };
 
 /* state table for reconfig state */
@@ -305,7 +315,9 @@
 /* AVDT_DISCONNECT_EVT */   {BTA_AV_RCFG_DISCNTD,   BTA_AV_SIGNORE,        BTA_AV_RCFG_SST },
 /* ROLE_CHANGE_EVT*/        {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_RCFG_SST },
 /* AVDT_DELAY_RPT_EVT */    {BTA_AV_DELAY_CO,       BTA_AV_SIGNORE,        BTA_AV_RCFG_SST },
-/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_RCFG_SST }
+/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_RCFG_SST },
+/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_RCFG_SST },
+/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_RCFG_SST }
 };
 
 /* state table for closing state */
@@ -345,7 +357,9 @@
 /* AVDT_DISCONNECT_EVT */   {BTA_AV_STR_CLOSED,     BTA_AV_SIGNORE,        BTA_AV_INIT_SST },
 /* ROLE_CHANGE_EVT*/        {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST },
 /* AVDT_DELAY_RPT_EVT */    {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST },
-/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST }
+/* ACP_CONNECT_EVT */       {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST },
+/* API_OFFLOAD_START_EVT */{BTA_AV_OFFLOAD_REQ,    BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST },
+/* API_OFFLOAD_START_RSP_EVT */{BTA_AV_OFFLOAD_RSP,    BTA_AV_SIGNORE,        BTA_AV_CLOSING_SST }
 };
 
 /* type for state table */
diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h
index da61249..351ebe9 100644
--- a/system/bta/include/bta_api.h
+++ b/system/bta/include/bta_api.h
@@ -28,7 +28,6 @@
 #include "bt_target.h"
 #include "bt_types.h"
 #include "btm_api.h"
-#include "uipc_msg.h"
 
 #if BLE_INCLUDED == TRUE
 #include "btm_ble_api.h"
diff --git a/system/bta/include/bta_av_api.h b/system/bta/include/bta_av_api.h
index e0e356f..8b92d30 100644
--- a/system/bta/include/bta_av_api.h
+++ b/system/bta/include/bta_av_api.h
@@ -249,10 +249,11 @@
 #define BTA_AV_META_MSG_EVT     17      /* metadata messages */
 #define BTA_AV_REJECT_EVT       18      /* incoming connection rejected */
 #define BTA_AV_RC_FEAT_EVT      19      /* remote control channel peer supported features update */
-#define BTA_AV_MEDIA_SINK_CFG_EVT    20      /* command to configure codec */
+#define BTA_AV_MEDIA_SINK_CFG_EVT    20 /* command to configure codec */
 #define BTA_AV_MEDIA_DATA_EVT   21      /* sending data to Media Task */
+#define BTA_AV_OFFLOAD_START_RSP_EVT 22 /* a2dp offload start response */
 /* Max BTA event */
-#define BTA_AV_MAX_EVT          22
+#define BTA_AV_MAX_EVT          23
 
 
 typedef UINT8 tBTA_AV_EVT;
@@ -448,6 +449,7 @@
     tBTA_AV_META_MSG    meta_msg;
     tBTA_AV_REJECT      reject;
     tBTA_AV_RC_FEAT     rc_feat;
+    tBTA_AV_STATUS      status;
 } tBTA_AV;
 
 /* union of data associated with AV Media callback */
@@ -784,6 +786,32 @@
 *******************************************************************************/
 void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p_pkt);
 
+/*******************************************************************************
+**
+** Function         BTA_AvOffloadStart
+**
+** Description      Request Starting of A2DP Offload.
+**                  This function is used to start A2DP offload if vendor lib has
+**                  the feature enabled.
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AvOffloadStart(tBTA_AV_HNDL hndl);
+
+/*******************************************************************************
+**
+** Function         BTA_AvOffloadStartRsp
+**
+** Description      Response from vendor library indicating response for
+**                  OffloadStart.
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AvOffloadStartRsp(tBTA_AV_HNDL hndl, tBTA_AV_STATUS status);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/system/btif/include/btif_av.h b/system/btif/include/btif_av.h
index cedc1b7..4b116ee 100644
--- a/system/btif/include/btif_av.h
+++ b/system/btif/include/btif_av.h
@@ -45,6 +45,7 @@
     BTIF_AV_STOP_STREAM_REQ_EVT,
     BTIF_AV_SUSPEND_STREAM_REQ_EVT,
     BTIF_AV_SINK_CONFIG_REQ_EVT,
+    BTIF_AV_OFFLOAD_START_REQ_EVT,
 } btif_av_sm_event_t;
 
 
diff --git a/system/btif/include/btif_media.h b/system/btif/include/btif_media.h
index f128c47..9602d6a 100644
--- a/system/btif/include/btif_media.h
+++ b/system/btif/include/btif_media.h
@@ -274,6 +274,8 @@
 void btif_a2dp_set_rx_flush(BOOLEAN enable);
 void btif_media_check_iop_exceptions(UINT8 *peer_bda);
 void btif_reset_decoder(UINT8 *p_av);
+void btif_a2dp_on_offload_started(tBTA_AV_STATUS status);
+
 
 int btif_a2dp_get_track_frequency(UINT8 frequency);
 int btif_a2dp_get_track_channel_count(UINT8 channeltype);
diff --git a/system/btif/src/btif_av.c b/system/btif/src/btif_av.c
index 251badc..f8e7771 100644
--- a/system/btif/src/btif_av.c
+++ b/system/btif/src/btif_av.c
@@ -183,6 +183,7 @@
         CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
         CASE_RETURN_STR(BTA_AV_REJECT_EVT)
         CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
+        CASE_RETURN_STR(BTA_AV_OFFLOAD_START_RSP_EVT)
         CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
         CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
         CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
@@ -191,6 +192,7 @@
         CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
         CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
         CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
+        CASE_RETURN_STR(BTIF_AV_OFFLOAD_START_REQ_EVT)
         default: return "UNKNOWN_EVENT";
    }
 }
@@ -339,6 +341,11 @@
             btif_rc_handler(event, p_data);
             break;
 
+        case BTIF_AV_OFFLOAD_START_REQ_EVT:
+            BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started IDLE");
+            btif_a2dp_on_offload_started(BTA_AV_FAIL);
+            break;
+
         default:
             BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
                                 dump_av_sm_event_name(event));
@@ -471,6 +478,11 @@
                 break;
             }
 
+        case BTIF_AV_OFFLOAD_START_REQ_EVT:
+            btif_a2dp_on_offload_started(BTA_AV_FAIL);
+            BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started OPENING");
+            break;
+
         CHECK_RC_EVENT(event, p_data);
 
         default:
@@ -544,6 +556,11 @@
             btif_rc_handler(event, (tBTA_AV*)p_data);
             break;
 
+        case BTIF_AV_OFFLOAD_START_REQ_EVT:
+            btif_a2dp_on_offload_started(BTA_AV_FAIL);
+            BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Closing");
+            break;
+
         default:
             BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
                                 dump_av_sm_event_name(event));
@@ -699,6 +716,11 @@
             btif_queue_advance();
             break;
 
+        case BTIF_AV_OFFLOAD_START_REQ_EVT:
+            btif_a2dp_on_offload_started(BTA_AV_FAIL);
+            BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Opened");
+            break;
+
         CHECK_RC_EVENT(event, p_data);
 
         default:
@@ -865,6 +887,15 @@
             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
             break;
 
+        case BTIF_AV_OFFLOAD_START_REQ_EVT:
+            BTA_AvOffloadStart(btif_av_cb.bta_handle);
+            break;
+
+        case BTA_AV_OFFLOAD_START_RSP_EVT:
+
+            btif_a2dp_on_offload_started(p_av->status);
+            break;
+
         CHECK_RC_EVENT(event, p_data);
 
         default:
diff --git a/system/btif/src/btif_media_task.c b/system/btif/src/btif_media_task.c
index 130062e..df70689 100644
--- a/system/btif/src/btif_media_task.c
+++ b/system/btif/src/btif_media_task.c
@@ -43,6 +43,8 @@
 
 #include <hardware/bluetooth.h>
 
+#define LOG_TAG "BTIF-MEDIA"
+
 #include "a2d_api.h"
 #include "a2d_int.h"
 #include "a2d_sbc.h"
@@ -369,6 +371,8 @@
         CASE_RETURN_STR(A2DP_CTRL_CMD_START)
         CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
         CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
+        CASE_RETURN_STR(A2DP_CTRL_CMD_OFFLOAD_START)
+
         default:
             return "UNKNOWN MSG ID";
     }
@@ -528,6 +532,10 @@
             break;
         }
 
+        case A2DP_CTRL_CMD_OFFLOAD_START:
+                btif_dispatch_sm_event(BTIF_AV_OFFLOAD_START_REQ_EVT, NULL, 0);
+            break;
+
         default:
             APPL_TRACE_ERROR("UNSUPPORTED CMD (%d)", cmd);
             a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
@@ -797,9 +805,9 @@
     mutex_global_lock();
 
     /* for now hardcode 44.1 khz 16 bit stereo PCM format */
-    media_feeding.cfg.pcm.sampling_freq = 44100;
-    media_feeding.cfg.pcm.bit_per_sample = 16;
-    media_feeding.cfg.pcm.num_channel = 2;
+    media_feeding.cfg.pcm.sampling_freq = BTIF_A2DP_SRC_SAMPLING_RATE;
+    media_feeding.cfg.pcm.bit_per_sample = BTIF_A2DP_SRC_BIT_DEPTH;
+    media_feeding.cfg.pcm.num_channel = BTIF_A2DP_SRC_NUM_CHANNELS;
     media_feeding.format = BTIF_AV_CODEC_PCM;
 
     if (bta_av_co_audio_set_codec(&media_feeding, &status))
@@ -1076,6 +1084,38 @@
     btif_media_task_stop_aa_req();
 }
 
+
+/*****************************************************************************
+**
+** Function        btif_a2dp_on_offload_started
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+void btif_a2dp_on_offload_started(tBTA_AV_STATUS status)
+{
+    tA2DP_CTRL_ACK ack;
+    APPL_TRACE_EVENT("%s status %d", __func__, status);
+
+    switch (status) {
+        case BTA_AV_SUCCESS:
+            ack = A2DP_CTRL_ACK_SUCCESS;
+            break;
+
+        case BTA_AV_FAIL_RESOURCES:
+            APPL_TRACE_ERROR("%s FAILED UNSUPPORTED", __func__);
+            ack = A2DP_CTRL_ACK_UNSUPPORTED;
+            break;
+        default:
+            APPL_TRACE_ERROR("%s FAILED", __func__);
+            ack = A2DP_CTRL_ACK_FAILURE;
+            break;
+    }
+    a2dp_cmd_acknowledge(ack);
+}
+
 /* when true media task discards any rx frames */
 void btif_a2dp_set_rx_flush(BOOLEAN enable)
 {
diff --git a/system/hci/Android.mk b/system/hci/Android.mk
index dd25d3d..e267812 100644
--- a/system/hci/Android.mk
+++ b/system/hci/Android.mk
@@ -32,6 +32,7 @@
     $(LOCAL_PATH)/../btcore/include \
     $(LOCAL_PATH)/../stack/include \
     $(LOCAL_PATH)/../utils/include \
+    $(LOCAL_PATH)/../bta/include \
     $(bdroid_C_INCLUDES)
 
 LOCAL_MODULE := libbt-hci
diff --git a/system/hci/include/bt_vendor_lib.h b/system/hci/include/bt_vendor_lib.h
index 65d448b..b4396ea 100644
--- a/system/hci/include/bt_vendor_lib.h
+++ b/system/hci/include/bt_vendor_lib.h
@@ -167,6 +167,35 @@
  *      specific epilog process once it has been done.
  */
     BT_VND_OP_EPILOG,
+
+/*  [operation]
+ *      Call to the vendor module so that it can perform all vendor-specific
+ *      operations to start offloading a2dp media encode & tx.
+ *  [input param]
+ *      pointer to bt_vendor_op_a2dp_offload_start_t containing elements
+ *      required for VND FW to setup a2dp offload.
+ *  [return]
+ *      0  - default, dont care.
+ *  [callback]
+ *      Must call a2dp_offload_start_cb to notify the stack of the
+ *      completion of vendor specific setup process once it has been done.
+ */
+    BT_VND_OP_A2DP_OFFLOAD_START,
+
+/*  [operation]
+ *      Call to the vendor module so that it can perform all vendor-specific
+ *      operations to suspend offloading a2dp media encode & tx.
+ *  [input param]
+ *      pointer to bt_vendor_op_a2dp_offload_t containing elements
+ *      required for VND FW to setup a2dp offload.
+ *  [return]
+ *      0  - default, dont care.
+ *  [callback]
+ *      Must call a2dp_offload_cb to notify the stack of the
+ *      completion of vendor specific setup process once it has been done.
+ */
+    BT_VND_OP_A2DP_OFFLOAD_STOP,
+
 } bt_vendor_opcode_t;
 
 /** Power on/off control states */
@@ -287,6 +316,8 @@
  */
 typedef uint8_t (*cmd_xmit_cb)(uint16_t opcode, void *p_buf, tINT_CMD_CBACK p_cback);
 
+typedef void (*cfg_a2dp_cb)(bt_vendor_op_result_t result, bt_vendor_opcode_t op, uint8_t bta_av_handle);
+
 typedef struct {
     /** set to sizeof(bt_vendor_callbacks_t) */
     size_t         size;
@@ -319,8 +350,25 @@
 
     /* notifies caller completion of epilog process */
     cfg_result_cb epilog_cb;
+
+    /* notifies status of a2dp offload cmd's */
+    cfg_a2dp_cb a2dp_offload_cb;
 } bt_vendor_callbacks_t;
 
+/** A2DP offload request */
+typedef struct {
+    uint8_t   bta_av_handle;                 /* BTA_AV Handle for callbacks */
+    uint16_t  xmit_quota;                    /* Total ACL quota for light stack */
+    uint16_t  acl_data_size;                 /* Max ACL data size across HCI transport */
+    uint16_t  stream_mtu;
+    uint16_t  local_cid;
+    uint16_t  remote_cid;
+    uint16_t  lm_handle;
+    uint8_t   is_flushable;                  /* TRUE if flushable channel */
+    uint32_t  stream_source;
+    uint8_t   codec_info[10];                /* Codec capabilities array */
+} bt_vendor_op_a2dp_offload_t;
+
 /*
  * Bluetooth Host/Controller VENDOR Interface
  */
diff --git a/system/hci/include/vendor.h b/system/hci/include/vendor.h
index 3181e62..e147b23 100644
--- a/system/hci/include/vendor.h
+++ b/system/hci/include/vendor.h
@@ -39,7 +39,10 @@
   VENDOR_CONFIGURE_FIRMWARE   = BT_VND_OP_FW_CFG,
   VENDOR_CONFIGURE_SCO        = BT_VND_OP_SCO_CFG,
   VENDOR_SET_LPM_MODE         = BT_VND_OP_LPM_SET_MODE,
-  VENDOR_DO_EPILOG            = BT_VND_OP_EPILOG
+  VENDOR_DO_EPILOG            = BT_VND_OP_EPILOG,
+  VENDOR_A2DP_OFFLOAD_START   = BT_VND_OP_A2DP_OFFLOAD_START,
+  VENDOR_A2DP_OFFLOAD_STOP    = BT_VND_OP_A2DP_OFFLOAD_STOP,
+  VENDOR_LAST_OP
 } vendor_async_opcode_t;
 
 typedef void (*vendor_cb)(bool success);
diff --git a/system/hci/src/vendor.c b/system/hci/src/vendor.c
index ace76b3..20b6841 100644
--- a/system/hci/src/vendor.c
+++ b/system/hci/src/vendor.c
@@ -24,10 +24,11 @@
 #include <dlfcn.h>
 
 #include "buffer_allocator.h"
+#include "bt_vendor_lib.h"
+#include "bta_av_api.h"
 #include "osi/include/log.h"
 #include "osi/include/osi.h"
 
-#define LAST_VENDOR_OPCODE_VALUE VENDOR_DO_EPILOG
 
 static const char *VENDOR_LIBRARY_NAME = "libbt-vendor.so";
 static const char *VENDOR_LIBRARY_SYMBOL_NAME = "BLUETOOTH_VENDOR_LIB_INTERFACE";
@@ -35,7 +36,7 @@
 static const vendor_t interface;
 static const allocator_t *buffer_allocator;
 static const hci_t *hci;
-static vendor_cb callbacks[LAST_VENDOR_OPCODE_VALUE + 1];
+static vendor_cb callbacks[VENDOR_LAST_OP];
 
 static void *lib_handle;
 static bt_vendor_interface_t *lib_interface;
@@ -186,6 +187,16 @@
   callback(result == BT_VND_OP_RESULT_SUCCESS);
 }
 
+// Called back from vendor library when the a2dp offload machine has to report status of
+// an a2dp offload command.
+static void a2dp_offload_cb(bt_vendor_op_result_t result, bt_vendor_opcode_t op, uint8_t bta_av_handle) {
+  tBTA_AV_STATUS status = (result == BT_VND_OP_RESULT_SUCCESS) ? BTA_AV_SUCCESS : BTA_AV_FAIL_RESOURCES;
+
+  if (op == BT_VND_OP_A2DP_OFFLOAD_START) {
+      BTA_AvOffloadStartRsp(bta_av_handle, status);
+  }
+}
+
 static const bt_vendor_callbacks_t lib_callbacks = {
   sizeof(lib_callbacks),
   firmware_config_cb,
@@ -195,7 +206,8 @@
   buffer_alloc_cb,
   buffer_free_cb,
   transmit_cb,
-  epilog_cb
+  epilog_cb,
+  a2dp_offload_cb
 };
 
 static const vendor_t interface = {
diff --git a/system/include/bt_target.h b/system/include/bt_target.h
index 1faf45f..eff6485 100644
--- a/system/include/bt_target.h
+++ b/system/include/bt_target.h
@@ -126,6 +126,18 @@
 #define BTA_AV_CO_CP_SCMS_T  FALSE
 #endif
 
+#ifndef BTIF_A2DP_SRC_SAMPLING_RATE
+#define BTIF_A2DP_SRC_SAMPLING_RATE 44100
+#endif
+
+#ifndef BTIF_A2DP_SRC_BIT_DEPTH
+#define BTIF_A2DP_SRC_BIT_DEPTH 16
+#endif
+
+#ifndef BTIF_A2DP_SRC_NUM_CHANNELS
+#define BTIF_A2DP_SRC_NUM_CHANNELS 2
+#endif
+
 /* This feature is used to eanble interleaved scan*/
 #ifndef BTA_HOST_INTERLEAVE_SEARCH
 #define BTA_HOST_INTERLEAVE_SEARCH FALSE
diff --git a/system/stack/include/l2c_api.h b/system/stack/include/l2c_api.h
index 69c5e92..b11c178 100644
--- a/system/stack/include/l2c_api.h
+++ b/system/stack/include/l2c_api.h
@@ -1067,6 +1067,18 @@
                                       tL2CAP_CFG_INFO **pp_our_cfg,  tL2CAP_CH_CFG_BITS *p_our_cfg_bits,
                                       tL2CAP_CFG_INFO **pp_peer_cfg, tL2CAP_CH_CFG_BITS *p_peer_cfg_bits);
 
+/*******************************************************************************
+**
+** Function     L2CA_GetConnectionConfig
+**
+** Description  This function polulates the mtu, remote cid & lm_handle for
+**              a given local L2CAP channel
+**
+** Returns      TRUE if successful
+**
+*******************************************************************************/
+extern BOOLEAN L2CA_GetConnectionConfig(UINT16 lcid, UINT16 *mtu, UINT16 *rcid, UINT16 *handle);
+
 #if (BLE_INCLUDED == TRUE)
 /*******************************************************************************
 **
diff --git a/system/stack/include/uipc_msg.h b/system/stack/include/uipc_msg.h
deleted file mode 100644
index 53cdccf..0000000
--- a/system/stack/include/uipc_msg.h
+++ /dev/null
@@ -1,568 +0,0 @@
-/******************************************************************************
- *
- *  Copyright (C) 1999-2012 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at:
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *  This file contains sync message over UIPC
- *
- ******************************************************************************/
-
-#ifndef UIPC_MSG_H
-#define UIPC_MSG_H
-
-#include "bt_types.h"
-
-/****************************************************************************/
-/*                            UIPC version number: 1.0                      */
-/****************************************************************************/
-#define UIPC_VERSION_MAJOR  0x0001
-#define UIPC_VERSION_MINOR  0x0000
-
-
-/********************************
-
-    UIPC Management Messages
-
-********************************/
-
-/* tUIPC_STATUS codes*/
-enum
-{
-    UIPC_STATUS_SUCCESS,
-    UIPC_STATUS_FAIL
-};
-typedef UINT8 tUIPC_STATUS;
-
-/* op_code */
-#define UIPC_OPEN_REQ                   0x00
-#define UIPC_OPEN_RSP                   0x01
-#define UIPC_CLOSE_REQ                  0x02
-#define UIPC_CLOSE_RSP                  0x03
-
-/* Structure of UIPC_OPEN_REQ message */
-typedef struct
-{
-    UINT8               opcode;         /* UIPC_OPEN_REQ */
-} tUIPC_OPEN_REQ;
-#define UIPC_OPEN_REQ_MSGLEN        (1)
-
-/* Structure of UIPC_OPEN_RSP message */
-typedef struct
-{
-    UINT8               opcode;         /* UIPC_OPEN_RESP */
-    tUIPC_STATUS        status;         /* UIPC_STATUS */
-    UINT16              version_major;  /* UIPC_VERSION_MAJOR */
-    UINT16              version_minor;  /* UIPC_VERSION_MINOR */
-    UINT8               num_streams;    /* Number of simultaneous streams supported by the light stack */
-} tUIPC_OPEN_RSP;
-#define UIPC_OPEN_RSP_MSGLEN        (7)
-
-/* Structure of UIPC_CLOSE_REQ message */
-typedef struct t_uipc_close_req
-{
-    UINT8               opcode;         /* UIPC_CLOSE_REQ */
-} tUIPC_CLOSE_REQ;
-#define UIPC_CLOSE_REQ_MSGLEN       (1)
-
-/* Structure of UIPC_CLOSE_RSP message, only for BTC, full stack may ignore it */
-typedef struct t_uipc_close_rsp
-{
-    UINT8               opcode;         /* UIPC_CLOSE_RSP */
-} tUIPC_CLOSE_RSP;
-#define UIPC_CLOSE_RSP_MSGLEN       (1)
-
-/* UIPC management message structures */
-typedef union
-{
-    UINT8               opcode;
-    tUIPC_OPEN_REQ      open_req;
-    tUIPC_OPEN_RSP      open_resp;
-    tUIPC_CLOSE_REQ     close_req;
-} tUIPC_MSG;
-
-#define UIPC_MGMT_MSG_MAXLEN    (sizeof(tUIPC_MSG))
-
-#define IPC_LOG_MSG_LEN  100
-typedef struct t_uipc_log_msg
-{
-    UINT32              trace_set_mask;
-    UINT8               msg[IPC_LOG_MSG_LEN];
-} tUIPC_LOG_MSG;
-#define UIPC_LOG_MSGLEN       (IPC_LOG_MSG_LEN + 4)
-
-typedef struct
-{
-    UINT8   opcode;     /* A2DP_START_REQ */
-    UINT16  lcid;
-    UINT16  curr_mtu;
-}tA2DP_START_REQ;
-
-typedef struct
-{
-    UINT8   opcode;     /* A2DP_STOP_REQ */
-    UINT16  lcid;
-}tA2DP_STOP_REQ;
-
-typedef struct
-{
-    UINT8   opcode;     /* A2DP_SUSPEND_REQ */
-    UINT16  lcid;
-}tA2DP_SUSPEND_REQ;
-
-typedef struct
-{
-    UINT8   opcode;     /* A2DP_CLEANUP_REQ */
-    UINT16  lcid;
-    UINT16  curr_mtu;
-} tA2DP_CLEANUP_REQ;
-
-typedef struct
-{
-    UINT8   opcode;     /* A2DP_START_RESP, A2DP_STOP_RESP, A2DP_CLEANUP_RESP, A2DP_SUSPEND_RESP */
-    UINT16  lcid;
-}tA2DP_GENERIC_RESP;
-
-#define AUDIO_CODEC_NONE            0x0000
-#define AUDIO_CODEC_SBC_ENC         0x0001
-#define AUDIO_CODEC_SBC_DEC         0x0002
-#define AUDIO_CODEC_MP3_ENC         0x0004
-#define AUDIO_CODEC_MP3_DEC         0x0008
-#define AUDIO_CODEC_AAC_ENC         0x0010
-#define AUDIO_CODEC_AAC_DEC         0x0020
-#define AUDIO_CODEC_AAC_PLUS_ENC    0x0040
-#define AUDIO_CODEC_AAC_PLUS_DEC    0x0080
-#define AUDIO_CODEC_MP2_ENC         0x0100
-#define AUDIO_CODEC_MP2_DEC         0x0200
-#define AUDIO_CODEC_MP2_5_ENC       0x0400
-#define AUDIO_CODEC_MP2_5_DEC       0x0800
-
-typedef UINT16 tAUDIO_CODEC_TYPE;
-
-/* SBC CODEC Parameters */
-
-#define CODEC_INFO_SBC_SF_16K       0x00
-#define CODEC_INFO_SBC_SF_32K       0x01
-#define CODEC_INFO_SBC_SF_44K       0x02
-#define CODEC_INFO_SBC_SF_48K       0x03
-
-#define CODEC_INFO_SBC_BLOCK_4      0x00
-#define CODEC_INFO_SBC_BLOCK_8      0x01
-#define CODEC_INFO_SBC_BLOCK_12     0x02
-#define CODEC_INFO_SBC_BLOCK_16     0x03
-
-#define CODEC_INFO_SBC_CH_MONO      0x00
-#define CODEC_INFO_SBC_CH_DUAL      0x01
-#define CODEC_INFO_SBC_CH_STEREO    0x02
-#define CODEC_INFO_SBC_CH_JS        0x03
-
-#define CODEC_INFO_SBC_ALLOC_LOUDNESS   0x00
-#define CODEC_INFO_SBC_ALLOC_SNR        0x01
-
-#define CODEC_INFO_SBC_SUBBAND_4    0x00
-#define CODEC_INFO_SBC_SUBBAND_8    0x01
-
-/* MPEG audio version ID */
-#define CODEC_INFO_MP25_ID              0x00
-#define CODEC_INFO_RESERVE              0x01
-#define CODEC_INFO_MP2_ID               0x02
-#define CODEC_INFO_MP3_ID               0x03
-
-#define CODEC_INFO_MP3_PROTECTION_ON    0x00
-#define CODEC_INFO_MP3_PROTECTION_OFF   0x01
-
-#define CODEC_INFO_MP3_BR_IDX_FREE      0x00
-#define CODEC_INFO_MP3_BR_IDX_32K       0x01
-#define CODEC_INFO_MP3_BR_IDX_40K       0x02
-#define CODEC_INFO_MP3_BR_IDX_48K       0x03
-#define CODEC_INFO_MP3_BR_IDX_56K       0x04
-#define CODEC_INFO_MP3_BR_IDX_64K       0x05
-#define CODEC_INFO_MP3_BR_IDX_80K       0x06
-#define CODEC_INFO_MP3_BR_IDX_96K       0x07
-#define CODEC_INFO_MP3_BR_IDX_112K      0x08
-#define CODEC_INFO_MP3_BR_IDX_128K      0x09
-#define CODEC_INFO_MP3_BR_IDX_160K      0x0A
-#define CODEC_INFO_MP3_BR_IDX_192K      0x0B
-#define CODEC_INFO_MP3_BR_IDX_224K      0x0C
-#define CODEC_INFO_MP3_BR_IDX_256K      0x0D
-#define CODEC_INFO_MP3_BR_IDX_320K      0x0E
-
-#define CODEC_INFO_MP3_SF_44K           0x00
-#define CODEC_INFO_MP3_SF_48K           0x01
-#define CODEC_INFO_MP3_SF_32K           0x02
-
-#define CODEC_INFO_MP3_MODE_STEREO      0x00
-#define CODEC_INFO_MP3_MODE_JS          0x01
-#define CODEC_INFO_MP3_MODE_DUAL        0x02
-#define CODEC_INFO_MP3_MODE_SINGLE      0x03
-
-/* layer 3, type of joint stereo coding method (intensity and ms) */
-#define CODEC_INFO_MP3_MODE_EXT_OFF_OFF 0x00
-#define CODEC_INFO_MP3_MODE_EXT_ON_OFF  0x01
-#define CODEC_INFO_MP3_MODE_EXT_OFF_ON  0x02
-#define CODEC_INFO_MP3_MODE_EXT_ON_ON   0x03
-
-
-#define CODEC_INFO_MP2_PROTECTION_ON    0x00
-#define CODEC_INFO_MP2_PROTECTION_OFF   0x01
-
-#define CODEC_INFO_MP2_BR_IDX_FREE      0x00
-#define CODEC_INFO_MP2_BR_IDX_8K        0x01
-#define CODEC_INFO_MP2_BR_IDX_16K       0x02
-#define CODEC_INFO_MP2_BR_IDX_24K       0x03
-#define CODEC_INFO_MP2_BR_IDX_32K       0x04
-#define CODEC_INFO_MP2_BR_IDX_40K       0x05
-#define CODEC_INFO_MP2_BR_IDX_48K       0x06
-#define CODEC_INFO_MP2_BR_IDX_56K       0x07
-#define CODEC_INFO_MP2_BR_IDX_64K       0x08
-#define CODEC_INFO_MP2_BR_IDX_80K       0x09
-#define CODEC_INFO_MP2_BR_IDX_96K       0x0A
-#define CODEC_INFO_MP2_BR_IDX_112K      0x0B
-#define CODEC_INFO_MP2_BR_IDX_128K      0x0C
-#define CODEC_INFO_MP2_BR_IDX_144K      0x0D
-#define CODEC_INFO_MP2_BR_IDX_160K      0x0E
-
-#define CODEC_INFO_MP2_SF_22K           0x00
-#define CODEC_INFO_MP2_SF_24K           0x01
-#define CODEC_INFO_MP2_SF_16K           0x02
-
-#define CODEC_INFO_MP2_MODE_STEREO      0x00
-#define CODEC_INFO_MP2_MODE_JS          0x01
-#define CODEC_INFO_MP2_MODE_DUAL        0x02
-#define CODEC_INFO_MP2_MODE_SINGLE      0x03
-
-/* layer 3, type of joint stereo coding method (intensity and ms) */
-#define CODEC_INFO_MP2_MODE_EXT_OFF_OFF 0x00
-#define CODEC_INFO_MP2_MODE_EXT_ON_OFF  0x01
-#define CODEC_INFO_MP2_MODE_EXT_OFF_ON  0x02
-#define CODEC_INFO_MP2_MODE_EXT_ON_ON   0x03
-
-#define CODEC_INFO_MP2_SAMPLE_PER_FRAME     576
-
-/* mpeg 2.5 layer 3 decoder */
-
-#define CODEC_INFO_MP25_PROTECTION_ON   0x00
-#define CODEC_INFO_MP25_PROTECTION_OFF  0x01
-
-#define CODEC_INFO_MP25_BR_IDX_FREE     0x00
-#define CODEC_INFO_MP25_BR_IDX_8K       0x01
-#define CODEC_INFO_MP25_BR_IDX_16K      0x02
-#define CODEC_INFO_MP25_BR_IDX_24K      0x03
-#define CODEC_INFO_MP25_BR_IDX_32K      0x04
-#define CODEC_INFO_MP25_BR_IDX_40K      0x05
-#define CODEC_INFO_MP25_BR_IDX_48K      0x06
-#define CODEC_INFO_MP25_BR_IDX_56K      0x07
-#define CODEC_INFO_MP25_BR_IDX_64K      0x08
-#define CODEC_INFO_MP25_BR_IDX_80K      0x09
-#define CODEC_INFO_MP25_BR_IDX_96K      0x0A
-#define CODEC_INFO_MP25_BR_IDX_112K     0x0B
-#define CODEC_INFO_MP25_BR_IDX_128K     0x0C
-#define CODEC_INFO_MP25_BR_IDX_144K     0x0D
-#define CODEC_INFO_MP25_BR_IDX_160K     0x0E
-
-#define CODEC_INFO_MP25_SF_11K          0x00
-#define CODEC_INFO_MP25_SF_12K          0x01
-#define CODEC_INFO_MP25_SF_8K           0x02
-
-#define CODEC_INFO_MP25_MODE_STEREO     0x00
-#define CODEC_INFO_MP25_MODE_JS         0x01
-#define CODEC_INFO_MP25_MODE_DUAL       0x02
-#define CODEC_INFO_MP25_MODE_SINGLE     0x03
-
-/* layer 3, type of joint stereo coding method (intensity and ms) */
-#define CODEC_INFO_MP25_MODE_EXT_OFF_OFF 0x00
-#define CODEC_INFO_MP25_MODE_EXT_ON_OFF  0x01
-#define CODEC_INFO_MP25_MODE_EXT_OFF_ON  0x02
-#define CODEC_INFO_MP25_MODE_EXT_ON_ON   0x03
-
-#define CODEC_INFO_MP25_SAMPLE_PER_FRAME    576
-
-/* AAC/AAC+ CODEC Parameters */
-#define CODEC_INFO_AAC_SF_IDX_96K   0x0
-#define CODEC_INFO_AAC_SF_IDX_88K   0x1
-#define CODEC_INFO_AAC_SF_IDX_64K   0x2
-#define CODEC_INFO_AAC_SF_IDX_48K   0x3
-#define CODEC_INFO_AAC_SF_IDX_44K   0x4
-#define CODEC_INFO_AAC_SF_IDX_32K   0x5
-#define CODEC_INFO_AAC_SF_IDX_24K   0x6
-#define CODEC_INFO_AAC_SF_IDX_22K   0x7
-#define CODEC_INFO_AAC_SF_IDX_16K   0x8
-#define CODEC_INFO_AAC_SF_IDX_12K   0x9
-#define CODEC_INFO_AAC_SF_IDX_11K   0xA
-#define CODEC_INFO_AAC_SF_IDX_08K   0xB
-#define CODEC_INFO_AAC_SF_IDX_RESERVE   0xC
-
-#define CODEC_INFO_AAC_BR_RATE_48K  288000
-#define CODEC_INFO_AAC_BR_RATE_44K  264600
-#define CODEC_INFO_AAC_BR_RATE_32K  192000
-
-
-#define CODEC_INFO_AAC_1_CH           1         /*center front speaker */
-#define CODEC_INFO_AAC_2_CH           2         /*left, right front speaker */
-#define CODEC_INFO_AAC_3_CH           3         /*center front speaker, left right front speaker */
-#define CODEC_INFO_AAC_4_CH           4         /*center/rear front speaker, left/right front speaker */
-#define CODEC_INFO_AAC_5_CH           5         /*center, left, right front speaker, left/right surround */
-#define CODEC_INFO_AAC_6_CH           6         /*center, left, right front speaker, left/right surround, LFE */
-#define CODEC_INFO_AAC_7_CH           7         /*(left, right)center/left,right front speaker, left/right surround, LFE */
-
-
-typedef struct
-{
-    UINT8   sampling_freq;
-    UINT8   channel_mode;
-    UINT8   block_length;
-    UINT8   num_subbands;
-    UINT8   alloc_method;
-    UINT8   bitpool_size;   /* 2 - 250 */
-} tCODEC_INFO_SBC;
-
-typedef struct
-{
-    UINT8   ch_mode;
-    UINT8   sampling_freq;
-    UINT8   bitrate_index;  /* 0 - 14 */
-} tCODEC_INFO_MP3;
-
-typedef struct
-{
-    UINT8   ch_mode;
-    UINT8   sampling_freq;
-    UINT8   bitrate_index;  /* 0 - 14 */
-} tCODEC_INFO_MP2;
-
-
-typedef struct
-{
-    UINT8   ch_mode;
-    UINT8   sampling_freq;
-    UINT8   bitrate_index;  /* 0 - 14 */
-} tCODEC_INFO_MP2_5;
-
-typedef struct
-{
-    UINT16  sampling_freq;
-    UINT8   channel_mode;   /* 0x02:mono, 0x01:dual */
-    UINT32  bitrate;        /* 0 - 320K */
-    UINT32  sbr_profile;        /* 1: ON, 0: OFF */
-} tCODEC_INFO_AAC;
-
-typedef union
-{
-    tCODEC_INFO_SBC     sbc;
-    tCODEC_INFO_MP3     mp3;
-    tCODEC_INFO_MP2     mp2;
-    tCODEC_INFO_MP2_5   mp2_5;
-    tCODEC_INFO_AAC     aac;
-} tCODEC_INFO;
-
-typedef struct
-{
-    UINT8               opcode;     /* AUDIO_CODEC_CONFIG_REQ */
-    tAUDIO_CODEC_TYPE   codec_type;
-    tCODEC_INFO         codec_info;
-} tAUDIO_CODEC_CONFIG_REQ;
-
-#define AUDIO_CONFIG_SUCCESS            0x00
-#define AUDIO_CONFIG_NOT_SUPPORTED      0x01
-#define AUDIO_CONFIG_FAIL_OUT_OF_MEMORY 0x02
-#define AUDIO_CONFIG_FAIL_CODEC_USED    0x03
-#define AUDIO_CONFIG_FAIL_ROUTE         0x04
-typedef UINT8 tAUDIO_CONFIG_STATUS;
-
-typedef struct
-{
-    UINT8                   opcode; /* AUDIO_CODEC_CONFIG_RESP */
-    tAUDIO_CONFIG_STATUS    status;
-} tAUDIO_CODEC_CONFIG_RESP;
-
-typedef struct
-{
-    UINT8               opcode;     /* AUDIO_CODEC_SET_BITRATE_REQ */
-    tAUDIO_CODEC_TYPE   codec_type;
-    union
-    {
-        UINT8   sbc;
-        UINT8   mp3;
-        UINT32  aac;
-    } codec_bitrate;
-} tAUDIO_CODEC_SET_BITRATE_REQ;
-
-#define AUDIO_ROUTE_SRC_FMRX        0x00
-#define AUDIO_ROUTE_SRC_I2S         0x01
-#define AUDIO_ROUTE_SRC_ADC         0x02
-#define AUDIO_ROUTE_SRC_HOST        0x03
-#define AUDIO_ROUTE_SRC_PTU         0x04
-#define AUDIO_ROUTE_SRC_BTSNK       0x05
-#define AUDIO_ROUTE_SRC_NONE        0x80
-#define MAX_AUDIO_ROUTE_SRC         6
-typedef UINT8 tAUDIO_ROUTE_SRC;
-
-#define AUDIO_ROUTE_MIX_NONE        0x00
-#define AUDIO_ROUTE_MIX_HOST        0x01
-#define AUDIO_ROUTE_MIX_PCM         0x02
-#define AUDIO_ROUTE_MIX_CHIRP       0x03
-#define AUDIO_ROUTE_MIX_I2S         0x04
-#define AUDIO_ROUTE_MIX_ADC         0x05
-#define AUDIO_ROUTE_MIX_RESERVED    0x06
-#define MAX_AUDIO_ROUTE_MIX         7
-typedef UINT8 tAUDIO_ROUTE_MIX;
-
-#define AUDIO_ROUTE_OUT_NONE        0x0000
-#define AUDIO_ROUTE_OUT_BTA2DP      0x0001
-#define AUDIO_ROUTE_OUT_FMTX        0x0002
-#define AUDIO_ROUTE_OUT_BTSCO       0x0004
-#define AUDIO_ROUTE_OUT_HOST        0x0008
-#define AUDIO_ROUTE_OUT_DAC         0x0010
-#define AUDIO_ROUTE_OUT_I2S         0x0020
-#define AUDIO_ROUTE_OUT_BTA2DP_DAC  0x0040
-#define AUDIO_ROUTE_OUT_BTA2DP_I2S  0x0080
-#define AUDIO_ROUTE_OUT_BTSCO_DAC   0x0100
-#define AUDIO_ROUTE_OUT_BTSCO_I2S   0x0200
-#define AUDIO_ROUTE_OUT_HOST_BTA2DP 0x0400
-#define AUDIO_ROUTE_OUT_HOST_BTSCO  0x0800
-#define AUDIO_ROUTE_OUT_HOST_DAC    0x1000
-#define AUDIO_ROUTE_OUT_HOST_I2S    0x2000
-#define AUDIO_ROUTE_OUT_DAC_I2S     0x4000
-#define AUDIO_ROUTE_OUT_RESERVED_2  0x8000
-
-#define MAX_AUDIO_SINGLE_ROUTE_OUT  6
-#define MAX_AUDIO_MULTI_ROUTE_OUT   16
-typedef UINT16 tAUDIO_MULTI_ROUTE_OUT;
-typedef UINT8  tAUDIO_ROUTE_OUT;
-
-#define AUDIO_ROUTE_SF_8K           0x00
-#define AUDIO_ROUTE_SF_16K          0x01
-#define AUDIO_ROUTE_SF_32K          0x02
-#define AUDIO_ROUTE_SF_44_1K        0x03
-#define AUDIO_ROUTE_SF_48K          0x04
-#define AUDIO_ROUTE_SF_11K          0x05
-#define AUDIO_ROUTE_SF_12K          0x06
-#define AUDIO_ROUTE_SF_22K          0x07
-#define AUDIO_ROUTE_SF_24K          0x08
-#define AUDIO_ROUTE_SF_NA           0xFF
-typedef UINT8 tAUDIO_ROUTE_SF;
-
-#define AUDIO_ROUTE_EQ_BASS_BOOST   0x00
-#define AUDIO_ROUTE_EQ_CLASSIC      0x01
-#define AUDIO_ROUTE_EQ_JAZZ         0x02
-#define AUDIO_ROUTE_EQ_LIVE         0x03
-#define AUDIO_ROUTE_EQ_NORMAL       0x04
-#define AUDIO_ROUTE_EQ_ROCK         0x05
-#define AUDIO_ROUTE_EQ_BYPASS       0x06
-
-#define AUDIO_ROUTE_DIGITAL_VOLUME_CONTROL  0x07
-
-#define AUDIO_ROUTE_EQ_CONFIG_GAIN  0xFF    /* Custion Gain Config */
-typedef UINT8 tAUDIO_ROUTE_EQ;
-
-typedef struct
-{
-    UINT8               opcode;     /* AUDIO_ROUTE_CONFIG_REQ */
-    tAUDIO_ROUTE_SRC    src;
-    tAUDIO_ROUTE_SF     src_sf;
-    tAUDIO_ROUTE_OUT    out;
-    tAUDIO_ROUTE_SF     out_codec_sf;
-    tAUDIO_ROUTE_SF     out_i2s_sf;
-    tAUDIO_ROUTE_EQ     eq_mode;
-} tAUDIO_ROUTE_CONFIG_REQ;
-
-typedef struct
-{
-    UINT8                   opcode; /* AUDIO_ROUTE_CONFIG_RESP */
-    tAUDIO_CONFIG_STATUS    status;
-} tAUDIO_ROUTE_CONFIG_RESP;
-
-typedef struct
-{
-    UINT16  amp[2];                 /* left/right 15 bit amplitude value        */
-    UINT16  tone[2];                /* left/right 12 bit frequency 0 - 4096Hz   */
-    UINT16  mark[2];                /* left/right 16 bit mark time 0 - 65535ms  */
-    UINT16  space[2];               /* left/right 16 bit space time 0 - 65535ms */
-} tCHIRP_CONFIG;
-
-typedef struct
-{
-    UINT8   pri_l;                  /* Primary Left scale : 0 ~ 255     */
-    UINT8   mix_l;                  /* Mixing Left scale : 0 ~ 255      */
-    UINT8   pri_r;                  /* Primary Right scale : 0 ~ 255    */
-    UINT8   mix_r;                  /* Mixing Right scale : 0 ~ 255     */
-} tMIX_SCALE_CONFIG;
-
-/* For custon equalizer gain configuration */
-typedef struct
-{
-    UINT32  audio_l_g0;         /* IIR biquad filter left ch gain 0 */
-    UINT32  audio_l_g1;         /* IIR biquad filter left ch gain 1 */
-    UINT32  audio_l_g2;         /* IIR biquad filter left ch gain 2 */
-    UINT32  audio_l_g3;         /* IIR biquad filter left ch gain 3 */
-    UINT32  audio_l_g4;         /* IIR biquad filter left ch gain 4 */
-    UINT32  audio_l_gl;         /* IIR biquad filter left ch global gain  */
-    UINT32  audio_r_g0;         /* IIR biquad filter left ch gain 0 */
-    UINT32  audio_r_g1;         /* IIR biquad filter left ch gain 1 */
-    UINT32  audio_r_g2;         /* IIR biquad filter left ch gain 2 */
-    UINT32  audio_r_g3;         /* IIR biquad filter left ch gain 3 */
-    UINT32  audio_r_g4;         /* IIR biquad filter left ch gain 4 */
-    UINT32  audio_r_gl;         /* IIR biquad filter left ch global gain */
-} tEQ_GAIN_CONFIG;
-
-typedef struct
-{
-    UINT8               opcode;     /* AUDIO_MIX_CONFIG_REQ */
-    tAUDIO_ROUTE_MIX    mix_src;
-    tAUDIO_ROUTE_SF     mix_src_sf;
-    tMIX_SCALE_CONFIG   mix_scale;
-    tCHIRP_CONFIG       chirp_config;
-} tAUDIO_MIX_CONFIG_REQ;
-
-typedef struct
-{
-    UINT8                   opcode; /* AUDIO_MIX_CONFIG_RESP */
-    tAUDIO_CONFIG_STATUS    status;
-} tAUDIO_MIX_CONFIG_RESP;
-
-
-typedef struct
-{
-    UINT8   opcode;                 /* AUDIO_BURST_FRAMES_IND */
-    UINT32  burst_size;             /* in bytes */
-} tAUDIO_BURST_FRAMES_IND;
-
-typedef struct
-{
-    UINT8   opcode;                 /* AUDIO_BURST_END_IND */
-} tAUDIO_BURST_END_IND;
-
-typedef struct
-{
-    UINT8   opcode;                 /* AUDIO_CODEC_FLUSH_REQ */
-} tAUDIO_CODEC_FLUSH_REQ;
-
-typedef struct
-{
-    UINT8               opcode;     /* AUDIO_EQ_MODE_CONFIG_REQ */
-    tAUDIO_ROUTE_EQ     eq_mode;
-    tEQ_GAIN_CONFIG     filter_gain;    /* Valid only when eq_mode is 0xFF */
-} tAUDIO_EQ_MODE_CONFIG_REQ;
-
-typedef struct
-{
-    UINT8               opcode;     /* AUDIO_SCALE_CONFIG_REQ */
-    tMIX_SCALE_CONFIG   mix_scale;
-} tAUDIO_SCALE_CONFIG_REQ;
-
-#endif /* UIPC_MSG_H */
-
diff --git a/system/stack/l2cap/l2c_api.c b/system/stack/l2cap/l2c_api.c
index 8d9704a..c82c80a 100644
--- a/system/stack/l2cap/l2c_api.c
+++ b/system/stack/l2cap/l2c_api.c
@@ -1765,6 +1765,37 @@
 
 /*******************************************************************************
 **
+** Function      L2CA_GetConnectionConfig
+**
+** Description  This function returns configurations of L2CAP channel
+**              pp_l2c_ccb : pointer to this channels L2CAP ccb data.
+**
+** Returns      TRUE if successful
+**
+*******************************************************************************/
+BOOLEAN L2CA_GetConnectionConfig(UINT16 lcid, UINT16 *mtu, UINT16 *rcid, UINT16 *handle)
+{
+    tL2C_CCB *p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);;
+
+    L2CAP_TRACE_API ("%s CID: 0x%04x", __func__, lcid);
+
+    if (p_ccb)
+    {
+        *mtu = L2CAP_MTU_SIZE;
+        if (p_ccb->our_cfg.mtu_present)
+            *mtu = p_ccb->our_cfg.mtu;
+
+        *rcid  = p_ccb->remote_cid;
+        *handle= p_ccb->p_lcb->handle;
+        return TRUE;
+    }
+
+    L2CAP_TRACE_ERROR ("%s No CCB for CID:0x%04x", __func__, lcid);
+    return FALSE;
+}
+
+/*******************************************************************************
+**
 ** Function         L2CA_RegForNoCPEvt
 **
 ** Description      Register callback for Number of Completed Packets event.